Skip to content

Commit 09f511a

Browse files
Copilotvoxpelli
andauthored
fix: kebab-case CLI flags broke in peowly migration (#125)
* Initial plan * Fix kebab-case CLI flags broken by meow→peowly migration; add regression tests Co-authored-by: voxpelli <34457+voxpelli@users.noreply.github.com> * test: add negative test to validate assertFlagRecognised catches unknown flags Co-authored-by: voxpelli <34457+voxpelli@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: voxpelli <34457+voxpelli@users.noreply.github.com>
1 parent 7700887 commit 09f511a

2 files changed

Lines changed: 53 additions & 14 deletions

File tree

cli.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,21 +47,21 @@ const baseFlags = /** @satisfies {Record<string, import('peowly').AnyFlag>} */ (
4747
});
4848

4949
const checkFlags = /** @satisfies {Record<string, import('peowly').AnyFlag & { listGroup: 'Checks' }>} */ ({
50-
engineCheck: {
50+
'engine-check': {
5151
'short': 'e',
5252
type: 'boolean',
5353
'default': false,
5454
description: 'Override default checks and explicitly request an engine range check',
5555
listGroup: 'Checks',
5656
},
57-
peerCheck: {
57+
'peer-check': {
5858
'short': 'p',
5959
type: 'boolean',
6060
'default': false,
6161
description: 'Override default checks and explicitly request a peer dependency range check',
6262
listGroup: 'Checks',
6363
},
64-
versionCheck: {
64+
'version-check': {
6565
'short': 'c',
6666
type: 'boolean',
6767
'default': false,
@@ -78,7 +78,7 @@ const checkOptionFlags = /** @satisfies {Record<string, import('peowly').AnyFlag
7878
description: 'Excludes the named dependency from non-version checks (Supports globs)',
7979
listGroup: 'Check options',
8080
},
81-
ignoreDev: {
81+
'ignore-dev': {
8282
'short': 'd',
8383
type: 'boolean',
8484
'default': false,
@@ -129,7 +129,7 @@ const workspaceFlags = /** @satisfies {Record<string, import('peowly').AnyFlag &
129129
description: 'Excludes all workspace packages not matching these names / paths',
130130
listGroup: 'Workspace options',
131131
},
132-
workspaceIgnore: {
132+
'workspace-ignore': {
133133
type: 'string',
134134
multiple: true,
135135
description: 'Excludes the specified paths from workspace lookup (Supports globs)',
@@ -138,13 +138,13 @@ const workspaceFlags = /** @satisfies {Record<string, import('peowly').AnyFlag &
138138
});
139139

140140
const deprecatedFlags = /** @satisfies {Record<string, import('peowly').AnyFlag & { listGroup: 'Deprecated options' }>} */ ({
141-
engineIgnore: {
141+
'engine-ignore': {
142142
type: 'string',
143143
multiple: true,
144144
description: 'Deprecated: use --ignore instead',
145145
listGroup: 'Deprecated options',
146146
},
147-
engineNoDev: {
147+
'engine-no-dev': {
148148
type: 'boolean',
149149
'default': false,
150150
description: 'Deprecated: use --ignore-dev instead',
@@ -178,21 +178,21 @@ if (cli.input.length > 1) {
178178

179179
const {
180180
debug,
181-
engineCheck,
182-
engineIgnore, // deprecated
183-
engineNoDev, // deprecated
181+
'engine-check': engineCheck,
182+
'engine-ignore': engineIgnore, // deprecated
183+
'engine-no-dev': engineNoDev, // deprecated
184184
fix,
185-
peerCheck,
185+
'peer-check': peerCheck,
186186
strict,
187187
verbose,
188-
versionCheck,
188+
'version-check': versionCheck,
189189
workspace,
190-
workspaceIgnore,
190+
'workspace-ignore': workspaceIgnore,
191191
} = cli.flags;
192192

193193
let {
194194
ignore,
195-
ignoreDev,
195+
'ignore-dev': ignoreDev,
196196
} = cli.flags;
197197

198198
const includeWorkspaceRoot = !cli.flags['no-include-workspace-root'];

test/integration.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,19 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
1616
const rootDir = join(__dirname, '..');
1717
const cliPath = join(rootDir, 'cli-wrapper.cjs');
1818

19+
/**
20+
* Asserts that a CLI flag is recognised (not rejected as "Unknown option").
21+
*
22+
* @param {string} flag
23+
*/
24+
async function assertFlagRecognised (flag) {
25+
const result = await run(`node "${cliPath}" ${flag} examples/basic`, rootDir);
26+
assert.ok(
27+
!result.output.includes('Unknown option'),
28+
`Flag ${flag} should be recognised by the CLI, got:\n${result.output}`
29+
);
30+
}
31+
1932
describe('Basic Example', () => {
2033
it('output matches README expected output', async () => {
2134
const expectedOutput = await extractExpectedOutput(join(rootDir, 'examples/basic/README.md'));
@@ -118,3 +131,29 @@ describe('Monorepo Example', () => {
118131
);
119132
});
120133
});
134+
135+
describe('CLI flag names', () => {
136+
// Regression tests: these flags broke when migrating from meow to peowly because
137+
// peowly uses flag key names as-is (no camelCase→kebab-case conversion like meow did).
138+
// Each test ensures the flag is recognised by the CLI (not rejected as "Unknown option").
139+
140+
it('rejects an unknown flag (validates assertFlagRecognised itself)', async () => {
141+
// A camelCase flag like --engineCheck is unknown to peowly — this negative test
142+
// confirms that assertFlagRecognised would catch a regression if a kebab-case key
143+
// were accidentally reverted to camelCase.
144+
const result = await run(`node "${cliPath}" --engineCheck examples/basic`, rootDir);
145+
assert.ok(
146+
result.output.includes('Unknown option'),
147+
`Expected --engineCheck to be rejected as unknown, got:\n${result.output}`
148+
);
149+
assert.notEqual(result.code, 0, `Expected non-zero exit code for unknown flag, got ${result.code}`);
150+
});
151+
152+
it('accepts --engine-check', async () => { await assertFlagRecognised('--engine-check'); });
153+
it('accepts --peer-check', async () => { await assertFlagRecognised('--peer-check'); });
154+
it('accepts --version-check', async () => { await assertFlagRecognised('--version-check'); });
155+
it('accepts --ignore-dev', async () => { await assertFlagRecognised('--ignore-dev'); });
156+
it('accepts --workspace-ignore', async () => { await assertFlagRecognised('--workspace-ignore=foo'); });
157+
it('accepts --engine-ignore (deprecated)', async () => { await assertFlagRecognised('--engine-ignore=foo'); });
158+
it('accepts --engine-no-dev (deprecated)', async () => { await assertFlagRecognised('--engine-no-dev'); });
159+
});

0 commit comments

Comments
 (0)