Skip to content

Any ability to specify 'raw' greedy args or pass-through? #179

@ppearson

Description

@ppearson

Is there any way to specify to argh that any:

#[argh(positional, greedy)]
/// command line args
args: Vec<String>,

arg options are expected to be totally "raw" (for lack of a better word), and to no longer try and interpret them, but just collect them?

I'm trying to use argh for an app which allows running other commands with optional args (similar to say gdb, lldb or valgrind) that need to be "passed through", and it looks like argh is attempting to parse any flags it doesn't understand and error, which isn't what I want...

Example here:

use argh::FromArgs;

#[derive(FromArgs)]
/// Main cmd args.
struct MainArgs {
    #[argh(subcommand)]
    command: SubCommandEnum,
}

#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand)]
enum SubCommandEnum {
    // Start the specified process with optional command line args
    Start(SubCommandStart),
    // Attach to a process based off the provided process ID
    Attach(SubCommandAttach),
}

#[derive(FromArgs, PartialEq, Debug)]
/// Run a process with command line args.
#[argh(subcommand, name = "run")]
struct SubCommandStart {
    #[argh(positional)]
    /// command line command to run
    command: String,

    #[argh(positional, greedy)]
    /// command line args
    args: Vec<String>,
}

#[derive(FromArgs, PartialEq, Debug)]
/// Attach to an existing pid.
#[argh(subcommand, name = "attach")]
struct SubCommandAttach {
    #[argh(positional)]
    /// PID of process to attach to
    pid: u32,
}

fn main() {
    let args: MainArgs = argh::from_env();
    if let SubCommandEnum::Attach(attach) = args.command {
        eprintln!("Attaching to process PID: {}...", attach.pid);
    } else if let SubCommandEnum::Start(start) = args.command {
        if start.args.is_empty() {
            eprintln!("Starting process '{}' without args", start.command);
        } else {
            eprintln!("Starting process: '{}' with args: {:?}", start.command, start.args);
        }
    }
}

If you run 'test' (as the compiled binary name) like so:

./test run uptime --version

I'd like '--version' to just be collected into the args Vec without any other processing, but instead it errors, with:
Unrecognized argument: --version

For the moment I can work around it to some degree by grouping the 'uptime' and '--version' into a single quoted string which then becomes the 'command' arg, and I can then detect that and separate it out, but it's a bit annoying having to work that way.

Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions