Skip to content

chore: update @oclif/core to v4 and @adobe/eslint-config-aio-lib-config to v5#130

Open
shazron wants to merge 2 commits intomasterfrom
fix/issue-129-update-oclif-core-v4
Open

chore: update @oclif/core to v4 and @adobe/eslint-config-aio-lib-config to v5#130
shazron wants to merge 2 commits intomasterfrom
fix/issue-129-update-oclif-core-v4

Conversation

@shazron
Copy link
Copy Markdown
Member

@shazron shazron commented Mar 25, 2026

Summary

Closes #129

  • @oclif/core v2 → v4: Updates @oclif/core from ^2.8.12 to ^4.9.0 to support aio-cli#781

    • Adds src/utils/table.js to replace ux.table which was removed in v4
    • Renames ux: cli import alias to ux across all command files
    • Updates test/jest.setup.js: removes obsolete @oclif/core/lib/cli-ux path mocks (paths removed in v4), adds mockConfig stub for Command.parse() which now requires this.config.runHook
    • Adds test/utils/table.test.js to maintain 100% branch coverage
  • @adobe/eslint-config-aio-lib-config v4 → v5.0.0: The new version uses ESLint 9 flat config format

    • Upgrades eslint to v9, adds neostandard, upgrades eslint-plugin-jest to latest
    • Replaces .eslintrc.json with eslint.config.js (ESLint 9 flat config)
    • Removes packages now bundled in neostandard: eslint-config-oclif, eslint-config-standard, eslint-plugin-import, eslint-plugin-n, eslint-plugin-node, eslint-plugin-promise, eslint-plugin-standard

Test plan

  • All 237 unit tests pass (npm test)
  • 100% code coverage maintained (statements, branches, functions, lines)
  • ESLint passes with no errors (eslint src test e2e)

🤖 Generated with Claude Code

…ig to v5

- Update @oclif/core from ^2.8.12 to ^4.9.0 (closes #129)
  - Replace removed ux.table with a new src/utils/table.js utility
  - Rename ux:cli import alias to ux across all command files
  - Update jest.setup.js: remove obsolete @oclif/core/lib/cli-ux mocks,
    add mockConfig stub for Command.parse() which now requires this.config
  - Add test/utils/table.test.js for full branch coverage
- Update @adobe/eslint-config-aio-lib-config from ^4.0.0 to 5.0.0
  - Upgrade eslint to v9, add neostandard, upgrade eslint-plugin-jest
  - Replace .eslintrc.json with eslint.config.js (ESLint 9 flat config)
  - Remove replaced packages: eslint-config-oclif, eslint-config-standard,
    eslint-plugin-import, eslint-plugin-n, eslint-plugin-node,
    eslint-plugin-promise, eslint-plugin-standard
  - Remove now-invalid eslint-disable comment from validator.js

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 25, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@shazron
Copy link
Copy Markdown
Member Author

shazron commented Mar 25, 2026

node-18 failures, wait for adobe/aio-reusable-workflows#14
done

Copy link
Copy Markdown
Member

@purplecabbage purplecabbage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copyright years, and I think we should be using ora for spinners.

}

cli.action.start('Creating Event Metadata')
ux.action.start('Creating Event Metadata')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought action was removed and we're all just supposed to use ora

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates this plugin to work with @oclif/core v4 and migrates linting to the ESLint 9 flat config format required by @adobe/eslint-config-aio-lib-config v5, while preserving existing CLI output behavior and test coverage.

Changes:

  • Upgrade @oclif/core to v4 and refactor commands to use ux plus a new internal table() utility (replacing removed ux.table).
  • Migrate from .eslintrc.json to eslint.config.js (ESLint 9 flat config) and adjust related dependencies/overrides.
  • Update Jest setup/mocks for new oclif behavior and add unit tests for the new table utility.

Reviewed changes

Copilot reviewed 22 out of 23 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
package.json Upgrades @oclif/core and ESLint toolchain deps; adds neostandard.
src/utils/table.js Adds replacement table renderer for removed ux.table.
test/utils/table.test.js Adds unit tests to cover the new table renderer.
src/commands/event/registration/list.js Switches from ux: cli to ux and replaces cli.table with new table() utility.
src/commands/event/registration/get.js Renames ux: cli to ux for action spinner usage.
src/commands/event/registration/create.js Renames ux: cli to ux for action spinner usage.
src/commands/event/registration/delete.js Renames ux: cli to ux for action spinner usage.
src/commands/event/provider/list.js Renames ux: cli to ux and replaces cli.table with new table() utility.
src/commands/event/provider/get.js Renames ux: cli to ux for action spinner usage.
src/commands/event/provider/create.js Renames ux: cli to ux for action spinner usage.
src/commands/event/provider/update.js Renames ux: cli to ux for action spinner usage.
src/commands/event/provider/delete.js Renames ux: cli to ux for action spinner usage.
src/commands/event/eventmetadata/list.js Renames ux: cli to ux and replaces cli.table with new table() utility.
src/commands/event/eventmetadata/get.js Renames ux: cli to ux for action spinner usage.
src/commands/event/eventmetadata/create.js Renames ux: cli to ux for action spinner usage.
src/commands/event/eventmetadata/update.js Renames ux: cli to ux for action spinner usage.
src/commands/event/eventmetadata/delete.js Renames ux: cli to ux for action spinner usage.
test/jest.setup.js Removes obsolete mocks and patches oclif parsing requirements for tests; keeps ux mocked.
eslint.config.js Introduces ESLint 9 flat config with Jest overrides for test/ and e2e/.
.eslintrc.json Removes legacy ESLint config file.
e2e/.eslintrc.json Removes legacy per-folder ESLint override (replaced by flat config overrides).
src/utils/validator.js Removes no-longer-needed ESLint disable comment.
.gitignore Adds .claude to ignored files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}
}
cli.table(projects, columns)
table(projects, columns)
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

