* fix(#1836): count prefixed milestone phase dirs * chore(#1836): add changeset fragment
This commit is contained in:
5
.changeset/eager-ibex-bark.md
Normal file
5
.changeset/eager-ibex-bark.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
type: Fixed
|
||||
pr: 1844
|
||||
---
|
||||
**`init milestone-op` now counts project_code-prefixed phase directories correctly** — fully shipped milestones using the standard prefixed directory layout no longer report `completed_phases: 0` or stay falsely incomplete. (#1844)
|
||||
@@ -64,7 +64,7 @@ const {
|
||||
extractCurrentMilestone,
|
||||
} = roadmapParser;
|
||||
const { pathExistsInternal, generateSlugInternal, toPosixPath } = coreUtils;
|
||||
const { normalizePhaseName, phaseTokenMatches } = phaseId;
|
||||
const { normalizePhaseName, phaseTokenMatches, stripProjectCodePrefix } = phaseId;
|
||||
const { pruneOrphanedWorktrees } = worktreeSafety;
|
||||
|
||||
const {
|
||||
@@ -1204,7 +1204,7 @@ function cmdInitMilestoneOp(cwd: string, raw: boolean): void {
|
||||
const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
|
||||
for (const e of entries) {
|
||||
if (!e.isDirectory()) continue;
|
||||
const m = e.name.match(/^(\d+[A-Z]?(?:\.\d+)*)/);
|
||||
const m = stripProjectCodePrefix(e.name).match(/^(\d+[A-Z]?(?:\.\d+)*)/);
|
||||
if (!m) continue;
|
||||
diskPhaseDirs.set(canonicalizePhase(m[1]), e.name);
|
||||
}
|
||||
|
||||
@@ -967,6 +967,47 @@ describe('cmdInitMilestoneOp', () => {
|
||||
assert.strictEqual(output.all_phases_complete, true);
|
||||
});
|
||||
|
||||
test('project_code-prefixed phase directories count as completed milestone phases (#1836)', () => {
|
||||
seedPhase(tmpDir, 'PROJ-01-setup', {
|
||||
'PROJ-01-01-PLAN.md': '# Plan',
|
||||
'PROJ-01-01-SUMMARY.md': '# Summary',
|
||||
});
|
||||
fs.writeFileSync(
|
||||
path.join(tmpDir, '.planning', 'config.json'),
|
||||
JSON.stringify({ project_code: 'PROJ' }, null, 2)
|
||||
);
|
||||
fs.writeFileSync(
|
||||
path.join(tmpDir, '.planning', 'STATE.md'),
|
||||
[
|
||||
'---',
|
||||
'gsd_state_version: 1.0',
|
||||
'milestone: v1.0.0',
|
||||
'milestone_name: Test Milestone',
|
||||
'status: executing',
|
||||
'---',
|
||||
'',
|
||||
].join('\n')
|
||||
);
|
||||
fs.writeFileSync(
|
||||
path.join(tmpDir, '.planning', 'ROADMAP.md'),
|
||||
[
|
||||
'# Roadmap',
|
||||
'',
|
||||
'## 🚧 v1.0.0 Test Milestone',
|
||||
'### Phase 1: Setup',
|
||||
'',
|
||||
].join('\n')
|
||||
);
|
||||
|
||||
const result = runGsdTools('init milestone-op', tmpDir);
|
||||
assert.ok(result.success, `Command failed: ${result.error}`);
|
||||
|
||||
const output = JSON.parse(result.output);
|
||||
assert.strictEqual(output.phase_count, 1);
|
||||
assert.strictEqual(output.completed_phases, 1);
|
||||
assert.strictEqual(output.all_phases_complete, true);
|
||||
});
|
||||
|
||||
test('archive directory scanning', () => {
|
||||
fs.mkdirSync(path.join(tmpDir, '.planning', 'archive', 'v1.0'), { recursive: true });
|
||||
fs.mkdirSync(path.join(tmpDir, '.planning', 'archive', 'v0.9'), { recursive: true });
|
||||
|
||||
Reference in New Issue
Block a user