Skip to content

fix(export): exit 0 on a successful export regardless of source lint findings - #126

Merged
davideast merged 1 commit into
google-labs-code:mainfrom
rmyndharis:fix/export-exit-code
Jul 1, 2026
Merged

fix(export): exit 0 on a successful export regardless of source lint findings#126
davideast merged 1 commit into
google-labs-code:mainfrom
rmyndharis:fix/export-exit-code

Conversation

@rmyndharis

Copy link
Copy Markdown
Contributor

Summary

export set its exit code from the source's lint summary:

process.exitCode = report.summary.errors > 0 ? 1 : 0;

So exporting a DESIGN.md that has a lint error (e.g. one invalid color) exited 1 even though the export ran and produced correct output for every valid token. That conflates two different things — "the source has lint findings" and "the export failed" — in one exit code, and it's undocumented.

Change (behavior change)

Decouple the export exit code from source lint findings:

  • 0 — export succeeded (even if the source has lint findings; use lint to gate on those)
  • 1 — invalid --format or an emitter failure
  • 2 — input file could not be read (readInput)

Documented in the README's export section. This is a deliberate behavior change on the success path (export of a lint-error file: 10); flagging it explicitly in case the coupling was intended as a validation gate — lint already serves that purpose.

Testing

  • New commands/export-exit-code.test.ts (spawns the CLI): export of a lint-error file → exit 0 with output; lint of the same file → exit 1.
  • bun test: 284 pass, 1 skip, 0 fail. bun run lint: clean.
  • Verified against the built CLI with both an error-containing and a valid source.

…findings

The export command derived its exit code from the source's lint summary, so
exporting a file that had any lint *error* exited 1 even though the export
produced correct output. That conflates "the source has lint findings"
(which `lint` already reports by exiting 1) with "the export failed."

Decouple them: a successful export exits 0; only an invalid --format or an
emitter failure exits 1 (and an unreadable input exits 2, via readInput).
Document the export exit codes in the README.

@rajpratham1 rajpratham1 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a sensible fix that clearly separates the responsibilities of the export and lint commands. If an export successfully produces output, it should exit with 0 regardless of lint findings, while lint remains the command responsible for enforcing validation failures. The added regression tests cover both behaviors, and the README has been updated to document the exit code semantics.

@rajpratham1 rajpratham1 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change corrects the CLI behavior by separating export success from lint validation. If an export is successfully generated, it should return a success exit code regardless of validation findings, while lint remains the command responsible for enforcing validation failures. The implementation is small, well-scoped, and backed by appropriate regression tests and documentation updates.

@davideast davideast left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you yet again (and again) @rmyndharis!

@davideast
davideast merged commit 3486d7a into google-labs-code:main Jul 1, 2026
9 checks passed
davideast pushed a commit that referenced this pull request Jul 14, 2026
The success branches (css-tailwind, json-tailwind, dtcg, css-vars) write
their output but never assign process.exitCode, so a successful export
left the code at its incoming value instead of an explicit 0. That is the
success-path counterpart to #126, which decoupled the exit code from
source lint findings; the subprocess test there only exercises json-tailwind
and a real process happens to exit 0 when exitCode is unset, so the gap went
unnoticed. Set process.exitCode = 0 after the format branches (every error
branch already returns first).

The in-process export.test.ts added in #109 asserts process.exitCode === 0
after a css-vars export, so it was failing on main. Also fix a companion
assertion in that file: it read error.error for the human message, but the
error envelope is { error: CODE, message: TEXT }, so the text lives on
error.message.

Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
@davideast davideast mentioned this pull request Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants