cli: list `bun pm diff` in `bun pm --help`, keep one copy of the pm help text, restore the indent of the `\`-continued messages
Problem
bun pm --helpdoes not listbun pm diff(added in #39229). Barebun pmdoes.- The
bun pmcommand list existed three times.bun pm --helpprinted the copy insrc/install/PackageManager.rs(CommandLineArguments::parseshort-circuits to it). Barebun pmand an unknown subcommand printed a second copy insrc/runtime/cli/package_manager_command.rs. #39229 updated only that one. #38333 had to patch both, and the openpm fetch(#29509) andpm sbom(#29512) PRs patch both. A third, six-entry copy sat intag_print_helpinsrc/runtime/cli/mod.rsand is unreachable (pmis not inUSES_GLOBAL_OPTIONS). misctools/generate-cli-completions.tsbuildscompletions/bun-cli.jsonfrombun pm --help, so regenerated shell completions would missdifftoo.- The second copy also printed wrong. It was a
"...\n\string literal, and a\line continuation strips the leading whitespace of the next line, so barebun pmprinted every row without the two-space indent (which the completions generator's^\s+bun pmmatch also needs). The same continuation strips the indent in three more messages written that way: thebun why/bun pm whyusage text (why_command.rs:278), and thebun create reactandbun create nextredirect messages (mod.rs:1847,mod.rs:1861). The pre-port text had the indent in all of them. tag_print_helphas one more unreachable hand-written arm of the same kind,Tag::InfoCommand.bun info --helpprints the text inCommandLineArguments::print_help(infois not inUSES_GLOBAL_OPTIONSeither).
Fix
- Moves the pm help text into the
Subcommand::Pmarm ofCommandLineArguments::print_help, where every other install-family command keeps its text, and adds thediffblock to it (its description padded to the column the other rows use). The one-methodPackageManagerCommandstruct inPackageManager.rsthat held the text is deleted. - Deletes the copy in
package_manager_command.rs. The bare and unknown-subcommand paths now callCommandLineArguments::print_help(Subcommand::Pm), which is whatbun pm --helpalready called. Thepmandinfoarms oftag_print_helpforward there too, like thepatch,outdated,dedupe, ... arms next to them. - Drops the trailing newline of the intro string, as the other intros in that function have. The merged text is the layout the pre-port implementation printed:
bun pm --helploses one stray blank line, barebun pmgets its indent back, nothing else in either output changes (diffs below). - Marks the first space of the indented lines in the
whyusage text and the twobun createmessages with\x20, the idiompm_version_command.rsalready uses for this, so they print the indent again. - Correct because all three pm entry points are the same command list, and the runtime crate already depends on the install crate, so separate copies can only drift. The
infoarm change is dead code only. The\x20change restores the text the Zig source had, byte for byte otherwise. - Intentionally left alone: the
bun whyhelp still has a usage text (barewhy) and a--helptext (tag_print_help) with different content, which is a separate consolidation.src/runtime/api/cron.rshas the same continuation pattern in generated plist/XML, where the indent does not matter.completions/bun-cli.jsonis not regenerated here (#38917 does that); whichever of the two lands second regenerates it. - Verified:
test/cli/install/bun-pm-diff.test.ts"bun pm help lists diff and its flags":bun pm --helpand barebun pmcontain the indentedbun pm diff [a] [b]row and its--stat,--name-only,-U,--jsonflags.test/cli/bun.test.ts"bun pm with no subcommand or an unknown one prints the same help as bun pm --help": the three entry points print byte-identical stdout with thediffanddefault-trustedrows and one blank line beforeCommands:. Exit codes 0 / 0 / 1 and the unknown-command error on stderr are unchanged.test/cli/install/bun-pm-why.test.ts"should show help when no package is specified" now holds the whole usage text as an inline snapshot, forbun whyandbun pm why. It no longer installs packages from the registry; the usage path only needs a package.json.test/cli/install/bun-create.test.ts"retired template names point at the replacement command": inline snapshots of the stderr ofbun create reactandbun create next. Inline, not a.snapfile, so the indent stays visible in the test (and file snapshots do not work insidedescribe.concurrent).- Each of these fails on main without the
src/changes (checked by stashing them and rebuilding) and passes with them. The four files pass in full with the debug build, as do the existingbun pm --helpassertions inbun.test.tsand thelicenseshelp test inbun-pm-licenses.test.ts. bun info --helpoutput is unchanged.rustfmt --checkon the touched Rust files. Thepre-port-identifiersandport-era-markerssource lints pass.
Background
CommandLineArguments::parse(subcommand)(src/install/PackageManager/CommandLineArguments.rs) parses the flags of the install-family commands (install,add,pm,why,info, ...). On--helpit callsCommandLineArguments::print_help(subcommand), amatchwith one arm of help text per subcommand, and exits. The install crate cannot depend on the CLI crate (the CLI is its consumer), which is why these texts live on the install side and the CLI forwards to them.PackageManagerCommand::exec(src/runtime/cli/package_manager_command.rs) runs after parsing and dispatches on the subcommand name. When nothing matches it prints the help and exits 0 (no subcommand) or prints"<name>" unknown commandand exits 1.tag_print_help(src/runtime/cli/mod.rs) is the help printer of the genericArguments::parse, whichcreate_context_dataonly runs for commands inUSES_GLOBAL_OPTIONS(src/options_types/command_tag.rs).pmandinfoare excluded, so their arms there never run. Several arms for other install-family commands are already one-line forwards toCommandLineArguments::print_help.- In a Rust string literal,
\at the end of a line removes the newline and all leading whitespace of the next line, so"a\n\followed byb"is"a\nb".\x20is a space written as an escape, so it survives, and\x20yields the two-space indent. Raw strings (r"...") keep the indent as written, which is what theprint_helparms use.
Before/after output of a debug build (pm)
bun pm --help, before vs after (the only changes):
6d5
<
22a22,28
> bun pm diff [a] [b] show what changed between two versions of a package (or vs a folder/tarball)
> ├ bun pm diff react installed version → latest
> ├ bun pm diff react@18.2.0 19.0.0
> ├ bun pm diff axios@1.6.0:lib 1.6.1 only files under lib/ (also :file.js, or paths after the two sides)
> ├ --stat, --name-only summarize instead of printing hunks
> ├ -U n lines of context (default 3)
> └ --json one JSON document (files, patch text, notes, totals)
Bare bun pm, before vs after, with the restored two-space indent stripped from the after output. What remains is the two rows whose description column was out of line:
22c22
< bun pm diff [a] [b] show what changed between two versions of a package (or vs a folder/tarball)
---
> bun pm diff [a] [b] show what changed between two versions of a package (or vs a folder/tarball)
34c34
< └ --filter <pattern> list only the matching workspaces' dependencies
---
> └ --filter <pattern> list only the matching workspaces' dependencies
After the change bun pm, bun pm --help and bun pm bogus produce byte-identical stdout (cmp), with exit codes 0, 0 and 1.
Earlier shape of this PR
The first push only added the diff block to the PackageManager.rs copy and made the CLI forward to it. A review pass pointed at the sibling sites (the why and bun create messages losing their indent the same way, and the dead info arm), which the second push covers. The third push moved the text into CommandLineArguments::print_help, which removed the struct and the comment that explained it.
no test proof · iteration 3 · Platform-specific test(s) that do not run on this machine. Deferring to CI, which covers all platforms: test/cli/bun.test.ts test/cli/install/bun-pm-diff.test.ts