Skip to content

feat(builtins): add truncate via codegen-ported argument surface#1536

Merged
chaliy merged 1 commit intomainfrom
fix/issue-1532-truncate
May 5, 2026
Merged

feat(builtins): add truncate via codegen-ported argument surface#1536
chaliy merged 1 commit intomainfrom
fix/issue-1532-truncate

Conversation

@chaliy
Copy link
Copy Markdown
Contributor

@chaliy chaliy commented May 5, 2026

Summary

Implements the truncate coreutil with its argument surface generated
from uutils via the bashkit-coreutils-port codegen tool. truncate
was one of the genuinely-missing utils on bashkit's command dispatch
table ("command not found" before this change).

Codegen tool extension

bashkit-coreutils-port learns to rewrite the
uucore::clap_localization::configure_localized_command(cmd) wrapper
into bare cmd. uutils uses that wrapper to thread a Fluent-aware
Command adapter through every uu_app(); bashkit doesn't pull Fluent,
so the wrapper is replaced by its first argument. Without this rewrite
the generated truncate_args.rs would not compile (uucore is not a
bashkit dependency).

Builtin behaviour

  • -s SIZE with absolute, +/- (extend/reduce), </>
    (at-most/at-least), and //% (round-down/round-up to multiple)
    operators.
  • K/KB/M/MB/G/GB/... unit suffixes (1024- vs 1000-based).
  • -r REF sizes against a reference file via VFS stat.
  • -c / --no-create skips missing files.
  • -o / --io-blocks rejected with explicit "not yet implemented"
    error, matching the existing tac -b/-r/-s pattern.
  • Target size capped at 4 GiB so a <extend> op against a small file
    cannot demand a huge in-memory zero-fill.

Test plan

  • cargo test -p bashkit --test spec_tests bash_spec_tests
    includes new truncate.test.sh (13 cases).
  • cargo test -p bashkit --lib builtins::truncate — 8 unit tests
    cover parse_size and TargetSize::resolve.
  • cargo clippy -p bashkit --all-targets --all-features -- -D warnings — green.
  • cargo clippy -p bashkit-coreutils-port -- -D warnings — green.
  • every_builtin_handles_bogus_flag_cleanly — passes (truncate
    added to the list).
  • no_debug_fmt_in_builtin_source — passes.

Scope note (Part of #1532)

This PR delivers truncate end-to-end. The other utils listed in
#1532 either already exist as builtins (tee, mktemp, realpath,
readlink, stat, od) and need a separate codegen-migration PR, or
are still to be written (shuf). Each will get its own PR per the
"one issue = one PR" guideline applied per util.


Generated by Claude Code

Implements the `truncate` coreutil with argument surface generated from
uutils via the bashkit-coreutils-port codegen tool. truncate was one of
the genuinely-missing utils on bashkit's command dispatch ("command not
found" before this change).

Codegen tool extension:

- `bashkit-coreutils-port` learns to rewrite the
  `uucore::clap_localization::configure_localized_command(cmd)` wrapper
  into bare `cmd`. uutils uses the wrapper to thread a Fluent-aware
  Command adapter through every uu_app(); bashkit doesn't pull Fluent,
  so the wrapper is replaced by its first argument. Without this rewrite
  the generated `truncate_args.rs` would not compile (uucore is not a
  bashkit dependency).

Builtin behaviour (`crates/bashkit/src/builtins/truncate.rs`):

- `-s SIZE` with absolute, `+`/`-` (extend/reduce), `<`/`>` (at-most/
  at-least), and `/`/`%` (round-down/round-up to multiple) operators.
- K/KB/M/MB/G/GB/T/TB/P/PB/E/EB unit suffixes (1024-based vs 1000-based).
- `-r REF` to size against a reference file (read via VFS stat).
- `-c`/`--no-create` to skip missing files.
- `-o`/`--io-blocks` rejected with explicit "not yet implemented" error,
  matching the existing `tac -b/-r/-s` pattern.
- Resize bounded by a 4 GiB target cap so an `<extend>` op against a
  small file cannot demand a huge in-memory zero-fill.

Tests:

- `crates/bashkit/tests/spec_cases/bash/truncate.test.sh` covers happy
  paths, relative ops, `-r`, units, `--no-create`, and unknown-flag
  rejection (with `### bash_diff` for the clap-vs-GNU exit-code
  divergence).
- 8 unit tests in `truncate.rs` cover parse_size and TargetSize::resolve
  (absolute, extend/reduce, at-most/at-least, round-up/down, error
  cases).

Registration:

- `interpreter/mod.rs` dispatch table.
- `compgen.rs` allowlist.
- `every_builtin_handles_bogus_flag_cleanly` in `builtins/mod.rs`.
- `generated/mod.rs` (`pub mod truncate_args;`).

Spec: `implementation-status.md` lists the new test file with summary.

Part of #1532. The remaining utils in #1532 (`shuf`; codegen migration
for the existing `tee`/`mktemp`/`realpath`/`readlink`/`stat`/`od`
builtins) follow in separate PRs.
@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 3124645 Commit Preview URL

Branch Preview URL
May 05 2026, 02:17 PM

@chaliy chaliy merged commit 5fd2e76 into main May 5, 2026
34 checks passed
@chaliy chaliy deleted the fix/issue-1532-truncate branch May 5, 2026 14:25
chaliy added a commit that referenced this pull request May 5, 2026
Implements `shuf` end-to-end. The second genuinely-missing util from
#1532's list (truncate landed in #1536); drops "command not found" for
shuf invocations.

Codegen tool extension: bashkit-coreutils-port now scans uu_app() for
plain identifier references and inlines any matching free fn defined
at the source file's top level (parse_range was the motivating case).
The inlined fn runs through the same translate!() rewriter so its FTL
keys resolve. Generated preamble now always includes
clap::builder::ValueParser, std::ops::RangeInclusive, and
std::str::FromStr. syn dep gains the visit feature for the read-only
AST walk.

Builtin behaviour: -e ARG... shuffles positional args; -i LO-HI
produces the integer range; -n N caps output; -r samples with
replacement (requires -n in bashkit's safe mode); -z switches
separator to NUL; -o FILE writes to a VFS file. --random-seed and
--random-source rejected with "not yet implemented" matching the
existing tac -b/-r/-s pattern. Tiny xorshift64* RNG inlined to avoid
pulling rand into the always-on dep set.

Tests: 7-case spec test + 3 unit tests. The shuf -r without -n case
carries ### bash_diff so the strict bash parity step doesn't hang
against real bash (which loops forever). Registered in dispatch,
compgen, every_builtin_handles_bogus_flag_cleanly. spec
implementation-status.md updated.

Part of #1532.
@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