Skip to content

Commit 4956ac8

Browse files
authored
fix: alt values for process.stdout.columns (#131)
* fix: alt values for process.stdout.columns * chore: clarify comment * chore: lower repeat for ci width * chore: check for CI
1 parent fb28f15 commit 4956ac8

File tree

5 files changed

+146
-5
lines changed

5 files changed

+146
-5
lines changed

examples/no-width-table.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {printTable} from '../src/index.js'
2+
3+
const data = [
4+
{
5+
actual: 'This is a string of the actual test results. ',
6+
expected: 'This is a long string of the expected test results. '.repeat(10),
7+
result: 'Passed',
8+
test: 'Topic',
9+
},
10+
]
11+
12+
printTable({
13+
columns: [ 'test', 'result', 'expected', 'actual' ],
14+
data,
15+
headerOptions: {
16+
formatter: 'capitalCase',
17+
},
18+
overflow: 'wrap',
19+
title: 'Fixed-Width Columns',
20+
titleOptions: {bold: true},
21+
})

src/table.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
determineConfiguredWidth,
2828
determineWidthOfWrappedText,
2929
getColumns,
30+
getColumnWidth,
3031
getHeadings,
3132
intersperse,
3233
maybeStripAnsi,
@@ -431,7 +432,7 @@ const createStdout = (): FakeStdout => {
431432
// https://github.com/vadimdemedes/ink/blob/v5.0.1/src/ink.tsx#L174
432433
// This might be a bad idea but it works.
433434
stdout.rows = 10_000
434-
stdout.columns = process.stdout.columns ?? 80
435+
stdout.columns = getColumnWidth();
435436
const frames: string[] = []
436437

437438
stdout.write = (data: string) => {
@@ -568,8 +569,7 @@ export function printTables<T extends Record<string, unknown>[]>(
568569
const output = new Output()
569570
const leftMargin = options?.marginLeft ?? options?.margin ?? 0
570571
const rightMargin = options?.marginRight ?? options?.margin ?? 0
571-
const columns = process.stdout.columns - (leftMargin + rightMargin)
572-
572+
const columns = getColumnWidth() - (leftMargin + rightMargin)
573573
const processed = tables.map((table) => ({
574574
...table,
575575
// adjust maxWidth to account for margin and columnGap

src/utils.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ export function determineWidthOfWrappedText(text: string): number {
5151
return lines.reduce((max, line) => Math.max(max, line.length), 0)
5252
}
5353

54+
// In certain systems, `process.stdout.columns` can be 0
55+
// The column width is calculated by:
56+
// 1. The value of `OCLIF_TABLE_COLUMN_OVERRIDE` (if set)
57+
// 2. The value of `process.stdout.columns`
58+
// 3. If `process.stdout.columns` is 0, use 80
59+
export function getColumnWidth(): number {
60+
return Number.parseInt(process.env.OCLIF_TABLE_COLUMN_OVERRIDE || '0', 10) || process.stdout.columns || 80
61+
}
62+
5463
/**
5564
* Determines the configured width based on the provided width value.
5665
* If no width is provided, it returns the width of the current terminal.
@@ -63,7 +72,7 @@ export function determineWidthOfWrappedText(text: string): number {
6372
*/
6473
export function determineConfiguredWidth(
6574
providedWidth: number | Percentage | undefined,
66-
columns = process.stdout.columns,
75+
columns = getColumnWidth(),
6776
): number {
6877
if (!providedWidth) return columns
6978

test/table.test.tsx

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,4 +718,90 @@ describe('printTable compatibility with @oclif/test', () => {
718718
)
719719
expect(stdout).to.equal(expected)
720720
})
721+
722+
it('prints full table with no set width', async () => {
723+
console.log(process.stdout.columns)
724+
const data = [
725+
{name: 'Foo', age: '1'.repeat(60)},
726+
{name: 'Bar', age: '2'.repeat(60)},
727+
]
728+
729+
const expected = `┌──────┬──────────────────────────────────────────────────────────────┐
730+
│ name │ age │
731+
├──────┼──────────────────────────────────────────────────────────────┤
732+
│ Foo │ 111111111111111111111111111111111111111111111111111111111111 │
733+
├──────┼──────────────────────────────────────────────────────────────┤
734+
│ Bar │ 222222222222222222222222222222222222222222222222222222222222 │
735+
└──────┴──────────────────────────────────────────────────────────────┘
736+
737+
`
738+
739+
const {stdout} = await captureOutput(async () =>
740+
printTable({
741+
data,
742+
columns: ['name', 'age'],
743+
}),
744+
)
745+
expect(stdout).to.equal(expected)
746+
})
747+
748+
it('should use width of 80 if process.stdout.columns is 0', async () => {
749+
const backupColumns = process.stdout.columns
750+
process.stdout.columns = 0
751+
const data = [
752+
{name: 'Foo', age: '1'.repeat(100)},
753+
{name: 'Bar', age: '2'.repeat(100)},
754+
]
755+
756+
const expected = `┌──────┬───────────────────────────────────────────────────────────────────────┐
757+
│ name │ age │
758+
├──────┼───────────────────────────────────────────────────────────────────────┤
759+
│ Foo │ 11111111111111111111111111111111111111111111111111111111111111111111… │
760+
├──────┼───────────────────────────────────────────────────────────────────────┤
761+
│ Bar │ 22222222222222222222222222222222222222222222222222222222222222222222… │
762+
└──────┴───────────────────────────────────────────────────────────────────────┘
763+
764+
`
765+
766+
const {stdout} = await captureOutput(async () =>
767+
printTable({
768+
data,
769+
columns: ['name', 'age'],
770+
}),
771+
)
772+
expect(stdout).to.equal(expected)
773+
774+
process.stdout.columns = backupColumns;
775+
})
776+
777+
it('should respect the OCLIF_TABLE_COLUMN_OVERRIDE env var', async () => {
778+
const backupColumns = process.stdout.columns
779+
process.stdout.columns = 0
780+
process.env.OCLIF_TABLE_COLUMN_OVERRIDE = '50'
781+
const data = [
782+
{name: 'Foo', age: '1'.repeat(100)},
783+
{name: 'Bar', age: '2'.repeat(100)},
784+
]
785+
786+
const expected = `┌──────┬─────────────────────────────────────────┐
787+
│ name │ age │
788+
├──────┼─────────────────────────────────────────┤
789+
│ Foo │ 11111111111111111111111111111111111111… │
790+
├──────┼─────────────────────────────────────────┤
791+
│ Bar │ 22222222222222222222222222222222222222… │
792+
└──────┴─────────────────────────────────────────┘
793+
794+
`
795+
796+
const {stdout} = await captureOutput(async () =>
797+
printTable({
798+
data,
799+
columns: ['name', 'age'],
800+
}),
801+
)
802+
expect(stdout).to.equal(expected)
803+
804+
delete process.env.OCLIF_TABLE_COLUMN_OVERRIDE;
805+
process.stdout.columns = backupColumns;
806+
})
721807
})

test/util.test.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {config, expect} from 'chai'
22

3-
import {intersperse, sortData} from '../src/utils.js'
3+
import {getColumnWidth, intersperse, sortData} from '../src/utils.js'
44

55
config.truncateThreshold = 0
66

@@ -64,3 +64,28 @@ describe('sortData', () => {
6464
expect(sortData(data, sort)).to.deep.equal(expected)
6565
})
6666
})
67+
68+
describe('should get the correct column width', () => {
69+
it('should return the value of OCLIF_TABLE_COLUMN_OVERRIDE', () => {
70+
process.env.OCLIF_TABLE_COLUMN_OVERRIDE = '100'
71+
expect(getColumnWidth()).to.equal(100)
72+
delete process.env.OCLIF_TABLE_COLUMN_OVERRIDE
73+
})
74+
75+
it('should return the value of process.stdout.columns', () => {
76+
if (process.env.CI && !process.stdout.columns) {
77+
// In GHA process.stdout.columns is undefined
78+
expect(getColumnWidth()).to.equal(80)
79+
} else {
80+
const currentColumns = process.stdout.columns
81+
expect(getColumnWidth()).to.equal(currentColumns)
82+
}
83+
})
84+
85+
it('should return the default value of 80', () => {
86+
const backupColumns = process.stdout.columns
87+
process.stdout.columns = 0
88+
expect(getColumnWidth()).to.equal(80)
89+
process.stdout.columns = backupColumns
90+
})
91+
})

0 commit comments

Comments
 (0)