-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Display the default value of --link-mode
in help
#6183
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
Conversation
Based on the CI failure
It seems the tool receipt will record the given options. Therefore, we should only set the value when it differs from the default. |
Also note that the default value varies by platform. We might need some help text about this to prevent confusion when reading the cli reference on the site. |
I'm not sure how we should handle the snapshot of cli references, as the output depends on the platform it's generated on. 😅 |
Lots of complications to consider here! I'm glad you just started with one option. We're going to be focused on 0.3.0 for a bit here — but after that I can try to help with the CLI reference guide and the snapshots. @charliermarsh is also going to need to take a look regarding the |
Or perhaps for this kind of platform-dependent default value, it would be better to display something similar to the CLI reference? e.g.
|
I think it's okay to show the default value per-platform in the CLI help menu, but yeah we'll want show both in the reference documentation — sounds complicated. Might be easier to always show them both for the sake of snapshots — but hopefully it's only a small amount of snapshots that actually include the help menu and we can just use filters... |
Based on the CI feedback, resetting only for |
I also noticed that we could implement the
Or we could add it (and other options whose doc already shows more descriptive information about the default value) to a group like |
#[arg(long, value_enum, env = "UV_LINK_MODE")] | ||
pub link_mode: Option<install_wheel_rs::linker::LinkMode>, | ||
#[arg(long, value_enum, env = "UV_LINK_MODE", default_value_t=LinkMode::default())] | ||
pub link_mode: LinkMode, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can't do this because we need to know if the value is provided on the CLI at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I think the best approach is to use the value_source
to determine where the value is being set. Then, if the source is not from the command line, we can simply reset it to None
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another simpler but trickier approach would be to leverage non-printable characters.
Consider the following:
#[derive(Clone, Debug)]
pub enum MaybeGiven<T> {
Default(T),
Given(T),
}
impl<T: Default> Default for MaybeGiven<T> {
fn default() -> Self {
Self::Default(T::default())
}
}
impl<T> MaybeGiven<T> {
pub fn into_given(self) -> Option<T> {
match self {
MaybeGiven::Default(_) => None,
MaybeGiven::Given(x) => Some(x),
}
}
pub fn into_inner(self) -> T {
match self {
MaybeGiven::Default(x) => x,
MaybeGiven::Given(x) => x,
}
}
}
impl<T> AsRef<T> for MaybeGiven<T> {
fn as_ref(&self) -> &T {
match self {
MaybeGiven::Default(x) => x,
MaybeGiven::Given(x) => x,
}
}
}
impl<T: Display> Display for MaybeGiven<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if matches!(self, MaybeGiven::Default(_)) {
f.write_str("\0")?;
self.as_ref().fmt(f)?;
f.write_str("\0")
} else {
self.as_ref().fmt(f)
}
}
}
impl<T: FromStr> FromStr for MaybeGiven<T> {
type Err = T::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let trimmed = s.trim_matches('\0');
if trimmed != s {
return Ok(Self::Default(T::from_str(trimmed)?));
}
Ok(Self::Given(T::from_str(s)?))
}
}
It checks if the string is surrounded by '\0' to determine whether it is from the default value or given by the user. This is a more hacky but simpler implementation without modifying the existing codebase too much, IMO.
If this is considered too hacky, I could implement it by checking the value_source
.
As more reference, I had to undo the default value in #6835 We don't have access to |
I guess the following should work: diff --git a/crates/uv/src/lib.rs b/crates/uv/src/lib.rs
index 080ed988..c5426578 100644
--- a/crates/uv/src/lib.rs
+++ b/crates/uv/src/lib.rs
@@ -1265,0 +1267,15 @@ async fn run_project(
+fn get_given_args(matches: &clap::ArgMatches) -> std::collections::HashSet<&clap::Id> {
+ let mut args = matches;
+ while let Some((_sub_cmd, sub_args)) = args.subcommand() {
+ args = sub_args;
+ }
+ args.ids()
+ .filter(|id| {
+ !matches!(
+ args.value_source(id.as_str()),
+ Some(clap::parser::ValueSource::DefaultValue)
+ )
+ })
+ .collect()
+}
+
@@ -1278,3 +1294,6 @@ where
- // `std::env::args` is not `Send` so we parse before passing to our runtime
- // https://github.com/rust-lang/rust/pull/48005
- let cli = match Cli::try_parse_from(args) {
+ let cmd = Cli::command();
+ let matches = cmd.get_matches_from(args);
+ let cli = match clap::FromArgMatches::from_arg_matches(&matches) {
+ // `std::env::args` is not `Send` so we parse before passing to our runtime
+ // https://github.com/rust-lang/rust/pull/48005
+ // let cli = match Cli::try_parse_from(args) { This should not alter the way uv currently parses arguments but provide us with the ability to retrieve given arguments from |
I think we may just need to keep this as documentation and not as a structured Clap default. As-is (in this PR) it's incorrect in the generated reference too, since it's dynamic. |
I'm going to close for now but let me know if you want to follow-up in some way. Thank you for your work here. |
Summary
Part of #6173 .
Test Plan
Inspect the help output for the following commands.
cargo run pip install --help
cargo run pip sync --help
cargo run pip venv --help