Merge branch 'feature/9'

This commit is contained in:
Tiara Rodney 2026-03-20 21:21:21 +01:00
commit 48d6e105de
No known key found for this signature in database
GPG key ID: 5CD8EC1D46106723
8 changed files with 37 additions and 2 deletions

View file

@ -1,6 +1,6 @@
{
"name": "@byteb4rb1e/mime-todo",
"version": "0.3.4",
"version": "0.4.0",
"description": "CLI for the MIME TODO issue tracker specification with Bugzilla integration",
"author": "Tiara Rodney <me@tiararodney.com>",
"license": "CC-BY-ND-4.0",

View file

@ -49,6 +49,9 @@ export class CancelCommand extends CLICommand {
args.reason as string
)
console.log(`Issue #${issue.id} is now cancelled`)
if (branch !== "develop") {
console.log(`Switch back to develop: git checkout develop`)
}
return 0
}
}

View file

@ -78,6 +78,7 @@ export class CreateCommand extends CLICommand {
writeTodoFile(todo)
commitFile("TODO", `todo(${nextId}): open`)
console.log(`Created issue #${nextId}: ${args.title}`)
console.log(`Start working: mime-todo start ${nextId}`)
return 0
}
}

View file

@ -1,7 +1,7 @@
import type { Argv, ArgumentsCamelCase } from "yargs"
import { CLICommand } from "../cli/CLICommand.js"
import { parseTodoFile, writeTodoFile } from "../file.js"
import { getCurrentBranch, commitFileWithBody } from "../git.js"
import { getCurrentBranch, commitFileWithBody, getDirtySubmodules } from "../git.js"
import { validateStatusTransition } from "../issue.js"
export class DoneCommand extends CLICommand {
@ -17,6 +17,11 @@ export class DoneCommand extends CLICommand {
demandOption: true,
description: "High-level summary of what was delivered",
})
.option("confirm", {
type: "boolean",
default: false,
description: "Confirm that submodule branches have been merged and pointer updated",
})
}
async execute(args: ArgumentsCamelCase): Promise<number> {
@ -41,6 +46,14 @@ export class DoneCommand extends CLICommand {
return 1
}
// Check for dirty submodules
const dirtySubmodules = getDirtySubmodules()
if (dirtySubmodules.length > 0 && !(args.confirm as boolean)) {
console.error(`Submodule(s) have uncommitted changes or modified pointers: ${dirtySubmodules.join(", ")}`)
console.error(`Ensure feature branches are merged and pointers updated, then run with --confirm`)
return 1
}
issue.status = "done"
writeTodoFile(todo)
commitFileWithBody(
@ -49,6 +62,8 @@ export class DoneCommand extends CLICommand {
args.summary as string
)
console.log(`Issue #${issue.id} is now done`)
console.log(`Merge to develop: git checkout develop && git merge ${expectedBranch} --no-ff`)
console.log(`Then push to Bugzilla: mime-todo push`)
return 0
}
}

View file

@ -48,6 +48,7 @@ export class HoldCommand extends CLICommand {
args.reason as string
)
console.log(`Issue #${issue.id} is now on hold`)
console.log(`Switch back to develop: git checkout develop`)
return 0
}
}

View file

@ -152,6 +152,7 @@ export class InitCommand extends CLICommand {
}
console.log(`\nInit complete: ${created} items created`)
console.log(`Push issues to Bugzilla: mime-todo push`)
return 0
}
}

View file

@ -55,6 +55,7 @@ export class StartCommand extends CLICommand {
)
console.log(`Issue #${issue.id} is now in-progress`)
console.log(`Create the issue branch: git checkout -b ${issueBranch}`)
console.log(`If working in a submodule, also checkout there: cd <submodule> && git checkout -b ${issueBranch}`)
return 0
}
}

View file

@ -87,6 +87,19 @@ function parseGitLog(range: string, cwd: string): GitCommit[] {
return commits
}
// Check for dirty or modified submodules
export function getDirtySubmodules(cwd = process.cwd()): string[] {
try {
const output = execSync("git submodule status", { cwd, encoding: "utf-8" }).trim()
if (!output) return []
return output.split("\n")
.filter(line => line.startsWith("+") || line.startsWith("-"))
.map(line => line.trim().split(/\s+/)[1])
} catch {
return []
}
}
// Check if a commit subject is a todo transition
export function parseTodoTransition(subject: string): { issueId: number; status: string } | null {
const match = subject.match(/^todo\((\d+)\):\s*([a-z-]+)/)