Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve handling of command arguments in uv run and uv tool run #4404

Merged
merged 1 commit into from
Jun 19, 2024

Conversation

zanieb
Copy link
Member

@zanieb zanieb commented Jun 18, 2024

Closes #4390

We no longer require -- to disambiguate child command options that overlap with uv options.

Comment on lines +1461 to +1465
#[derive(Parser, Debug, Clone)]
pub(crate) enum ExternalCommand {
#[command(external_subcommand)]
Cmd(Vec<OsString>),
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lifted from Rye.

Comment on lines 1477 to 1484
impl ExternalCommand {
pub(crate) fn split(&self) -> (Option<&OsString>, &[OsString]) {
match self.deref().as_slice() {
[] => (None, &[]),
[cmd, args @ ..] => (Some(cmd), args),
}
}
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes life easier in the implementations, we special case the first argument.

mod common;

#[test]
fn tool_run_args() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our first tool run tests!

@@ -44,7 +44,7 @@ pub const INSTA_FILTERS: &[(&str, &str)] = &[
(r"uv.exe", "uv"),
// uv version display
(
r"uv \d+\.\d+\.\d+( \(.*\))?",
r"uv(-.*)? \d+\.\d+\.\d+( \(.*\))?",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We output uv-run ... for uv run --version. Kind of annoying tbh but it's Clap's behavior I think so just going to filter it.

Comment on lines -28 to +29
target: Option<String>,
mut args: Vec<OsString>,
command: ExternalCommand,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We split this into target and args late so we can avoid borrowing, cloning, or otherwise painfully popping the first item from the vector.

Copy link
Member

@BurntSushi BurntSushi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you say at a high level how this works? Does this introduce any ambiguities?


impl ExternalCommand {
pub(crate) fn split(&self) -> (Option<&OsString>, &[OsString]) {
match self.deref().as_slice() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is odd to need to use .deref() explicitly. Does just self.as_slice() work?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably just me being dumb, thanks!

@zanieb
Copy link
Member Author

zanieb commented Jun 19, 2024

Can you say at a high level how this works? Does this introduce any ambiguities?

Honestly I'm not sure about the details, just that this is the standard flag for this purpose. My understanding is as follows though:

  • Once we start parsing the external command we'll treat all the flags we see as options for that command
  • If we add a uv run subcommand e.g. uv run list then list will be treated as a uv subcommand and we won't parse anything as an external flag
  • Now, the only reason to use -- is to disambiguate between an external subcommand and a uv subcommand but we don't have any right now

Base automatically changed from zb/filter-version to main June 19, 2024 14:46
zanieb added a commit that referenced this pull request Jun 19, 2024
No reason for these to be special-cased and I need them for #4404 tests
@zanieb zanieb enabled auto-merge (squash) June 19, 2024 14:50
@zanieb zanieb merged commit 39da391 into main Jun 19, 2024
47 checks passed
@zanieb zanieb deleted the zb/run-command branch June 19, 2024 14:55
Comment on lines +1478 to +1484
pub(crate) fn split(&self) -> (Option<&OsString>, &[OsString]) {
match self.as_slice() {
[] => (None, &[]),
[cmd, args @ ..] => (Some(cmd), args),
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's implemented in std as split_first

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah thanks!

.collect::<Vec<_>>();
let (target, args) = command.split();
let Some(target) = target else {
return Err(anyhow::anyhow!("No tool command provided"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be bail!

Comment on lines +49 to +51
let Some(target) = target.to_str() else {
return Err(anyhow::anyhow!("Tool command could not be parsed as UTF-8 string. Use `--from` to specify the package name."));
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be .context("..."), anyhow conveniently implements it on option too

Comment on lines +438 to +450
.arg("--cache-dir")
.arg(self.cache_dir.path())
.env("VIRTUAL_ENV", self.venv.as_os_str())
.env("UV_NO_WRAP", "1")
.env("UV_TOOLCHAIN_DIR", "")
.env("UV_TEST_PYTHON_PATH", &self.python_path())
.current_dir(&self.temp_dir);

if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
// default windows stack of 1MB
command.env("UV_STACK_SIZE", (4 * 1024 * 1024).to_string());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably need to abstract those away soon, we're having them in a lot of subcommand test instantiators now

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
preview Experimental behavior
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants