Repository navigation
feat(x): add --package/-p flag for specifying package separately from binary - #32855
Conversation
… binary Add `--package`/`-p` flag to `deno x` that allows specifying the package to install separately from the binary to execute, matching the `npx -p <package> <binary>` convention. This is useful when a package exposes multiple binaries (e.g. `typescript` has `tsc` and `tsserver`): deno x -p typescript tsc deno x -p typescript@5 tsc Previously, the only way to do this was: deno x typescript/tsc Closes #31667 Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
fibibot
left a comment
There was a problem hiding this comment.
Substance is right and minimally scoped — --package/-p is parsed into XCommandFlags::package, then combined as {package}/{command} and threaded through the existing resolution flow as effective_command. Walked the version-specifier path (-p typescript@5 tsc → npm:typescript@5/tsc): URL::parse fails on the @, falls through to the npm: prefix branch, NpmPackageReqReference::from_str handles the version+subpath split correctly. --package correctly conflicts_with("install-alias"). The error message at the binary-not-found path now reports effective_command (with the package context), which is more informative.
One test-coverage gap inline. CI 97 pass / 17 pending / 0 fail; @nathanwhit already approved. Holding COMMENT until the remaining shards settle, but I'd flip to APPROVE on green CI.
| "args": "x -y --package @denotest/bin cli-esm hello world", | ||
| "output": "run.out" | ||
| } | ||
| } |
There was a problem hiding this comment.
Coverage is happy-path only — both tests use the same plain @denotest/bin cli-esm shape. The version-specifier case is the canonical npx -p typescript@5 tsc pattern that motivates this flag, and exercises the URL::parse failure → npm: fallback path with a different surface than the bare-package case.
A third entry like:
"package_flag_with_version": {
"tempDir": true,
"args": "x -y -p @denotest/[email protected] cli-esm hello world",
"output": "run.out"
}would pin that path. Same run.out works (output doesn't depend on the version). Non-blocking, but since this is the case the PR description leads with, a regression test for it would be worth more than the long-vs-short-form duplication.
Summary
Closes #31667
Adds
--package/-pflag todeno xthat allows specifying the package to install separately from the binary to execute, matching thenpx -p <package> <binary>convention.This is useful when a package exposes multiple binaries (e.g.
typescripthastscandtsserver):Previously, the only way was
deno x typescript/tsc.The implementation combines
--packageand the binary name into{package}/{binary}before feeding it to the existing npm resolution flow, so all existing behavior is preserved.Test plan
-p(short) and--package(long) formsdeno xspec tests still pass🤖 Generated with Claude Code