mirror of
https://github.com/denoland/deno.git
synced 2025-01-08 15:19:40 -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.
|
||||
/// This method should not make any side effects.
|
||||
pub fn parse_flags(matches: &ArgMatches) -> DenoFlags {
|
||||
let mut flags = DenoFlags::default();
|
||||
pub fn parse_flags(
|
||||
matches: &ArgMatches,
|
||||
maybe_flags: Option<DenoFlags>,
|
||||
) -> DenoFlags {
|
||||
let mut flags = maybe_flags.unwrap_or_default();
|
||||
|
||||
if matches.is_present("log-level") {
|
||||
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
|
||||
}
|
||||
|
||||
/// 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
|
||||
const PRETTIER_URL: &str = "https://deno.land/std@v0.7.0/prettier/main.ts";
|
||||
/// Used for `deno install...` subcommand
|
||||
|
@ -603,7 +656,7 @@ pub fn flags_from_vec(
|
|||
let cli_app = create_cli_app();
|
||||
let matches = cli_app.get_matches_from(args);
|
||||
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() {
|
||||
("bundle", Some(bundle_match)) => {
|
||||
|
@ -711,6 +764,9 @@ pub fn flags_from_vec(
|
|||
.unwrap()
|
||||
.map(String::from)
|
||||
.collect();
|
||||
|
||||
let (script_args, flags_) = parse_script_args(script_args, flags);
|
||||
flags = flags_;
|
||||
argv.extend(script_args);
|
||||
}
|
||||
DenoSubcommand::Run
|
||||
|
@ -746,6 +802,9 @@ pub fn flags_from_vec(
|
|||
.unwrap()
|
||||
.map(String::from)
|
||||
.collect();
|
||||
|
||||
let (script_args, flags_) = parse_script_args(script_args, flags);
|
||||
flags = flags_;
|
||||
argv.extend(script_args);
|
||||
}
|
||||
DenoSubcommand::Run
|
||||
|
@ -933,7 +992,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
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
|
||||
// script args as Deno.args
|
||||
let (flags, subcommand, argv) = flags_from_vec(svec![
|
||||
|
@ -941,6 +1000,7 @@ mod tests {
|
|||
"run",
|
||||
"--allow-write",
|
||||
"script.ts",
|
||||
"--",
|
||||
"-D",
|
||||
"--allow-net"
|
||||
]);
|
||||
|
@ -952,7 +1012,7 @@ mod tests {
|
|||
}
|
||||
);
|
||||
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]
|
||||
|
@ -1436,4 +1496,43 @@ mod tests {
|
|||
assert_eq!(subcommand, DenoSubcommand::Completions);
|
||||
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