#!/usr/bin/env node /** * cli:finish — Finish a feature/release/hotfix branch * Responsabilité : Parse args → validate → execute → output JSON */ import { parseArgs } from 'node:util' import { validate } from './validate.js' import { execute } from './execute.js' import type { FinishResult } from './types.js' // ─── Parse des arguments ────────────────────────────────────────────────────── const { values } = parseArgs({ options: { spec: { type: 'string' }, workdir: { type: 'string' }, json: { type: 'boolean' }, help: { type: 'boolean', short: 'h' }, }, }) if (values.help) { console.log(` cli:finish — Finish a feature/release/hotfix branch Usage: npx --prefer-offline tsx cli/finish/index.ts --spec '' Options: --spec JSON spec with { branch?: string } (defaults to current branch) --json Output JSON only --help Show this help `) process.exit(0) } // ─── Parse du JSON ──────────────────────────────────────────────────────────── let spec: unknown = {} if (values.spec) { try { spec = JSON.parse(values.spec) } catch { const result: FinishResult = { success: false, branch: '', branchType: 'feature', error: 'Invalid JSON in --spec', } output(result, values.json ?? false) process.exit(2) } } // ─── Validation ─────────────────────────────────────────────────────────────── const validation = validate(spec) if (!validation.valid) { const result: FinishResult = { success: false, branch: '', branchType: 'feature', error: validation.blockers.join('; '), } output(result, values.json ?? false) process.exit(2) } // ─── Exécution ──────────────────────────────────────────────────────────────── execute(validation.data as any, values.workdir ?? process.cwd()) .then((result) => { output(result, values.json ?? false) const exitCode = result.success ? 0 : validation.blockers.length > 0 ? 2 : 1 process.exit(exitCode) }) .catch((err) => { const message = err instanceof Error ? err.message : String(err) const result: FinishResult = { success: false, branch: '', branchType: 'feature', error: message, } output(result, values.json ?? false) process.exit(2) }) // ─── Helper ─────────────────────────────────────────────────────────────────── function output(data: FinishResult, json: boolean): void { if (json) { console.log(JSON.stringify(data, null, 2)) } else { if (data.success) { console.log(`✓ Finished ${data.branchType} branch: ${data.branch}`) if (data.tag) console.log(` Tagged as: ${data.tag}`) if (data.mergedBack) console.log(` Merged back to develop`) if (data.versionBumped) console.log(` Version bumped`) if (data.worktreeCleaned) console.log(` Worktree cleaned`) } else { console.error(`✗ Failed to finish branch: ${data.error}`) } for (const w of data.warnings ?? []) console.warn(`⚠ ${w}`) } }