Skip to content

Commit

Permalink
feat: use oclif/table (#763)
Browse files Browse the repository at this point in the history
* feat: use oclif/table

* fix: dont print table if json

* chore: remove tty-table

* chore: bump oclif/table

* chore: code review
  • Loading branch information
mdonnalley authored Oct 4, 2024
1 parent 2fbe1c9 commit 27c0ebc
Show file tree
Hide file tree
Showing 4 changed files with 239 additions and 161 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
"bugs": "https://github.com/oclif/plugin-commands/issues",
"dependencies": {
"@oclif/core": "^4",
"@oclif/table": "^0.1.12",
"lodash": "^4.17.21",
"object-treeify": "^4.0.1",
"tty-table": "^4.2.3"
"object-treeify": "^4.0.1"
},
"devDependencies": {
"@commitlint/config-conventional": "^19",
Expand Down
75 changes: 16 additions & 59 deletions src/commands/commands.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {Command, Flags, toConfiguredId} from '@oclif/core'
import {printTable} from '@oclif/table'
import _ from 'lodash'
// @ts-expect-error because object-treeify does not have types: https://github.com/blackflux/object-treeify/issues/1077
import treeify from 'object-treeify'
import TtyTable from 'tty-table'

type Dictionary = {[index: string]: object}

Expand All @@ -27,26 +27,6 @@ function createTree(commands: Command.Loadable[]): RecursiveTree {
return tree
}

function determineHeaders(columns: Column[] | undefined, extended: boolean | undefined): TtyTable.Header[] {
const columnConfigs = {
id: {align: 'left', value: 'ID', width: '25%'},
plugin: {align: 'left', value: 'Plugin'},
summary: {align: 'left', value: 'Summary', width: '75%'},
type: {align: 'left', value: 'Type'},
}

if (columns) {
return columns.map((column) => columnConfigs[column])
}

if (extended) {
return [columnConfigs.id, columnConfigs.summary, columnConfigs.plugin, columnConfigs.type]
}

return [columnConfigs.id, columnConfigs.summary]
}

// In order to collect static properties up the inheritance chain, we need to recursively access the prototypes until there's nothing left
function mergePrototype(result: Command.Class, command: Command.Class): Command.Class {
const proto = Object.getPrototypeOf(command)
const filteredProto = _.pickBy(proto, (v) => v !== undefined) as Command.Class
Expand Down Expand Up @@ -109,45 +89,22 @@ export default class Commands extends Command {
if (flags.tree) {
const tree = createTree(commands)
this.log(treeify(tree))
} else {
const headers = determineHeaders(flags.columns, flags.extended)
const extractData = (command: Command.Loadable) =>
headers.map((header) => {
switch (header.value) {
case 'ID': {
return toConfiguredId(command.id, config)
}

case 'Plugin': {
return command.pluginName
}

case 'Type': {
return command.pluginType
}

case 'Summary': {
return command.summary ?? command.description
}

default: {
throw new Error('Unknown column')
}
}
})

// eslint-disable-next-line new-cap
const table = TtyTable(
headers,
commands.map((c) => extractData(c)),
{
compact: true,
defaultValue: '',
truncate: flags['no-truncate'] ? undefined : '...',
} else if (!this.jsonEnabled()) {
printTable({
borderStyle: 'vertical-with-outline',
columns: (flags.columns ?? ['id', 'summary', ...(flags.extended ? ['plugin', 'type'] : [])]) as Column[],
data: commands.map((c) => ({
id: toConfiguredId(c.id, config),
plugin: c.pluginName,
summary: c.summary ?? c.description,
type: c.pluginType,
})),
headerOptions: {
formatter: 'capitalCase',
},
)

this.log(table.render())
overflow: flags['no-truncate'] ? 'wrap' : 'truncate',
sort: {[flags.sort]: 'asc'},
})
}

const json = _.uniqBy(
Expand Down
2 changes: 1 addition & 1 deletion test/commands/commands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ describe('commands', () => {
it('prints commands', async () => {
const {stdout} = await runCommand(['commands'])
// pro tip: don't assert the entire table output since the width of the table can differ between CI and local
expect(stdout).include('ID')
expect(stdout).include('Id')
expect(stdout).include('Summary')
expect(stdout).include('commands')
expect(stdout).include('List all oclif-example commands.')
Expand Down
Loading

0 comments on commit 27c0ebc

Please sign in to comment.