astral-sh / uv

An extremely fast Python package installer and resolver, written in Rust.
https://astral.sh/
Apache License 2.0
11.74k stars 321 forks source link

Allow all arguments to be repeated in the CLI #3259

Open charliermarsh opened 2 weeks ago

charliermarsh commented 2 weeks ago

Summary

We need to decide if we actually want to change this, but I wanted to test it out anyway.

Closes https://github.com/astral-sh/uv/issues/3248.

Test Plan

Ran echo "flask" | cargo run pip compile - --output-file req.txt --output-file foo.txt, and verified that foo.txt was populated.

charliermarsh commented 2 weeks ago

I think I'm weakly in favor given that it seems like a popular behavior. Per https://github.com/clap-rs/clap/discussions/2627, it seems like you do this in ripgrep Andrew?

zanieb commented 2 weeks ago

I'm not yet convinced this is a better experience for the majority of users.

charliermarsh commented 2 weeks ago

I wasn't really sold, but it seems to be the default in most tools, and every CLI I've tested since researching this issue seems to operate this way (e.g., git, gh, and so on). Given that, I suspect that it's actually more surprising to users that it doesn't work than it is helpful in the rare cases that you accidentally repeat an argument.

BurntSushi commented 2 weeks ago

I am loosely in favor.

It's true that this is enabled in ripgrep, and has been for a long time. I don't use Clap any more in ripgrep, but in the move off of it, I think it's fair to say that I've doubled down on this behavior. I think the original motivation for allowing args to override itself is to be more flexible in the face of different workflows. For example, a user might have --max-columns 100 in their config file (or an alias). But maybe the user wants to change that to something else for a specific invocation. Without being able to override previous values, the user isn't allowed to do that.

Anyway, how much of this applies to uv? I'm not sure. I'm not sure uv benefits as much from being super flexible. It's hard to pick a non-contrived example, but, what's the behavior of --index-strategy unsafe-any-match --index-strategy first-match? Today it returns an error, but I feel like it has obvious intended semantics: the index strategy should be set to first-match. Now... whether that specific example will come up in the wild or not is unclear. It would probably mean having --index-strategy unsafe-any-match in an alias or something.

zanieb commented 2 weeks ago

My complaint is arguments where it's ambiguous if we accept multiple items, e.g.--output-file (as discussed in #3248) which could easily mean "write to all of the provided files"

BurntSushi commented 2 weeks ago

My complaint is arguments where it's ambiguous if we accept multiple items, e.g.--output-file (as discussed in #3248) which could easily mean "write to all of the provided files"

Yeah that is somewhat unfortunate. I think I'd still go with the flexibility though.

Another choice is that we could do both here: we could set this option globally (to allow most flags to override themselves) while treating ambiguous flags like --output-file specially. Although, how to do that using Clap isn't totally clear to me. (An obvious approach is to say that it can be used multiple times and error if it's used more than once, but then I imagine the auto-generated docs for that flag will be wrong.)