Skip to content

Commit

Permalink
Do not steal arguments from the script
Browse files Browse the repository at this point in the history
If run as e.g. "rust-script <script> <arg>", the <arg> should always
be passed to the script, and not be interpreted by rust-script itself.

This allows e.g. a script to handle "--help" and resolves #40.
  • Loading branch information
fornwall committed Nov 9, 2021
1 parent aceff54 commit 44dfcdd
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 11 deletions.
32 changes: 21 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,13 @@ impl BuildKind {

fn parse_args() -> Args {
use clap::{App, Arg, ArgGroup};
use std::iter::FromIterator;
let version = option_env!("CARGO_PKG_VERSION").unwrap_or("unknown");
let about = r#"Compiles and runs a Rust script."#;

let app = App::new(consts::PROGRAM_NAME)
.version(version)
.setting(clap::AppSettings::TrailingVarArg)
.setting(clap::AppSettings::AllowLeadingHyphen)
.about(about)
.arg(Arg::new("script")
.index(1)
Expand All @@ -117,12 +117,7 @@ fn parse_args() -> Args {
} else {
&["list-templates"]
})
)
.arg(Arg::new("script-args")
.index(2)
.about("Arguments for the script to execute.")
.multiple_values(true)
.min_values(0)
)
.arg(Arg::new("expr")
.about("Execute <script> as a literal expression and display the result.")
Expand Down Expand Up @@ -213,7 +208,7 @@ fn parse_args() -> Args {
.about("Generate the Cargo package, but don't compile or run it.")
.long("gen-pkg-only")
.requires("script")
.conflicts_with_all(&["script-args", "debug", "force", "test", "bench"])
.conflicts_with_all(&["debug", "force", "test", "bench"])
)
.arg(Arg::new("pkg_path")
.about("Specify where to place the generated Cargo package.")
Expand All @@ -225,12 +220,12 @@ fn parse_args() -> Args {
.arg(Arg::new("test")
.about("Compile and run tests.")
.long("test")
.conflicts_with_all(&["bench", "debug", "script-args", "force"])
.conflicts_with_all(&["bench", "debug", "force"])
)
.arg(Arg::new("bench")
.about("Compile and run benchmarks. Requires a nightly toolchain.")
.long("bench")
.conflicts_with_all(&["test", "debug", "script-args", "force"])
.conflicts_with_all(&["test", "debug", "force"])
)
.arg(Arg::new("template")
.about("Specify a template to use for expression scripts.")
Expand Down Expand Up @@ -281,9 +276,24 @@ fn parse_args() -> Args {
.unwrap_or_default()
}

let script_and_args: Option<Vec<&str>> = m.values_of("script").map(|o| o.collect());
let script;
let script_args: Vec<String>;
if let Some(script_and_args) = script_and_args {
script = script_and_args.get(0).map(|s| s.to_string());
script_args = if script_and_args.len() > 1 {
Vec::from_iter(script_and_args[1..].iter().map(|s| s.to_string()))
} else {
Vec::new()
};
} else {
script = None;
script_args = Vec::new();
}

Args {
script: m.value_of("script").map(Into::into),
script_args: owned_vec_string(m.values_of("script-args")),
script,
script_args,
features: m.value_of("features").map(Into::into),

expr: m.is_present("expr"),
Expand Down
4 changes: 4 additions & 0 deletions tests/data/same-flags.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
println!("--output--");
if let Some(arg) = std::env::args().skip(1).next() {
println!("Argument: {}", arg);
}
9 changes: 9 additions & 0 deletions tests/tests/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,12 @@ fn test_nightly_toolchain() {
.unwrap();
assert!(out.success());
}

#[test]
fn test_same_flags() {
let out = rust_script!("tests/data/same-flags.rs", "--help").unwrap();
scan!(out.stdout_output();
("Argument: --help") => ()
)
.unwrap()
}

0 comments on commit 44dfcdd

Please sign in to comment.