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

Usage shows erroneous message #4451

Closed
2 tasks done
hectorruiz-it opened this issue Nov 4, 2022 · 2 comments
Closed
2 tasks done

Usage shows erroneous message #4451

hectorruiz-it opened this issue Nov 4, 2022 · 2 comments
Labels
C-bug Category: Updating dependencies

Comments

@hectorruiz-it
Copy link

hectorruiz-it commented Nov 4, 2022

Please complete the following tasks

Rust Version

rustc 1.63.0 (4b91a6ea7 2022-08-08)

Clap Version

"4.0.18"

Minimal reproducible code

use std::process::exit;

use clap::{Parser, Subcommand};
use clap::ArgAction::SetTrue;

mod list;
mod new;
mod setup;

#[derive(Parser)]
#[clap(about, version, author)]
struct Value {
    #[clap(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// List client platforms and repositories
    List {
        #[clap(long = "ssh", action = SetTrue, exclusive = true, required_unless_present_any = ["clients"])]
        /// List all platform ssh key alias
        ssh: bool,

        #[clap(long = "clients", action = SetTrue, exclusive = true, required_unless_present_any = ["ssh"])]
        /// List all clients)]
        clients: bool,
    }

}

fn main() {
    let value = Value::parse();
    match &value.command {
        Commands::List {
            ssh,
            clients,
        } => {
            if ssh.to_string() == "true" {
                match list::platforms() {
                    Ok(_) => exit(0),
                    Err(err) => {
                        eprintln!("ERROR: {}", err);
                        exit(1);
                    }
                };
            }
            if clients.to_string() == "true" {
                match list::clients() {
                    Ok(_) => exit(0),
                    Err(err) => {
                        eprintln!("ERROR: {}", err);
                        exit(1);
                    }
                }
            }
        }
    }
}

Steps to reproduce the bug with the above code

cargo run list

Actual Behaviour

error: The following required arguments were not provided:
  --ssh
  --clients

Usage: grabber list --ssh --clients

For more information try '--help'

Expected Behaviour

error: One of the following required arguments were not provided:
  --ssh
  --clients

Usage: grabber list --ssh  || grabber list --clients

For more information try '--help'

Additional Context

With the exclusive method, --ssh and --clients arguments can't be used together. The usage message doesn't representate this behaviour.
If you run the usage message works as expected printing that it can't be used with one or more of the other specified arguments:

error: The argument '--ssh' cannot be used with one or more of the other specified arguments

Usage: grabber list [OPTIONS]

For more information try '--help'

Debug Output

No response

@hectorruiz-it hectorruiz-it added the C-bug Category: Updating dependencies label Nov 4, 2022
@epage
Copy link
Member

epage commented Nov 5, 2022

imo this is a fairly complicated state for clap to infer that we are unlikely to support it.

However, another way of expressing this is by putting the two arguments into an ArgGroup and marking the ArgGroup as required.

Something like

use std::process::exit;

use clap::{Parser, Subcommand};
use clap::ArgAction::SetTrue;

mod list;
mod new;
mod setup;

#[derive(Parser)]
#[clap(about, version, author)]
struct Value {
    #[clap(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// List client platforms and repositories
    #[command(group = ArgGroup::new("action").required(true))]
    List {
        #[clap(group = "action")]
        /// List all platform ssh key alias
        ssh: bool,

        #[clap(group = "action")]
        /// List all clients)]
        clients: bool,
    }

}

fn main() {
    let value = Value::parse();
    match &value.command {
        Commands::List {
            ssh,
            clients,
        } => {
            if ssh.to_string() == "true" {
                match list::platforms() {
                    Ok(_) => exit(0),
                    Err(err) => {
                        eprintln!("ERROR: {}", err);
                        exit(1);
                    }
                };
            }
            if clients.to_string() == "true" {
                match list::clients() {
                    Ok(_) => exit(0),
                    Err(err) => {
                        eprintln!("ERROR: {}", err);
                        exit(1);
                    }
                }
            }
        }
    }
}

#2621 will make this even easier

Side notes

  • long can be inferred from the field name
  • bool fields automatically get ArgAction::SetTrue
  • exclusive should automatically disable required = true

@epage
Copy link
Member

epage commented Nov 5, 2022

Due to the complexity of supporting the inferring of this while we provide a more direct way for users to request this, I'm going to go ahead and close this. If there is something I missed, we can look into re-opening this.

@epage epage closed this as not planned Won't fix, can't repro, duplicate, stale Nov 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Updating dependencies
Projects
None yet
Development

No branches or pull requests

2 participants