table() defaults to console.log, which bypasses the command’s this.log/stdout handling. Consider passing printLine: this.log.bind(this) so table output flows through the same channel as other command output (and is easier to stub in tests).

Suggested change
table(projects, columns)
table(projects, columns, { printLine: this.log.bind(this) })

Copilot uses AI. Check for mistakes.
Comment on lines 18 to 55
table: jest.fn((data, columns, options) => {
const printLine = options?.printLine || console.log.bind(console)
const headerKeys = Object.keys(columns)

const colWidths = headerKeys.map(key => {
const col = columns[key]
const header = col.header || key.toUpperCase()
let maxWidth = col.minWidth || header.length

if (header.length > maxWidth) maxWidth = header.length
data.forEach(row => {
const strValue = String(row[key] ?? '')
if (strValue.length > maxWidth) maxWidth = strValue.length
})

const isLastColumn = headerKeys.indexOf(key) === headerKeys.length - 1
if (col.minWidth && maxWidth === col.minWidth && !isLastColumn) {
maxWidth--
}
return maxWidth
})

const headers = headerKeys.map((key, idx) =>
(columns[key].header || key.toUpperCase()).padEnd(colWidths[idx], ' ')
)
printLine(' ' + headers.join(' ') + ' ')

const separator = colWidths.map(w => '─'.repeat(w)).join(' ')
printLine(' ' + separator + ' ')

data.forEach(row => {
const values = headerKeys.map((key, idx) =>
String(row[key] ?? '').padEnd(colWidths[idx], ' ')
)
printLine(' ' + values.join(' ') + ' ')
})
})
}
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mockUx.table re-implements the table rendering logic that now lives in src/utils/table.js, but nothing in src/ or test/ appears to call ux.table anymore. Keeping this duplicated implementation increases drift risk and maintenance cost.

Consider removing mockUx.table entirely, or delegating it to the shared table utility if you still need it for any tests.

Copilot uses AI. Check for mistakes.
Comment on lines +34 to +37
const isLastColumn = headerKeys.indexOf(key) === headerKeys.length - 1
if (col.minWidth && maxWidth === col.minWidth && !isLastColumn) {
maxWidth--
}
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

headerKeys.indexOf(key) inside the map introduces an unnecessary O(n²) scan. Since map already has the index, use the callback index to determine whether this is the last column for clearer and more efficient code.

Copilot uses AI. Check for mistakes.
}
const lines = []
table(data, columns, { printLine: (l) => lines.push(l) })
expect(lines).toHaveLength(3)
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The last test only asserts the number of lines, so it doesn’t actually validate the behavior described in the test name (the maxWidth decrement). Consider asserting on the rendered header/separator widths (or a specific expected output) so the test would fail if that decrement logic regresses.

Suggested change
expect(lines).toHaveLength(3)
expect(lines).toHaveLength(3)
// Verify that the non-last column's effective width is smaller than the last column's,
// reflecting the maxWidth decrement behavior.
const headerLine = lines[0]
const indexA = headerLine.indexOf('A')
const indexB = headerLine.indexOf('B')
// Sanity checks: both headers should be present in the header line.
expect(indexA).toBeGreaterThanOrEqual(0)
expect(indexB).toBeGreaterThan(indexA)
const firstColumnSpan = indexB - indexA
const secondColumnSpan = headerLine.length - indexB
// Because maxWidth is decremented for non-last columns when minWidth === maxWidth,
// the first column's span should be strictly less than the second column's span.
expect(firstColumnSpan).toBeLessThan(secondColumnSpan)

Copilot uses AI. Check for mistakes.
Comment on lines +35 to +44
...pluginJest.configs['flat/recommended'],
rules: {
...pluginJest.configs['flat/recommended'].rules
}
},
{
files: ['e2e/**/*.js'],
...pluginJest.configs['flat/recommended'],
rules: {
...pluginJest.configs['flat/recommended'].rules,
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the test/**/*.js and e2e/**/*.js overrides, ...pluginJest.configs['flat/recommended'] already includes the rules field; re-specifying rules: { ...pluginJest.configs['flat/recommended'].rules } is redundant and makes it easier for the two to get out of sync if one side changes.

Consider removing the redundant rules assignments (keeping only the additional overrides you need).

Suggested change
...pluginJest.configs['flat/recommended'],
rules: {
...pluginJest.configs['flat/recommended'].rules
}
},
{
files: ['e2e/**/*.js'],
...pluginJest.configs['flat/recommended'],
rules: {
...pluginJest.configs['flat/recommended'].rules,
...pluginJest.configs['flat/recommended']
},
{
files: ['e2e/**/*.js'],
...pluginJest.configs['flat/recommended']
},
{
files: ['e2e/**/*.js'],
rules: {

Copilot uses AI. Check for mistakes.
}
}
cli.table(projects, columns)
table(projects, columns)
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

table() defaults to console.log, which bypasses the command’s this.log/stdout handling. For consistency with registration:list (and to make output interception/redirection more predictable), consider passing printLine: this.log.bind(this) here as well.

Suggested change
table(projects, columns)
table(projects, columns, { printLine: this.log.bind(this) })

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore: update @oclif/core to latest version

3 participants