mirror of
https://github.com/denoland/deno.git
synced 2025-01-09 15:48:16 -05:00
feat: parse flags after script name (#2596)
This commit is contained in:
parent
cde81c6a53
commit
38cf346d5c
1 changed files with 104 additions and 5 deletions
109
cli/flags.rs
109
cli/flags.rs
|
@ -434,8 +434,11 @@ fn resolve_paths(paths: Vec<String>) -> Vec<String> {
|
||||||
|
|
||||||
/// Parse ArgMatches into internal DenoFlags structure.
|
/// Parse ArgMatches into internal DenoFlags structure.
|
||||||
/// This method should not make any side effects.
|
/// This method should not make any side effects.
|
||||||
pub fn parse_flags(matches: &ArgMatches) -> DenoFlags {
|
pub fn parse_flags(
|
||||||
let mut flags = DenoFlags::default();
|
matches: &ArgMatches,
|
||||||
|
maybe_flags: Option<DenoFlags>,
|
||||||
|
) -> DenoFlags {
|
||||||
|
let mut flags = maybe_flags.unwrap_or_default();
|
||||||
|
|
||||||
if matches.is_present("log-level") {
|
if matches.is_present("log-level") {
|
||||||
flags.log_level = match matches.value_of("log-level").unwrap() {
|
flags.log_level = match matches.value_of("log-level").unwrap() {
|
||||||
|
@ -552,6 +555,56 @@ fn parse_run_args(mut flags: DenoFlags, matches: &ArgMatches) -> DenoFlags {
|
||||||
flags
|
flags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse vector or arguments as DenoFlags.
|
||||||
|
///
|
||||||
|
/// This is very specialized utility that parses arguments passed after script URL.
|
||||||
|
///
|
||||||
|
/// Only dash (eg. `-r`) and double dash (eg. `--reload`) arguments are supported.
|
||||||
|
/// Arguments recognized as DenoFlags will be eaten.
|
||||||
|
/// Parsing stops after double dash `--` argument.
|
||||||
|
///
|
||||||
|
/// NOTE: this method ignores `-h/--help` and `-v/--version` flags.
|
||||||
|
fn parse_script_args(
|
||||||
|
args: Vec<String>,
|
||||||
|
mut flags: DenoFlags,
|
||||||
|
) -> (Vec<String>, DenoFlags) {
|
||||||
|
let mut argv = vec![];
|
||||||
|
let mut seen_double_dash = false;
|
||||||
|
|
||||||
|
// we have to iterate and parse argument one by one because clap returns error on any
|
||||||
|
// unrecognized argument
|
||||||
|
for arg in args.iter() {
|
||||||
|
if seen_double_dash {
|
||||||
|
argv.push(arg.to_string());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if arg == "--" {
|
||||||
|
seen_double_dash = true;
|
||||||
|
argv.push(arg.to_string());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !arg.starts_with('-') {
|
||||||
|
argv.push(arg.to_string());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cli_app = create_cli_app();
|
||||||
|
// `get_matches_from_safe` returns error for `-h/-v` flags
|
||||||
|
let matches =
|
||||||
|
cli_app.get_matches_from_safe(vec!["deno".to_string(), arg.to_string()]);
|
||||||
|
|
||||||
|
if matches.is_ok() {
|
||||||
|
flags = parse_flags(&matches.unwrap(), Some(flags));
|
||||||
|
} else {
|
||||||
|
argv.push(arg.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(argv, flags)
|
||||||
|
}
|
||||||
|
|
||||||
/// Used for `deno fmt <files>...` subcommand
|
/// Used for `deno fmt <files>...` subcommand
|
||||||
const PRETTIER_URL: &str = "https://deno.land/std@v0.7.0/prettier/main.ts";
|
const PRETTIER_URL: &str = "https://deno.land/std@v0.7.0/prettier/main.ts";
|
||||||
/// Used for `deno install...` subcommand
|
/// Used for `deno install...` subcommand
|
||||||
|
@ -603,7 +656,7 @@ pub fn flags_from_vec(
|
||||||
let cli_app = create_cli_app();
|
let cli_app = create_cli_app();
|
||||||
let matches = cli_app.get_matches_from(args);
|
let matches = cli_app.get_matches_from(args);
|
||||||
let mut argv: Vec<String> = vec!["deno".to_string()];
|
let mut argv: Vec<String> = vec!["deno".to_string()];
|
||||||
let mut flags = parse_flags(&matches.clone());
|
let mut flags = parse_flags(&matches.clone(), None);
|
||||||
|
|
||||||
let subcommand = match matches.subcommand() {
|
let subcommand = match matches.subcommand() {
|
||||||
("bundle", Some(bundle_match)) => {
|
("bundle", Some(bundle_match)) => {
|
||||||
|
@ -711,6 +764,9 @@ pub fn flags_from_vec(
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(String::from)
|
.map(String::from)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let (script_args, flags_) = parse_script_args(script_args, flags);
|
||||||
|
flags = flags_;
|
||||||
argv.extend(script_args);
|
argv.extend(script_args);
|
||||||
}
|
}
|
||||||
DenoSubcommand::Run
|
DenoSubcommand::Run
|
||||||
|
@ -746,6 +802,9 @@ pub fn flags_from_vec(
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(String::from)
|
.map(String::from)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let (script_args, flags_) = parse_script_args(script_args, flags);
|
||||||
|
flags = flags_;
|
||||||
argv.extend(script_args);
|
argv.extend(script_args);
|
||||||
}
|
}
|
||||||
DenoSubcommand::Run
|
DenoSubcommand::Run
|
||||||
|
@ -933,7 +992,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_flags_from_vec_10() {
|
fn test_flags_from_vec_10() {
|
||||||
// notice that flags passed after script name will not
|
// notice that flags passed after double dash will not
|
||||||
// be parsed to DenoFlags but instead forwarded to
|
// be parsed to DenoFlags but instead forwarded to
|
||||||
// script args as Deno.args
|
// script args as Deno.args
|
||||||
let (flags, subcommand, argv) = flags_from_vec(svec![
|
let (flags, subcommand, argv) = flags_from_vec(svec![
|
||||||
|
@ -941,6 +1000,7 @@ mod tests {
|
||||||
"run",
|
"run",
|
||||||
"--allow-write",
|
"--allow-write",
|
||||||
"script.ts",
|
"script.ts",
|
||||||
|
"--",
|
||||||
"-D",
|
"-D",
|
||||||
"--allow-net"
|
"--allow-net"
|
||||||
]);
|
]);
|
||||||
|
@ -952,7 +1012,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
assert_eq!(subcommand, DenoSubcommand::Run);
|
assert_eq!(subcommand, DenoSubcommand::Run);
|
||||||
assert_eq!(argv, svec!["deno", "script.ts", "-D", "--allow-net"]);
|
assert_eq!(argv, svec!["deno", "script.ts", "--", "-D", "--allow-net"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1436,4 +1496,43 @@ mod tests {
|
||||||
assert_eq!(subcommand, DenoSubcommand::Completions);
|
assert_eq!(subcommand, DenoSubcommand::Completions);
|
||||||
assert_eq!(argv, svec!["deno"])
|
assert_eq!(argv, svec!["deno"])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_flags_from_vec_33() {
|
||||||
|
let (flags, subcommand, argv) =
|
||||||
|
flags_from_vec(svec!["deno", "script.ts", "--allow-read", "--allow-net"]);
|
||||||
|
assert_eq!(
|
||||||
|
flags,
|
||||||
|
DenoFlags {
|
||||||
|
allow_net: true,
|
||||||
|
allow_read: true,
|
||||||
|
..DenoFlags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(subcommand, DenoSubcommand::Run);
|
||||||
|
assert_eq!(argv, svec!["deno", "script.ts"]);
|
||||||
|
|
||||||
|
let (flags, subcommand, argv) = flags_from_vec(svec![
|
||||||
|
"deno",
|
||||||
|
"--allow-read",
|
||||||
|
"run",
|
||||||
|
"script.ts",
|
||||||
|
"--allow-net",
|
||||||
|
"-r",
|
||||||
|
"--help",
|
||||||
|
"--foo",
|
||||||
|
"bar"
|
||||||
|
]);
|
||||||
|
assert_eq!(
|
||||||
|
flags,
|
||||||
|
DenoFlags {
|
||||||
|
allow_net: true,
|
||||||
|
allow_read: true,
|
||||||
|
reload: true,
|
||||||
|
..DenoFlags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(subcommand, DenoSubcommand::Run);
|
||||||
|
assert_eq!(argv, svec!["deno", "script.ts", "--help", "--foo", "bar"]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue