Skip to content

refactor(builtins): migrate readlink to codegen-ported argument surface#1542

Merged
chaliy merged 3 commits intomainfrom
fix/issue-1532-readlink-codegen
May 5, 2026
Merged

refactor(builtins): migrate readlink to codegen-ported argument surface#1542
chaliy merged 3 commits intomainfrom
fix/issue-1532-readlink-codegen

Conversation

@chaliy
Copy link
Copy Markdown
Contributor

@chaliy chaliy commented May 5, 2026

Summary

readlink moves from handwritten char-by-char short-flag parsing to the
bashkit-coreutils-port codegen pipeline. Replaces the manual parser
(~50 LoC of match arg.as_str() plus a combined-flag loop) with
readlink_command().try_get_matches_from(...).

Codegen tool extension

bashkit-coreutils-port now also handles utils that declare option
keys as module-level const OPT_FOO: &str = ... or static OPT_FOO
rather than wrapping them in mod options { ... }. The two patterns
coexist in uutils — cat/tac/truncate/stat/shuf use the mod,
mktemp/realpath/readlink/od use bare consts. The tool now
emits whichever the source uses without requiring per-util branches
in bashkit.

Behaviour fixes accompanying the migration

  • -n / --no-newline now suppresses the trailing terminator on the
    last operand (previously silently accepted as a no-op).
  • -z / --zero switches the terminator to NUL (previously rejected
    as unknown).
  • Combined short flags like -fn now parse natively via clap; the
    manual for ch in s[1..].chars() loop is gone.
  • Unknown flags now exit with clap's exit code 2 instead of the
    custom code 1; documented as a clap-vs-GNU divergence in the spec
    test (### bash_diff), matching cat / tac / truncate / shuf.

Test plan

  • cargo test -p bashkit --test spec_tests bash_spec_tests
    includes new readlink.test.sh (6 cases).
  • generated_args_headers_match_pinned_uutils_revision — passes
    against the pinned rev (39364b6).
  • every_builtin_handles_bogus_flag_cleanly — passes.
  • cargo clippy -p bashkit -p bashkit-coreutils-port --all-targets --all-features -- -D warnings — green.
  • cargo fmt --check — green.

Scope

Part of #1532. Five existing builtins remain on the codegen-migration
list (tee, mktemp, realpath, stat, od) — separate PRs as
their parser surfaces are larger.


Generated by Claude Code

readlink moves from handwritten char-by-char short-flag parsing to
the bashkit-coreutils-port codegen pipeline. Replaces the manual
parser (~50 LoC of `match arg.as_str()` plus a combined-flag loop)
with `readlink_command().try_get_matches_from(...)`.

Codegen tool extension: bashkit-coreutils-port now also handles utils
that declare option keys as module-level `const OPT_FOO: &str = ...`
or `static OPT_FOO` rather than wrapping them in `mod options { }`.
The two patterns coexist in uutils (cat/tac/truncate/stat/shuf use
the mod, mktemp/realpath/readlink/od use bare consts); the tool now
emits whichever the source uses without requiring per-util branches
in the bashkit codebase.

Behaviour fixes accompanying the migration:

- `-n` / `--no-newline` now suppresses the trailing terminator on the
  last operand (previously silently accepted as a no-op).
- `-z` / `--zero` switches the terminator to NUL (previously rejected
  as unknown).
- Combined short flags like `-fn` now parse natively via clap; the
  manual `for ch in s[1..].chars()` loop is gone.
- Unknown flags now exit with clap's exit code 2 instead of the
  custom code 1; documented as a clap-vs-GNU divergence in the spec
  test (`### bash_diff`), matching cat / tac / truncate / shuf.

Tests:

- `crates/bashkit/tests/spec_cases/bash/readlink.test.sh` covers
  `-f`/`-m`/`-e`, combined short flags, long form, and unknown-flag
  rejection.
- `generated_args_headers_match_pinned_uutils_revision` continues
  to pass against the existing pin (39364b6).

Spec: implementation-status.md adds the new test row.

Part of #1532.
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 5, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bashkit ac8daf3 Commit Preview URL

Branch Preview URL
May 05 2026, 11:15 PM

chaliy added 2 commits May 5, 2026 22:58
`test_readlink_invalid_option` previously asserted exit 1 with stderr
containing "invalid option" — the GNU/handwritten convention. After
the codegen migration, clap exits 2 with "unexpected argument".
Additionally, -z is now a valid flag (zero-terminate output), so the
test must pick a flag that is genuinely not part of the ported
surface.

The clap-vs-GNU exit-code divergence is already documented as a
\`### bash_diff\` row in the spec test; mirror that in the unit
assertion. Same fix as the prior cat/tac/truncate/shuf migrations.

Part of #1532.
The previous fix used `{:?}` which trips
`no_debug_fmt_in_builtin_source`. Switch to `{}` — the asserted value
is a String for which Display reads cleanly.
@chaliy chaliy merged commit 06a388d into main May 5, 2026
34 checks passed
@chaliy chaliy deleted the fix/issue-1532-readlink-codegen branch May 5, 2026 23:55
@chaliy chaliy mentioned this pull request May 6, 2026
7 tasks
chaliy added a commit that referenced this pull request May 6, 2026
Minor release `0.4.1` → `0.5.0`. Two new builtins (`shuf`, `truncate`),
a coreutils-codegen pipeline that ports uutils' `uu_app()` clap
definitions for `cat`/`tac`/`truncate`/`shuf`/`readlink`, and `tool_def`
flag-syntax improvements.

## Highlights

- **Coreutils argument surface via codegen** — Ports uutils' `uu_app()`
clap definitions into bashkit so builtins share the real coreutils
argument shape; `cat`, `tac`, `truncate`, `shuf`, and `readlink` now
flow through this surface, with a coreutils differential testing harness
to catch parity drift. Pipeline reads a single pinned uutils revision so
generated builtins, the differential harness, and CI all agree on the
upstream source of truth (#1529, #1535, #1536, #1537, #1538, #1542).
- **Site updates** — Bashkit agent skill is now published on the site,
alongside rustdoc guides and content signal declarations for
discoverability.

## What's Changed

* refactor(builtins): migrate readlink to codegen-ported argument
surface (#1542)
* chore(site): publish bashkit agent skill (#1541)
* chore(site): declare content signals
* docs(site): publish rustdoc guides
* feat(builtins): add shuf via codegen with helper-fn inlining (#1538)
* chore(builtins): pin uutils revision as single source of truth (#1537)
* feat(builtins): add truncate via codegen-ported argument surface
(#1536)
* test(builtins): add coreutils differential testing harness (#1535)
* feat(builtins): port uutils argument surfaces via codegen (POC: cat,
tac) (#1529)
* feat(tool_def): accept --flag key=value... syntax for object/array
flags (#1528)
* fix(tool_def): coerce stringified JSON for array/object flag schemas
(#1527)

## Publish-readiness report

Per the updated `specs/release-process.md`:

- [x] `cargo fmt --check` clean
- [x] `cargo clippy --all-targets --all-features -- -D warnings` clean
- [x] `cargo build` clean
- [x] Versions synced across `Cargo.toml`,
`crates/bashkit-cli/Cargo.toml`, `crates/bashkit-js/package.json`,
`package-lock.json`, `Cargo.lock`
- [x] `cargo publish --dry-run -p bashkit --allow-dirty` (after CI's
monty-strip): **success**
- [x] `cargo publish --dry-run -p bashkit-cli`: blocked only on ordering
(`bashkit 0.5.0` not yet on crates.io) — resolves at real publish time
when `publish-bashkit` runs first per `publish.yml`'s `needs:` chain.
- [x] New `0.5.0` > latest published versions on crates.io / PyPI / npm
(`0.4.1`).

## Companion change

This branch also includes `chore(specs): document publish verification
and post-merge monitoring`, codifying the verify-before-tag and
watch-after-merge flow that this release follows.

On merge, `release.yml` will create the GitHub Release `v0.5.0` and
dispatch publish workflows for crates.io, PyPI, npm, and Homebrew.

**Full Changelog**:
v0.4.1...v0.5.0

---
_Generated by [Claude
Code](https://claude.ai/code/session_01SvuLdA8pMAmP4woG2HqxKw)_
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.

1 participant