diff --git a/.changeset/1324-glued-phase-token.md b/.changeset/1324-glued-phase-token.md new file mode 100644 index 000000000..3548bb0d7 --- /dev/null +++ b/.changeset/1324-glued-phase-token.md @@ -0,0 +1,6 @@ +--- +type: Fixed +pr: 1353 +--- + +**Glued letter-prefix phase directories now resolve correctly** -- phase lookup now recognizes tokens like `P0.3` and `M1-2` from directory names, so phase commands can find their plans instead of reporting none found. (#1324) diff --git a/src/phase-id.cts b/src/phase-id.cts index 2dfd34e61..bee1cc6c1 100644 --- a/src/phase-id.cts +++ b/src/phase-id.cts @@ -174,7 +174,7 @@ function extractPhaseToken(dirName: string): string { const tokenSegments: string[] = []; for (let i = 0; i < segments.length; i++) { const seg = segments[i]; - if (/^\d/.test(seg)) { + if (/^\d/.test(seg) || (i === 0 && /^[A-Za-z]{1,3}\d/.test(seg))) { tokenSegments.push(seg); } else { break; diff --git a/tests/phase-id.test.cjs b/tests/phase-id.test.cjs index f299ce4fd..615aaa1eb 100644 --- a/tests/phase-id.test.cjs +++ b/tests/phase-id.test.cjs @@ -185,9 +185,17 @@ describe('extractPhaseToken', () => { assert.strictEqual(phaseId.extractPhaseToken('PROJ-12-feature'), 'PROJ-12'); }); + test('extracts glued letter-prefix phase tokens (#1324)', () => { + assert.strictEqual(phaseId.extractPhaseToken('P0.3-tenant-primitives'), 'P0.3'); + assert.strictEqual(phaseId.extractPhaseToken('P0.0-foundation'), 'P0.0'); + assert.strictEqual(phaseId.extractPhaseToken('P0.16-gate'), 'P0.16'); + assert.strictEqual(phaseId.extractPhaseToken('M1-2-brain'), 'M1-2'); + }); + test('returns the full dirName when no numeric token found', () => { assert.strictEqual(phaseId.extractPhaseToken('no-numeric'), 'no-numeric'); assert.strictEqual(phaseId.extractPhaseToken('alpha'), 'alpha'); + assert.strictEqual(phaseId.extractPhaseToken('phase-name-01'), 'phase-name-01'); }); test('stops at first non-numeric-starting segment', () => { @@ -209,6 +217,12 @@ describe('phaseTokenMatches', () => { assert.ok(phaseId.phaseTokenMatches('PROJ-12-feature', '12')); }); + test('matches glued letter-prefix phase dirs (#1324)', () => { + assert.ok(phaseId.phaseTokenMatches('P0.3-tenant-primitives', 'P0.3')); + assert.ok(phaseId.phaseTokenMatches('M1-2-brain', 'M1-2')); + assert.ok(!phaseId.phaseTokenMatches('P0.3-tenant-primitives', 'P0.4')); + }); + test('does not match when token differs', () => { assert.ok(!phaseId.phaseTokenMatches('01-some-phase', '02')); assert.ok(!phaseId.phaseTokenMatches('12A-feature', '12B')); @@ -386,4 +400,3 @@ describe('getPhaseDirFromPhaseId', () => { assert.ok(!result.endsWith('-')); }); }); -