Fix multi-token command aliases; shorter README; 0.4.1#3
Merged
Conversation
`commands:` values have always been passed to `Command::new()` as a
single filename, which breaks any alias that contains whitespace, e.g.:
commands:
nukex: ${NUKE_HOME}/Nuke --nukex
usdview: python3.14 ~/USD/bin/usdview
The expected behavior (and what the walkthrough documents) is that the
first token is the program and the rest are prepended to the user's
args. This change tokenizes the resolved alias value with POSIX shell
rules via `shell-words`, then executes `Command::new(program)` with
`baked_args ++ user_args`.
Also surfaces a clear error if an alias resolves to an empty string
(previously produced an opaque ENOENT from `Command::new("")`).
Two regression tests added:
- run_multi_token_command_alias: unquoted tokens
- run_quoted_tokens_in_alias: quoted strings stay as a single argv entry
Cargo.toml: adds `shell-words = "1.1"` (35 kB, zero deps).
All 35 CLI integration tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Package::expand_env_value only expands a leading ~/, so an alias like `usdview: python3.14 ~/USD/bin/usdview` had its second token left literal and execve saw the string `~/USD/bin/usdview` as a relative path under $PWD. After shell-words splits the alias into tokens, pipe each through shellexpand::tilde (already a transitive dep of shellexpand). Only the leading ~ of each token is expanded, matching POSIX shell behavior. Regression: run_tilde_expands_in_each_token — creates a fake $HOME with a script at ~/bin/ping.sh, registers an alias `ping: /bin/bash ~/bin/ping.sh`, and checks the script runs and prints PONG. All 36 CLI tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bugfixes:
- Split multi-token command aliases before exec so values like
`nukex: ${NUKE}/Nuke --nukex` and `usdview: python3.14 ~/USD/bin/usdview`
run correctly instead of failing with ENOENT.
- Tilde expand every token of a split alias so `~/foo` after a space
resolves against $HOME rather than being looked up as a relative path.
Three regression tests added; full suite now 36 CLI integration tests.
Docs:
- README shortened from 681 to 404 lines.
- Every 0.4 command is covered in the Commands section.
- Multi-token alias behavior documented under Command aliases.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
commands:aliases before exec so values likenukex: \${NUKE}/Nuke --nukexandusdview: python3.14 ~/USD/bin/usdviewwork. Previously the whole string went toCommand::new()as a single filename.~/fooafter whitespace resolves against $HOME rather than being looked up as a relative path.Test plan
run_multi_token_command_alias,run_quoted_tokens_in_alias,run_tilde_expands_in_each_tokencargo test --release(36 passing)anvil run usd -- usdresolve myasset://assets/...now resolves apython3.14 ~/USD/bin/usdresolvealias and returns the expected path.cargo publish --dry-runclean🤖 Generated with Claude Code