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

stdin argument used more than once when argument is not in the final subcommand #9

Closed
RGBCube opened this issue Jul 5, 2024 · 6 comments

Comments

@RGBCube
Copy link

RGBCube commented Jul 5, 2024

MRE

use clap::{Parser, Subcommand};
use clap_stdin::FileOrStdin;

#[derive(Parser)]
struct Cli {
    #[clap(default_value = "-", global = true)]
    file: FileOrStdin,

    #[clap(subcommand)]
    command: Command,
}

#[derive(Subcommand)]
enum Command {
    Foo,
}

fn main() {
    let _ = Cli::parse();
}

Then run the resulting binary as <binary> foo:

image

If this isn't solveable, a feature that disables the "more than one stdin" check would be useful for cases where there is only a single file.

(note that <binary> foo <filehere> works, as expected)

@RGBCube
Copy link
Author

RGBCube commented Jul 5, 2024

A workaround for the default not working is to set it to "/dev/stdin" instead, as that's a "normal file"

thepacketgeek added a commit that referenced this issue Jul 6, 2024
This change relaxes the check for duplicate usage of `stdin` on arg
declarations (error at runtime if any two args use `MaybeStdin` or
`FileOrStdin`) and instead only check for duplicated `stdin` usage
when these args are accessed.

This allows usages of args that may be mutually exclusive (E.g. under
different subcommands) or use the `global=true` clap option (as reported
in #9)

If a tool happens to accept multiple args that can be Stdin, the CLI user
will only see an error if they actually try to use `stdin` for values
twice.
thepacketgeek added a commit that referenced this issue Jul 6, 2024
This change relaxes the check for duplicate usage of `stdin` on arg
declarations (error at runtime if any two args use `MaybeStdin` or
`FileOrStdin`) and instead only check for duplicated `stdin` usage
when these args are accessed.

This allows usages of args that may be mutually exclusive (E.g. under
different subcommands) or use the `global=true` clap option (as reported
in #9)

If a tool happens to accept multiple args that can be Stdin, the CLI user
will only see an error if they actually try to use `stdin` for values
twice.
@thepacketgeek
Copy link
Owner

@RGBCube thank you for reporting!! I believe you are running into this issue because of the default=true clap option for the arg. If I remove that, the example seems to work as expected.

The incompatibility ended up being from a side affect of checking for stdin usage when args are parsed instead of when stdin is actually read from. #10 fixes the issue by doing the duplicate stdin check on read, as I probably originally intended since it matches how I explain it in the doc.

Please feel free to test that PR (I confirmed it works with your example above) and let me know if that resolves the issue. If so, I'll merge and release a new version soon.

thepacketgeek added a commit that referenced this issue Jul 6, 2024
This change relaxes the check for duplicate usage of `stdin` on arg
declarations (error at runtime if any two args use `MaybeStdin` or
`FileOrStdin`) and instead only check for duplicated `stdin` usage
when these args are accessed.

This allows usages of args that may be mutually exclusive (E.g. under
different subcommands) or use the `global=true` clap option (as reported
in #9)

If a tool happens to accept multiple args that can be Stdin, the CLI user
will only see an error if they actually try to use `stdin` for values
twice.
@RGBCube
Copy link
Author

RGBCube commented Jul 6, 2024

default=true clap option for the arg. If I remove that, the example seems to work as expected.

(i suppose you mean global=true)

This PR indeed fixes it, but won't this regress program behavior?

If I'm understanding correctly, if I accepted two FileOrStdins and the user passed in - -, the cli error wouldn't be printed until after the first stdin is read & the second one attempted. This isn't great, since it could have been determined at the start.

What if instead of this, the argument was checked when the FileOrStdin was created, and the atomic was changed when it was? So when clap tries to construct the second FileOrStdin with once again -, the error message could be printed & the program could exit.

@RGBCube
Copy link
Author

RGBCube commented Jul 6, 2024

Ah, after looking at the changes, this was already the case before. Disregard my previous comment then :)

After thinking a little more about it, I can actually see the "lazy" behavior being useful for flags which are accessed based on behavior.

@thepacketgeek
Copy link
Owner

(i suppose you mean global=true)

whoops, yes, global=true :)

What if instead of this, the argument was checked when the FileOrStdin was created, and the atomic was changed when it was? So when clap tries to construct the second FileOrStdin with once again -, the error message could be printed & the program could exit.

This is what the previous code did, but that seems to be an issue with global=true as clap must be creating the arg instance twice for each level of commands?

thepacketgeek added a commit that referenced this issue Jul 6, 2024
This change relaxes the check for duplicate usage of `stdin` on arg
declarations (error at runtime if any two args use `MaybeStdin` or
`FileOrStdin`) and instead only check for duplicated `stdin` usage
when these args are accessed.

This allows usages of args that may be mutually exclusive (E.g. under
different subcommands) or use the `global=true` clap option (as reported
in #9)

If a tool happens to accept multiple args that can be Stdin, the CLI user
will only see an error if they actually try to use `stdin` for values
twice.
@thepacketgeek
Copy link
Owner

Fix released in v0.5.0

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

No branches or pull requests

2 participants