mirror of
https://github.com/glittercowboy/get-shit-done
synced 2026-04-26 01:35:29 +02:00
Compare commits
1 Commits
fix/2180-c
...
fix/2192-c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6e33602c3 |
@@ -58,6 +58,16 @@ function cmdInitExecutePhase(cwd, phase, raw, options = {}) {
|
||||
|
||||
const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
|
||||
|
||||
// If findPhaseInternal matched an archived phase from a prior milestone, but
|
||||
// the phase exists in the current milestone's ROADMAP.md, ignore the archive
|
||||
// match — we are initializing a new phase in the current milestone that
|
||||
// happens to share a number with an archived one. Without this, phase_dir,
|
||||
// phase_slug and related fields would point at artifacts from a previous
|
||||
// milestone.
|
||||
if (phaseInfo?.archived && roadmapPhase?.found) {
|
||||
phaseInfo = null;
|
||||
}
|
||||
|
||||
// Fallback to ROADMAP.md if no phase directory exists yet
|
||||
if (!phaseInfo && roadmapPhase?.found) {
|
||||
const phaseName = roadmapPhase.phase_name;
|
||||
@@ -181,6 +191,16 @@ function cmdInitPlanPhase(cwd, phase, raw, options = {}) {
|
||||
|
||||
const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
|
||||
|
||||
// If findPhaseInternal matched an archived phase from a prior milestone, but
|
||||
// the phase exists in the current milestone's ROADMAP.md, ignore the archive
|
||||
// match — we are planning a new phase in the current milestone that happens
|
||||
// to share a number with an archived one. Without this, phase_dir,
|
||||
// phase_slug, has_context and has_research would point at artifacts from a
|
||||
// previous milestone.
|
||||
if (phaseInfo?.archived && roadmapPhase?.found) {
|
||||
phaseInfo = null;
|
||||
}
|
||||
|
||||
// Fallback to ROADMAP.md if no phase directory exists yet
|
||||
if (!phaseInfo && roadmapPhase?.found) {
|
||||
const phaseName = roadmapPhase.phase_name;
|
||||
@@ -552,6 +572,16 @@ function cmdInitVerifyWork(cwd, phase, raw) {
|
||||
const config = loadConfig(cwd);
|
||||
let phaseInfo = findPhaseInternal(cwd, phase);
|
||||
|
||||
// If findPhaseInternal matched an archived phase from a prior milestone, but
|
||||
// the phase exists in the current milestone's ROADMAP.md, ignore the archive
|
||||
// match — same pattern as cmdInitPhaseOp.
|
||||
if (phaseInfo?.archived) {
|
||||
const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
|
||||
if (roadmapPhase?.found) {
|
||||
phaseInfo = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to ROADMAP.md if no phase directory exists yet
|
||||
if (!phaseInfo) {
|
||||
const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
|
||||
|
||||
@@ -352,6 +352,76 @@ describe('init commands ROADMAP fallback when phase directory does not exist (#1
|
||||
});
|
||||
});
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// init ignores archived phases from prior milestones that share a phase number
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('init commands ignore archived phases from prior milestones sharing a number', () => {
|
||||
let tmpDir;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpDir = createTempProject();
|
||||
// Current milestone ROADMAP has Phase 2 but no disk directory yet
|
||||
fs.writeFileSync(
|
||||
path.join(tmpDir, '.planning', 'ROADMAP.md'),
|
||||
'# v2.0 Roadmap\n\n### Phase 2: New Feature\n**Goal:** New v2.0 feature\n**Requirements**: NEW-01, NEW-02\n**Plans:** TBD\n'
|
||||
);
|
||||
// Prior milestone archive has a shipped Phase 2 with different slug and artifacts
|
||||
const archivedDir = path.join(tmpDir, '.planning', 'milestones', 'v1.0-phases', '02-old-feature');
|
||||
fs.mkdirSync(archivedDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(archivedDir, '2-CONTEXT.md'), '# OLD v1.0 Phase 2 context');
|
||||
fs.writeFileSync(path.join(archivedDir, '2-RESEARCH.md'), '# OLD v1.0 Phase 2 research');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanup(tmpDir);
|
||||
});
|
||||
|
||||
test('init plan-phase prefers current ROADMAP entry over archived v1.0 phase of same number', () => {
|
||||
const result = runGsdTools('init plan-phase 2', tmpDir);
|
||||
assert.ok(result.success, `Command failed: ${result.error}`);
|
||||
|
||||
const output = JSON.parse(result.output);
|
||||
assert.strictEqual(output.phase_found, true);
|
||||
assert.strictEqual(output.phase_name, 'New Feature',
|
||||
'phase_name must come from current ROADMAP.md, not archived v1.0');
|
||||
assert.strictEqual(output.phase_slug, 'new-feature');
|
||||
assert.strictEqual(output.phase_dir, null,
|
||||
'phase_dir must be null — current milestone has no directory yet');
|
||||
assert.strictEqual(output.has_context, false,
|
||||
'has_context must not inherit archived v1.0 artifacts');
|
||||
assert.strictEqual(output.has_research, false,
|
||||
'has_research must not inherit archived v1.0 artifacts');
|
||||
assert.ok(!output.context_path,
|
||||
'context_path must not point at archived v1.0 file');
|
||||
assert.ok(!output.research_path,
|
||||
'research_path must not point at archived v1.0 file');
|
||||
assert.strictEqual(output.phase_req_ids, 'NEW-01, NEW-02');
|
||||
});
|
||||
|
||||
test('init execute-phase prefers current ROADMAP entry over archived v1.0 phase of same number', () => {
|
||||
const result = runGsdTools('init execute-phase 2', tmpDir);
|
||||
assert.ok(result.success, `Command failed: ${result.error}`);
|
||||
|
||||
const output = JSON.parse(result.output);
|
||||
assert.strictEqual(output.phase_found, true);
|
||||
assert.strictEqual(output.phase_name, 'New Feature');
|
||||
assert.strictEqual(output.phase_slug, 'new-feature');
|
||||
assert.strictEqual(output.phase_dir, null);
|
||||
assert.strictEqual(output.phase_req_ids, 'NEW-01, NEW-02');
|
||||
});
|
||||
|
||||
test('init verify-work prefers current ROADMAP entry over archived v1.0 phase of same number', () => {
|
||||
const result = runGsdTools('init verify-work 2', tmpDir);
|
||||
assert.ok(result.success, `Command failed: ${result.error}`);
|
||||
|
||||
const output = JSON.parse(result.output);
|
||||
assert.strictEqual(output.phase_found, true);
|
||||
assert.strictEqual(output.phase_name, 'New Feature');
|
||||
assert.strictEqual(output.phase_dir, null);
|
||||
});
|
||||
});
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// cmdInitTodos (INIT-01)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user