From 8d40028ee1dc880bd18bf07a7a06f7c378dc5a5c Mon Sep 17 00:00:00 2001 From: David Turnbull Date: Mon, 13 Oct 2025 11:19:42 +1100 Subject: [PATCH 1/4] feat(run): add --strict fail-fast mode; add plan.md for implementation plan --- packages/cli/src/cli/cmd/run/execute.ts | 7 ++++-- packages/cli/src/cli/cmd/run/index.ts | 4 ++++ plan.md | 30 +++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 plan.md diff --git a/packages/cli/src/cli/cmd/run/execute.ts b/packages/cli/src/cli/cmd/run/execute.ts index 16c63de22..65db722e4 100644 --- a/packages/cli/src/cli/cmd/run/execute.ts +++ b/packages/cli/src/cli/cmd/run/execute.ts @@ -77,7 +77,7 @@ export default async function execute(input: CmdRunContext) { return task.newListr(workerTasks, { concurrent: true, - exitOnError: false, + exitOnError: !!ctx.flags.strict, rendererOptions: { ...commonTaskRendererOptions, collapseSubtasks: true, @@ -87,7 +87,7 @@ export default async function execute(input: CmdRunContext) { }, ], { - exitOnError: false, + exitOnError: !!input.flags.strict, rendererOptions: commonTaskRendererOptions, }, ).run(input); @@ -296,6 +296,9 @@ function createWorkerTask(args: { targetLocale: assignedTask.targetLocale, } satisfies CmdRunTaskResult; } catch (error) { + if (args.ctx.flags.strict) { + throw error; + } return { status: "error", error: error as Error, diff --git a/packages/cli/src/cli/cmd/run/index.ts b/packages/cli/src/cli/cmd/run/index.ts index 8d8d80c17..10720ba63 100644 --- a/packages/cli/src/cli/cmd/run/index.ts +++ b/packages/cli/src/cli/cmd/run/index.ts @@ -112,6 +112,10 @@ export default new Command() "--sound", "Play audio feedback when translations complete (success or failure sounds)", ) + .option( + "--strict", + "Stop immediately on first error instead of continuing to process remaining buckets and locales (fail-fast mode)", + ) .action(async (args) => { let authId: string | null = null; try { diff --git a/plan.md b/plan.md new file mode 100644 index 000000000..37fa5a029 --- /dev/null +++ b/plan.md @@ -0,0 +1,30 @@ +Title: Add `--strict` to `run` with fail-fast behavior matching `i18n` + +Objective +- Implement a `--strict` flag for the `run` command that stops processing immediately on the first error, mirroring the `i18n` command’s fail-fast behavior. + +Scope +- `packages/cli/src/cli/cmd/run/index.ts` +- `packages/cli/src/cli/cmd/run/execute.ts` +- Verification only, no changes required in `packages/cli/src/cli/cmd/run/_types.ts:46`. + +Implementation Steps +1) Expose CLI flag in `packages/cli/src/cli/cmd/run/index.ts:60`: + - Add `.option("--strict", "Stop immediately on first error instead of continuing to process remaining buckets and locales (fail-fast mode)")` alongside the other flags. + +2) Enforce fail-fast execution in `packages/cli/src/cli/cmd/run/execute.ts`: + - Top-level Listr: set `exitOnError` to `true` when `input.flags.strict` is `true`. + - Worker sub-Listr: set `exitOnError` to `true` when `ctx.flags.strict` is `true`. + - In `createWorkerTask` error handling, rethrow on error when `args.ctx.flags.strict` is `true`; otherwise, return the `{ status: "error", ... }` result so non-strict runs continue. + +3) Types validation + - No change required; `packages/cli/src/cli/cmd/run/_types.ts:46` already defines `strict: z.boolean().optional()` and is consumed via `flagsSchema.parse(args)`. + +Behavioral Guarantees +- With `--strict`, the first task error aborts the pipeline immediately and returns a non-zero exit code. +- Without `--strict`, the pipeline continues processing remaining tasks and reports a per-task summary including errors and successes. +- Watch mode continues to observe files. Each triggered run honors `--strict` for that run and resumes watching afterward. + +Rationale From `i18n` Review +- `packages/cli/src/cli/cmd/i18n.ts:522` and `packages/cli/src/cli/cmd/i18n.ts:548` throw on errors when `flags.strict` is `true` and otherwise continue while tracking errors. The above changes apply the same semantics to the `run` pipeline, which executes tasks concurrently via Listr. + From e5d21c367063d5091c56299bbd962f3be6d8d8ab Mon Sep 17 00:00:00 2001 From: David Turnbull Date: Fri, 10 Oct 2025 09:29:25 +1100 Subject: [PATCH 2/4] chore: add changeset for --strict flag --- .changeset/add-run-strict-flag.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .changeset/add-run-strict-flag.md diff --git a/.changeset/add-run-strict-flag.md b/.changeset/add-run-strict-flag.md new file mode 100644 index 000000000..14784b77e --- /dev/null +++ b/.changeset/add-run-strict-flag.md @@ -0,0 +1,4 @@ +--- +"lingo.dev": minor +--- +Add `--strict` mode to stop on the first error. From a2b7d8b9ae2b2769744c5bf0cec59569f5bbb1d1 Mon Sep 17 00:00:00 2001 From: David Turnbull Date: Mon, 13 Oct 2025 12:13:25 +1100 Subject: [PATCH 3/4] chore: format --- plan.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/plan.md b/plan.md index 37fa5a029..57a97531f 100644 --- a/plan.md +++ b/plan.md @@ -1,30 +1,36 @@ Title: Add `--strict` to `run` with fail-fast behavior matching `i18n` Objective + - Implement a `--strict` flag for the `run` command that stops processing immediately on the first error, mirroring the `i18n` command’s fail-fast behavior. Scope + - `packages/cli/src/cli/cmd/run/index.ts` - `packages/cli/src/cli/cmd/run/execute.ts` - Verification only, no changes required in `packages/cli/src/cli/cmd/run/_types.ts:46`. Implementation Steps -1) Expose CLI flag in `packages/cli/src/cli/cmd/run/index.ts:60`: + +1. Expose CLI flag in `packages/cli/src/cli/cmd/run/index.ts:60`: + - Add `.option("--strict", "Stop immediately on first error instead of continuing to process remaining buckets and locales (fail-fast mode)")` alongside the other flags. -2) Enforce fail-fast execution in `packages/cli/src/cli/cmd/run/execute.ts`: +2. Enforce fail-fast execution in `packages/cli/src/cli/cmd/run/execute.ts`: + - Top-level Listr: set `exitOnError` to `true` when `input.flags.strict` is `true`. - Worker sub-Listr: set `exitOnError` to `true` when `ctx.flags.strict` is `true`. - In `createWorkerTask` error handling, rethrow on error when `args.ctx.flags.strict` is `true`; otherwise, return the `{ status: "error", ... }` result so non-strict runs continue. -3) Types validation +3. Types validation - No change required; `packages/cli/src/cli/cmd/run/_types.ts:46` already defines `strict: z.boolean().optional()` and is consumed via `flagsSchema.parse(args)`. Behavioral Guarantees + - With `--strict`, the first task error aborts the pipeline immediately and returns a non-zero exit code. - Without `--strict`, the pipeline continues processing remaining tasks and reports a per-task summary including errors and successes. - Watch mode continues to observe files. Each triggered run honors `--strict` for that run and resumes watching afterward. Rationale From `i18n` Review -- `packages/cli/src/cli/cmd/i18n.ts:522` and `packages/cli/src/cli/cmd/i18n.ts:548` throw on errors when `flags.strict` is `true` and otherwise continue while tracking errors. The above changes apply the same semantics to the `run` pipeline, which executes tasks concurrently via Listr. +- `packages/cli/src/cli/cmd/i18n.ts:522` and `packages/cli/src/cli/cmd/i18n.ts:548` throw on errors when `flags.strict` is `true` and otherwise continue while tracking errors. The above changes apply the same semantics to the `run` pipeline, which executes tasks concurrently via Listr. From 17ccf2039d04b31edcad24578a1795c8a2d96fef Mon Sep 17 00:00:00 2001 From: David Turnbull Date: Mon, 13 Oct 2025 12:17:52 +1100 Subject: [PATCH 4/4] chore: remove accidental plan.md --- plan.md | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 plan.md diff --git a/plan.md b/plan.md deleted file mode 100644 index 57a97531f..000000000 --- a/plan.md +++ /dev/null @@ -1,36 +0,0 @@ -Title: Add `--strict` to `run` with fail-fast behavior matching `i18n` - -Objective - -- Implement a `--strict` flag for the `run` command that stops processing immediately on the first error, mirroring the `i18n` command’s fail-fast behavior. - -Scope - -- `packages/cli/src/cli/cmd/run/index.ts` -- `packages/cli/src/cli/cmd/run/execute.ts` -- Verification only, no changes required in `packages/cli/src/cli/cmd/run/_types.ts:46`. - -Implementation Steps - -1. Expose CLI flag in `packages/cli/src/cli/cmd/run/index.ts:60`: - - - Add `.option("--strict", "Stop immediately on first error instead of continuing to process remaining buckets and locales (fail-fast mode)")` alongside the other flags. - -2. Enforce fail-fast execution in `packages/cli/src/cli/cmd/run/execute.ts`: - - - Top-level Listr: set `exitOnError` to `true` when `input.flags.strict` is `true`. - - Worker sub-Listr: set `exitOnError` to `true` when `ctx.flags.strict` is `true`. - - In `createWorkerTask` error handling, rethrow on error when `args.ctx.flags.strict` is `true`; otherwise, return the `{ status: "error", ... }` result so non-strict runs continue. - -3. Types validation - - No change required; `packages/cli/src/cli/cmd/run/_types.ts:46` already defines `strict: z.boolean().optional()` and is consumed via `flagsSchema.parse(args)`. - -Behavioral Guarantees - -- With `--strict`, the first task error aborts the pipeline immediately and returns a non-zero exit code. -- Without `--strict`, the pipeline continues processing remaining tasks and reports a per-task summary including errors and successes. -- Watch mode continues to observe files. Each triggered run honors `--strict` for that run and resumes watching afterward. - -Rationale From `i18n` Review - -- `packages/cli/src/cli/cmd/i18n.ts:522` and `packages/cli/src/cli/cmd/i18n.ts:548` throw on errors when `flags.strict` is `true` and otherwise continue while tracking errors. The above changes apply the same semantics to the `run` pipeline, which executes tasks concurrently via Listr.