feat: add next-step hints and submodule check to CLI commands
This commit is contained in:
parent
fd2c8ba640
commit
6a36497205
7 changed files with 36 additions and 1 deletions
|
|
@ -49,6 +49,9 @@ export class CancelCommand extends CLICommand {
|
||||||
args.reason as string
|
args.reason as string
|
||||||
)
|
)
|
||||||
console.log(`Issue #${issue.id} is now cancelled`)
|
console.log(`Issue #${issue.id} is now cancelled`)
|
||||||
|
if (branch !== "develop") {
|
||||||
|
console.log(`Switch back to develop: git checkout develop`)
|
||||||
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ export class CreateCommand extends CLICommand {
|
||||||
writeTodoFile(todo)
|
writeTodoFile(todo)
|
||||||
commitFile("TODO", `todo(${nextId}): open`)
|
commitFile("TODO", `todo(${nextId}): open`)
|
||||||
console.log(`Created issue #${nextId}: ${args.title}`)
|
console.log(`Created issue #${nextId}: ${args.title}`)
|
||||||
|
console.log(`Start working: mime-todo start ${nextId}`)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import type { Argv, ArgumentsCamelCase } from "yargs"
|
import type { Argv, ArgumentsCamelCase } from "yargs"
|
||||||
import { CLICommand } from "../cli/CLICommand.js"
|
import { CLICommand } from "../cli/CLICommand.js"
|
||||||
import { parseTodoFile, writeTodoFile } from "../file.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"
|
import { validateStatusTransition } from "../issue.js"
|
||||||
|
|
||||||
export class DoneCommand extends CLICommand {
|
export class DoneCommand extends CLICommand {
|
||||||
|
|
@ -17,6 +17,11 @@ export class DoneCommand extends CLICommand {
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
description: "High-level summary of what was delivered",
|
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> {
|
async execute(args: ArgumentsCamelCase): Promise<number> {
|
||||||
|
|
@ -41,6 +46,14 @@ export class DoneCommand extends CLICommand {
|
||||||
return 1
|
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"
|
issue.status = "done"
|
||||||
writeTodoFile(todo)
|
writeTodoFile(todo)
|
||||||
commitFileWithBody(
|
commitFileWithBody(
|
||||||
|
|
@ -49,6 +62,8 @@ export class DoneCommand extends CLICommand {
|
||||||
args.summary as string
|
args.summary as string
|
||||||
)
|
)
|
||||||
console.log(`Issue #${issue.id} is now done`)
|
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
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ export class HoldCommand extends CLICommand {
|
||||||
args.reason as string
|
args.reason as string
|
||||||
)
|
)
|
||||||
console.log(`Issue #${issue.id} is now on hold`)
|
console.log(`Issue #${issue.id} is now on hold`)
|
||||||
|
console.log(`Switch back to develop: git checkout develop`)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,7 @@ export class InitCommand extends CLICommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`\nInit complete: ${created} items created`)
|
console.log(`\nInit complete: ${created} items created`)
|
||||||
|
console.log(`Push issues to Bugzilla: mime-todo push`)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ export class StartCommand extends CLICommand {
|
||||||
)
|
)
|
||||||
console.log(`Issue #${issue.id} is now in-progress`)
|
console.log(`Issue #${issue.id} is now in-progress`)
|
||||||
console.log(`Create the issue branch: git checkout -b ${issueBranch}`)
|
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
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
src/git.ts
13
src/git.ts
|
|
@ -87,6 +87,19 @@ function parseGitLog(range: string, cwd: string): GitCommit[] {
|
||||||
return commits
|
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
|
// Check if a commit subject is a todo transition
|
||||||
export function parseTodoTransition(subject: string): { issueId: number; status: string } | null {
|
export function parseTodoTransition(subject: string): { issueId: number; status: string } | null {
|
||||||
const match = subject.match(/^todo\((\d+)\):\s*([a-z-]+)/)
|
const match = subject.match(/^todo\((\d+)\):\s*([a-z-]+)/)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue