mirror of
https://github.com/lexmount/moli.git
synced 2026-10-08 16:01:05 +00:00
fix(cli): stop inferring subcommands from flags
This commit is contained in:
+34
-104
@@ -2,64 +2,6 @@ use std::{ffi::OsString, num::NonZeroU32};
|
||||
|
||||
use clap::{Args, Parser, Subcommand, ValueEnum};
|
||||
|
||||
const FETCH_INFER_FLAGS: &[&str] = &[
|
||||
"--dump",
|
||||
"-d",
|
||||
"--header",
|
||||
"-H",
|
||||
"--trace-network",
|
||||
"--trace-matched-response-body",
|
||||
"--noscript",
|
||||
"-n",
|
||||
"--strip-mode",
|
||||
"--with-base",
|
||||
"--with-frames",
|
||||
"--wait-until",
|
||||
"-w",
|
||||
"--redirect-wait-ms",
|
||||
"--wait-selector",
|
||||
"-s",
|
||||
"--wait-script",
|
||||
"--wait-script-file",
|
||||
"--delay-ms",
|
||||
"--wait-response-url",
|
||||
"--wait-response-body",
|
||||
"--wait-response-json",
|
||||
"--document-start-script",
|
||||
"--document-start-script-file",
|
||||
"--image",
|
||||
"-i",
|
||||
"--font",
|
||||
"-f",
|
||||
"--audio",
|
||||
"-a",
|
||||
"--video",
|
||||
"-v",
|
||||
"--media",
|
||||
"-m",
|
||||
"--text-track",
|
||||
"-T",
|
||||
"--resource",
|
||||
"-r",
|
||||
"--disable-subframes",
|
||||
"--wait-ms",
|
||||
"--profile-dir",
|
||||
"-P",
|
||||
"--web-bot-auth-key-file",
|
||||
"--web-bot-auth-keyid",
|
||||
"--web-bot-auth-domain",
|
||||
"--web-bot-auth-profile",
|
||||
];
|
||||
const SERVE_INFER_FLAGS: &[&str] = &[
|
||||
"--host",
|
||||
"--port",
|
||||
"-p",
|
||||
"--timeout",
|
||||
"-t",
|
||||
"--layout",
|
||||
"-l",
|
||||
];
|
||||
const EXPLICIT_COMMANDS: &[&str] = &["fetch", "serve"];
|
||||
const DUMP_MODES: &[&str] = &[
|
||||
"json",
|
||||
"html",
|
||||
@@ -538,28 +480,10 @@ fn infer_command(next: Option<&OsString>) -> Option<&'static str> {
|
||||
};
|
||||
let next = next.to_string_lossy();
|
||||
|
||||
if EXPLICIT_COMMANDS.contains(&next.as_ref()) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if next.starts_with("http://") || next.starts_with("https://") {
|
||||
return Some("fetch");
|
||||
}
|
||||
|
||||
if FETCH_INFER_FLAGS
|
||||
.iter()
|
||||
.any(|flag| next == *flag || next.starts_with(&format!("{flag}=")))
|
||||
{
|
||||
return Some("fetch");
|
||||
}
|
||||
|
||||
if SERVE_INFER_FLAGS
|
||||
.iter()
|
||||
.any(|flag| next == *flag || next.starts_with(&format!("{flag}=")))
|
||||
{
|
||||
return Some("serve");
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
@@ -595,9 +519,14 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn delay_ms_infers_fetch_command() {
|
||||
let args =
|
||||
normalize_args_for_compat(["moli", "--delay-ms", "250", "https://example.test/"]);
|
||||
fn parses_delay_ms_with_explicit_fetch_command() {
|
||||
let args = normalize_args_for_compat([
|
||||
"moli",
|
||||
"fetch",
|
||||
"--delay-ms",
|
||||
"250",
|
||||
"https://example.test/",
|
||||
]);
|
||||
let cli = Cli::parse_from(args);
|
||||
|
||||
match cli.command {
|
||||
@@ -607,9 +536,13 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn redirect_wait_ms_infers_fetch_command() {
|
||||
let args =
|
||||
normalize_args_for_compat(["moli", "--redirect-wait-ms=1500", "https://example.test/"]);
|
||||
fn parses_redirect_wait_ms_with_explicit_fetch_command() {
|
||||
let args = normalize_args_for_compat([
|
||||
"moli",
|
||||
"fetch",
|
||||
"--redirect-wait-ms=1500",
|
||||
"https://example.test/",
|
||||
]);
|
||||
let cli = Cli::parse_from(args);
|
||||
|
||||
match cli.command {
|
||||
@@ -631,8 +564,8 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn port_equals_infers_serve_command() {
|
||||
let args = normalize_args_for_compat(["moli", "--port=0"]);
|
||||
fn parses_port_equals_with_explicit_serve_command() {
|
||||
let args = normalize_args_for_compat(["moli", "serve", "--port=0"]);
|
||||
let cli = Cli::parse_from(args);
|
||||
|
||||
match cli.command {
|
||||
@@ -771,8 +704,8 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn short_dump_infers_fetch_command_and_defaults_its_value() {
|
||||
let args = normalize_args_for_compat(["moli", "-d", "https://example.test/"]);
|
||||
fn short_dump_defaults_its_value_with_explicit_fetch_command() {
|
||||
let args = normalize_args_for_compat(["moli", "fetch", "-d", "https://example.test/"]);
|
||||
let cli = Cli::parse_from(args);
|
||||
|
||||
match cli.command {
|
||||
@@ -783,24 +716,21 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn short_port_infers_serve_command() {
|
||||
let args = normalize_args_for_compat(["moli", "-p", "0"]);
|
||||
let cli = Cli::parse_from(args);
|
||||
|
||||
match cli.command {
|
||||
Commands::Serve(args) => assert_eq!(args.port, 0),
|
||||
other => panic!("expected serve command, got {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn layout_infers_serve_command() {
|
||||
let args = normalize_args_for_compat(["moli", "--layout"]);
|
||||
let cli = Cli::parse_from(args);
|
||||
|
||||
match cli.command {
|
||||
Commands::Serve(args) => assert!(args.common.layout),
|
||||
other => panic!("expected serve command, got {other:?}"),
|
||||
fn flags_do_not_infer_subcommands() {
|
||||
for arguments in [
|
||||
["moli", "--dump", "html", "https://example.test/"].as_slice(),
|
||||
["moli", "-d", "html", "https://example.test/"].as_slice(),
|
||||
["moli", "--port=0"].as_slice(),
|
||||
["moli", "-p", "0"].as_slice(),
|
||||
["moli", "--layout"].as_slice(),
|
||||
] {
|
||||
let error = Cli::try_parse_from(normalize_args_for_compat(arguments.iter().copied()))
|
||||
.expect_err("a flag must not infer a subcommand");
|
||||
assert_eq!(
|
||||
error.kind(),
|
||||
clap::error::ErrorKind::UnknownArgument,
|
||||
"unexpected parse result for {arguments:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-10
@@ -196,7 +196,7 @@ fn rejects_removed_wpt_dump_mode() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_binary_dump_modes_with_inferred_fetch_command() {
|
||||
fn parses_binary_dump_modes_with_explicit_fetch_command() {
|
||||
for (value, expected) in [
|
||||
("screenshot", DumpFormat::Screenshot),
|
||||
("screenshot_full", DumpFormat::ScreenshotFull),
|
||||
@@ -204,6 +204,7 @@ fn parses_binary_dump_modes_with_inferred_fetch_command() {
|
||||
] {
|
||||
let cli = Cli::try_parse_from(normalize_args_for_compat([
|
||||
"moli",
|
||||
"fetch",
|
||||
"--dump",
|
||||
value,
|
||||
"https://example.com",
|
||||
@@ -402,9 +403,10 @@ fn infers_fetch_mode_from_bare_url() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infers_fetch_mode_from_fetch_only_flags_and_defaults_dump_to_html() {
|
||||
fn parses_bare_dump_with_explicit_fetch_command_and_defaults_to_html() {
|
||||
let cli = Cli::try_parse_from(normalize_args_for_compat([
|
||||
"moli",
|
||||
"fetch",
|
||||
"--dump",
|
||||
"https://example.com",
|
||||
]))
|
||||
@@ -438,9 +440,10 @@ fn infers_fetch_mode_from_fetch_only_flags_and_defaults_dump_to_html() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infers_fetch_mode_from_header_flag() {
|
||||
fn parses_header_flag_with_explicit_fetch_command() {
|
||||
let cli = Cli::try_parse_from(normalize_args_for_compat([
|
||||
"moli",
|
||||
"fetch",
|
||||
"-H",
|
||||
"X-Test: one",
|
||||
"https://example.com",
|
||||
@@ -478,7 +481,7 @@ fn infers_fetch_mode_from_header_flag() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_optional_resource_flag_infers_fetch_mode() {
|
||||
fn every_optional_resource_flag_parses_with_explicit_fetch_command() {
|
||||
let cases = [
|
||||
("--image", 0),
|
||||
("--font", 1),
|
||||
@@ -492,12 +495,13 @@ fn every_optional_resource_flag_infers_fetch_mode() {
|
||||
for (flag, enabled_index) in cases {
|
||||
let cli = Cli::try_parse_from(normalize_args_for_compat([
|
||||
"moli",
|
||||
"fetch",
|
||||
flag,
|
||||
"https://example.com",
|
||||
]))
|
||||
.unwrap_or_else(|error| panic!("{flag} should infer fetch mode: {error}"));
|
||||
.unwrap_or_else(|error| panic!("{flag} should parse for fetch: {error}"));
|
||||
let Commands::Fetch(args) = cli.command else {
|
||||
panic!("{flag} should infer the fetch command");
|
||||
panic!("{flag} should preserve the explicit fetch command");
|
||||
};
|
||||
let values = [
|
||||
args.common.image,
|
||||
@@ -521,9 +525,10 @@ fn every_optional_resource_flag_infers_fetch_mode() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infers_fetch_mode_from_disable_subframes_flag() {
|
||||
fn parses_disable_subframes_with_explicit_fetch_command() {
|
||||
let cli = Cli::try_parse_from(normalize_args_for_compat([
|
||||
"moli",
|
||||
"fetch",
|
||||
"--disable-subframes",
|
||||
"https://example.com",
|
||||
]))
|
||||
@@ -555,9 +560,10 @@ fn infers_serve_mode_when_called_without_args() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infers_serve_mode_from_legacy_serve_flags() {
|
||||
fn parses_serve_flags_with_explicit_command() {
|
||||
let cli = Cli::try_parse_from(normalize_args_for_compat([
|
||||
"moli",
|
||||
"serve",
|
||||
"--host",
|
||||
"0.0.0.0",
|
||||
"--port",
|
||||
@@ -792,7 +798,7 @@ fn fetch_strip_options_combine_cli_selections() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn does_not_infer_mode_from_top_level_common_flags() {
|
||||
fn does_not_infer_subcommand_from_flag() {
|
||||
let error =
|
||||
Cli::try_parse_from(normalize_args_for_compat(["moli", "--obey-robots"])).unwrap_err();
|
||||
|
||||
@@ -872,9 +878,10 @@ fn parses_fetch_domstable_wait_until() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infers_fetch_mode_from_wait_flags() {
|
||||
fn parses_wait_flags_with_explicit_fetch_command() {
|
||||
let cli = Cli::try_parse_from(normalize_args_for_compat([
|
||||
"moli",
|
||||
"fetch",
|
||||
"--wait-selector",
|
||||
"#ready",
|
||||
"https://example.com",
|
||||
|
||||
Reference in New Issue
Block a user