diff options
-rw-r--r-- | cli/config_file.rs | 32 | ||||
-rw-r--r-- | cli/flags.rs | 131 | ||||
-rw-r--r-- | cli/tests/integration/run_tests.rs | 6 | ||||
-rw-r--r-- | cli/tests/testdata/run/with_config/no_auto_discovery.out | 4 | ||||
-rw-r--r-- | cli/tools/installer.rs | 8 | ||||
-rw-r--r-- | cli/tools/standalone.rs | 2 |
6 files changed, 129 insertions, 54 deletions
diff --git a/cli/config_file.rs b/cli/config_file.rs index ba1d427a1..3644bb7c1 100644 --- a/cli/config_file.rs +++ b/cli/config_file.rs @@ -1,5 +1,7 @@ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +use crate::flags::ConfigFlag; +use crate::flags::Flags; use crate::fs_util::canonicalize_path; use crate::fs_util::specifier_parent; use crate::fs_util::specifier_to_file_path; @@ -161,21 +163,25 @@ pub const IGNORED_RUNTIME_COMPILER_OPTIONS: &[&str] = &[ /// Filenames that Deno will recognize when discovering config. const CONFIG_FILE_NAMES: [&str; 2] = ["deno.json", "deno.jsonc"]; -pub fn discover(flags: &crate::Flags) -> Result<Option<ConfigFile>, AnyError> { - if let Some(config_path) = flags.config_path.as_ref() { - Ok(Some(ConfigFile::read(config_path)?)) - } else if let Some(config_path_args) = flags.config_path_args() { - let mut checked = HashSet::new(); - for f in config_path_args { - if let Some(cf) = discover_from(&f, &mut checked)? { - return Ok(Some(cf)); +pub fn discover(flags: &Flags) -> Result<Option<ConfigFile>, AnyError> { + match &flags.config_flag { + ConfigFlag::Disabled => Ok(None), + ConfigFlag::Path(config_path) => Ok(Some(ConfigFile::read(config_path)?)), + ConfigFlag::Discover => { + if let Some(config_path_args) = flags.config_path_args() { + let mut checked = HashSet::new(); + for f in config_path_args { + if let Some(cf) = discover_from(&f, &mut checked)? { + return Ok(Some(cf)); + } + } + // From CWD walk up to root looking for deno.json or deno.jsonc + let cwd = std::env::current_dir()?; + discover_from(&cwd, &mut checked) + } else { + Ok(None) } } - // From CWD walk up to root looking for deno.json or deno.jsonc - let cwd = std::env::current_dir()?; - discover_from(&cwd, &mut checked) - } else { - Ok(None) } } diff --git a/cli/flags.rs b/cli/flags.rs index d2fdbfa49..c11d46c0c 100644 --- a/cli/flags.rs +++ b/cli/flags.rs @@ -270,6 +270,19 @@ impl Default for FutureTypeCheckMode { } } +#[derive(Clone, Debug, PartialEq)] +pub enum ConfigFlag { + Discover, + Path(String), + Disabled, +} + +impl Default for ConfigFlag { + fn default() -> Self { + Self::Discover + } +} + #[derive(Clone, Debug, PartialEq, Default)] pub struct Flags { /// Vector of CLI arguments - these are user script arguments, all Deno @@ -297,7 +310,7 @@ pub struct Flags { // once type checking is skipped by default pub future_type_check_mode: FutureTypeCheckMode, pub has_check_flag: bool, - pub config_path: Option<String>, + pub config_flag: ConfigFlag, pub coverage_dir: Option<String>, pub enable_testing_features: bool, pub ignore: Vec<PathBuf>, @@ -1067,7 +1080,7 @@ Ignore formatting a file by adding an ignore comment at the top of the file: // deno-fmt-ignore-file", ) - .arg(config_arg()) + .args(config_args()) .arg( Arg::new("check") .long("check") @@ -1355,7 +1368,7 @@ Ignore linting a file by adding an ignore comment at the top of the file: .conflicts_with("rules") .help("Exclude lint rules"), ) - .arg(config_arg()) + .args(config_args()) .arg( Arg::new("ignore") .long("ignore") @@ -1447,7 +1460,7 @@ Specifying the filename '-' to read the file from stdin. fn task_subcommand<'a>() -> Command<'a> { Command::new("task") .trailing_var_arg(true) - .arg(config_arg()) + .args(config_args()) // Ideally the task name and trailing arguments should be two separate clap // arguments, but there is a bug in clap that's preventing us from doing // this (https://github.com/clap-rs/clap/issues/1538). Once that's fixed, @@ -1691,7 +1704,7 @@ Remote modules and multiple modules may also be specified: ) .takes_value(false), ) - .arg(config_arg()) + .args(config_args()) .arg(import_map_arg()) .arg(lock_arg()) .arg(reload_arg()) @@ -1702,7 +1715,7 @@ fn compile_args(app: Command) -> Command { app .arg(import_map_arg()) .arg(no_remote_arg()) - .arg(config_arg()) + .args(config_args()) .arg(no_check_arg()) .arg(reload_arg()) .arg(lock_arg()) @@ -1714,7 +1727,7 @@ fn compile_args_without_no_check(app: Command) -> Command { app .arg(import_map_arg()) .arg(no_remote_arg()) - .arg(config_arg()) + .args(config_args()) .arg(reload_arg()) .arg(lock_arg()) .arg(lock_write_arg()) @@ -2097,15 +2110,22 @@ static CONFIG_HELP: Lazy<String> = Lazy::new(|| { ) }); -fn config_arg<'a>() -> Arg<'a> { - Arg::new("config") - .short('c') - .long("config") - .value_name("FILE") - .help("Specify the configuration file") - .long_help(CONFIG_HELP.as_str()) - .takes_value(true) - .value_hint(ValueHint::FilePath) +fn config_args<'a>() -> [Arg<'a>; 2] { + [ + Arg::new("config") + .short('c') + .long("config") + .value_name("FILE") + .help("Specify the configuration file") + .long_help(CONFIG_HELP.as_str()) + .takes_value(true) + .value_hint(ValueHint::FilePath) + .conflicts_with("no-config"), + Arg::new("no-config") + .long("no-config") + .help("Disable automatic loading of the configuration file.") + .conflicts_with("config"), + ] } fn no_remote_arg<'a>() -> Arg<'a> { @@ -2338,7 +2358,7 @@ fn eval_parse(flags: &mut Flags, matches: &clap::ArgMatches) { } fn fmt_parse(flags: &mut Flags, matches: &clap::ArgMatches) { - config_arg_parse(flags, matches); + config_args_parse(flags, matches); watch_arg_parse(flags, matches, false); let files = match matches.values_of("files") { @@ -2461,7 +2481,7 @@ fn lsp_parse(flags: &mut Flags, _matches: &clap::ArgMatches) { } fn lint_parse(flags: &mut Flags, matches: &clap::ArgMatches) { - config_arg_parse(flags, matches); + config_args_parse(flags, matches); watch_arg_parse(flags, matches, false); let files = match matches.values_of("files") { Some(f) => f.map(PathBuf::from).collect(), @@ -2540,7 +2560,7 @@ fn task_parse( matches: &clap::ArgMatches, raw_args: &[String], ) { - config_arg_parse(flags, matches); + config_args_parse(flags, matches); let mut task_name = "".to_string(); if let Some(mut index) = matches.index_of("task_name_and_args") { @@ -2550,9 +2570,13 @@ fn task_parse( while index < raw_args.len() { match raw_args[index].as_str() { "-c" | "--config" => { - flags.config_path = Some(raw_args[index + 1].to_string()); + flags.config_flag = ConfigFlag::Path(raw_args[index + 1].to_string()); index += 2; } + "--no-config" => { + flags.config_flag = ConfigFlag::Disabled; + index += 1; + } "-q" | "--quiet" => { flags.log_level = Some(Level::Error); index += 1; @@ -2695,7 +2719,7 @@ fn upgrade_parse(flags: &mut Flags, matches: &clap::ArgMatches) { fn vendor_parse(flags: &mut Flags, matches: &clap::ArgMatches) { ca_file_arg_parse(flags, matches); - config_arg_parse(flags, matches); + config_args_parse(flags, matches); import_map_arg_parse(flags, matches); lock_arg_parse(flags, matches); reload_arg_parse(flags, matches); @@ -2713,7 +2737,7 @@ fn vendor_parse(flags: &mut Flags, matches: &clap::ArgMatches) { fn compile_args_parse(flags: &mut Flags, matches: &clap::ArgMatches) { import_map_arg_parse(flags, matches); no_remote_arg_parse(flags, matches); - config_arg_parse(flags, matches); + config_args_parse(flags, matches); no_check_arg_parse(flags, matches); reload_arg_parse(flags, matches); lock_args_parse(flags, matches); @@ -2726,7 +2750,7 @@ fn compile_args_without_no_check_parse( ) { import_map_arg_parse(flags, matches); no_remote_arg_parse(flags, matches); - config_arg_parse(flags, matches); + config_args_parse(flags, matches); reload_arg_parse(flags, matches); lock_args_parse(flags, matches); ca_file_arg_parse(flags, matches); @@ -2960,8 +2984,14 @@ fn lock_arg_parse(flags: &mut Flags, matches: &clap::ArgMatches) { } } -fn config_arg_parse(flags: &mut Flags, matches: &ArgMatches) { - flags.config_path = matches.value_of("config").map(ToOwned::to_owned); +fn config_args_parse(flags: &mut Flags, matches: &ArgMatches) { + flags.config_flag = if matches.is_present("no-config") { + ConfigFlag::Disabled + } else if let Some(config) = matches.value_of("config") { + ConfigFlag::Path(config.to_string()) + } else { + ConfigFlag::Discover + }; } fn no_remote_arg_parse(flags: &mut Flags, matches: &clap::ArgMatches) { @@ -3444,7 +3474,7 @@ mod tests { single_quote: None, prose_wrap: None, }), - config_path: Some("deno.jsonc".to_string()), + config_flag: ConfigFlag::Path("deno.jsonc".to_string()), ..Flags::default() } ); @@ -3471,7 +3501,7 @@ mod tests { single_quote: None, prose_wrap: None, }), - config_path: Some("deno.jsonc".to_string()), + config_flag: ConfigFlag::Path("deno.jsonc".to_string()), watch: Some(vec![]), ..Flags::default() } @@ -3684,7 +3714,7 @@ mod tests { json: true, ignore: vec![], }), - config_path: Some("Deno.jsonc".to_string()), + config_flag: ConfigFlag::Path("Deno.jsonc".to_string()), ..Flags::default() } ); @@ -3817,7 +3847,7 @@ mod tests { subcommand: DenoSubcommand::Run(RunFlags { script: "script.ts".to_string(), }), - config_path: Some("tsconfig.json".to_owned()), + config_flag: ConfigFlag::Path("tsconfig.json".to_owned()), ..Flags::default() } ); @@ -3907,7 +3937,7 @@ mod tests { }), import_map_path: Some("import_map.json".to_string()), no_remote: true, - config_path: Some("tsconfig.json".to_string()), + config_flag: ConfigFlag::Path("tsconfig.json".to_owned()), type_check_mode: TypeCheckMode::None, reload: true, lock: Some(PathBuf::from("lock.json")), @@ -3998,7 +4028,7 @@ mod tests { }), import_map_path: Some("import_map.json".to_string()), no_remote: true, - config_path: Some("tsconfig.json".to_string()), + config_flag: ConfigFlag::Path("tsconfig.json".to_owned()), type_check_mode: TypeCheckMode::None, reload: true, lock: Some(PathBuf::from("lock.json")), @@ -4228,7 +4258,7 @@ mod tests { }), allow_write: Some(vec![]), no_remote: true, - config_path: Some("tsconfig.json".to_owned()), + config_flag: ConfigFlag::Path("tsconfig.json".to_owned()), ..Flags::default() } ); @@ -4521,7 +4551,7 @@ mod tests { }), import_map_path: Some("import_map.json".to_string()), no_remote: true, - config_path: Some("tsconfig.json".to_string()), + config_flag: ConfigFlag::Path("tsconfig.json".to_owned()), type_check_mode: TypeCheckMode::None, reload: true, lock: Some(PathBuf::from("lock.json")), @@ -5366,7 +5396,7 @@ mod tests { }), import_map_path: Some("import_map.json".to_string()), no_remote: true, - config_path: Some("tsconfig.json".to_string()), + config_flag: ConfigFlag::Path("tsconfig.json".to_owned()), type_check_mode: TypeCheckMode::None, reload: true, lock: Some(PathBuf::from("lock.json")), @@ -5538,7 +5568,7 @@ mod tests { force: true, output_path: Some(PathBuf::from("out_dir")), }), - config_path: Some("deno.json".to_string()), + config_flag: ConfigFlag::Path("deno.json".to_owned()), import_map_path: Some("import_map.json".to_string()), lock: Some(PathBuf::from("lock.json")), reload: true, @@ -5592,7 +5622,7 @@ mod tests { task: "build".to_string(), }), argv: svec!["--", "hello", "world"], - config_path: Some("deno.json".to_string()), + config_flag: ConfigFlag::Path("deno.json".to_owned()), ..Flags::default() } ); @@ -5667,7 +5697,7 @@ mod tests { subcommand: DenoSubcommand::Task(TaskFlags { task: "".to_string(), }), - config_path: Some("deno.jsonc".to_string()), + config_flag: ConfigFlag::Path("deno.jsonc".to_string()), ..Flags::default() } ); @@ -5682,7 +5712,7 @@ mod tests { subcommand: DenoSubcommand::Task(TaskFlags { task: "".to_string(), }), - config_path: Some("deno.jsonc".to_string()), + config_flag: ConfigFlag::Path("deno.jsonc".to_string()), ..Flags::default() } ); @@ -5773,4 +5803,29 @@ mod tests { ]); assert!(r.is_err()); } + + #[test] + fn no_config() { + let r = flags_from_vec(svec!["deno", "run", "--no-config", "script.ts",]); + assert_eq!( + r.unwrap(), + Flags { + subcommand: DenoSubcommand::Run(RunFlags { + script: "script.ts".to_string(), + }), + config_flag: ConfigFlag::Disabled, + ..Flags::default() + } + ); + + let r = flags_from_vec(svec![ + "deno", + "run", + "--config", + "deno.json", + "--no-config", + "script.ts", + ]); + assert!(r.is_err()); + } } diff --git a/cli/tests/integration/run_tests.rs b/cli/tests/integration/run_tests.rs index 1cf22a51a..dc158fd7a 100644 --- a/cli/tests/integration/run_tests.rs +++ b/cli/tests/integration/run_tests.rs @@ -2560,6 +2560,12 @@ itest!(config_auto_discovered_for_local_script { output_str: Some("ok\n"), }); +itest!(no_config_auto_discovery_for_local_script { + args: "run --quiet --no-config run/with_config/frontend_work.ts", + output: "run/with_config/no_auto_discovery.out", + exit_code: 1, +}); + itest!(config_not_auto_discovered_for_remote_script { args: "run --quiet http://127.0.0.1:4545/run/with_config/server_side_work.ts", output_str: Some("ok\n"), diff --git a/cli/tests/testdata/run/with_config/no_auto_discovery.out b/cli/tests/testdata/run/with_config/no_auto_discovery.out new file mode 100644 index 000000000..59339ebe5 --- /dev/null +++ b/cli/tests/testdata/run/with_config/no_auto_discovery.out @@ -0,0 +1,4 @@ +error: TS2584 [ERROR]: Cannot find name 'document'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'. + console.log(document); + ~~~~~~~~ + at [WILDCARD]run/with_config/frontend_work.ts:2:15 diff --git a/cli/tools/installer.rs b/cli/tools/installer.rs index 8ebbf8f53..2dc86f0dc 100644 --- a/cli/tools/installer.rs +++ b/cli/tools/installer.rs @@ -1,5 +1,6 @@ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +use crate::flags::ConfigFlag; use crate::flags::Flags; use crate::flags::InstallFlags; use crate::flags::TypeCheckMode; @@ -361,7 +362,7 @@ fn resolve_shim_data( executable_args.push(import_map_url.to_string()); } - if let Some(config_path) = &flags.config_path { + if let ConfigFlag::Path(config_path) = &flags.config_flag { let mut copy_path = file_path.clone(); copy_path.set_extension("tsconfig.json"); executable_args.push("--config".to_string()); @@ -404,6 +405,7 @@ fn is_in_path(dir: &Path) -> bool { mod tests { use super::*; + use crate::flags::ConfigFlag; use std::process::Command; use test_util::testdata_path; use test_util::TempDir; @@ -771,7 +773,9 @@ mod tests { let result = install( Flags { - config_path: Some(config_file_path.to_string_lossy().to_string()), + config_flag: ConfigFlag::Path( + config_file_path.to_string_lossy().to_string(), + ), ..Flags::default() }, InstallFlags { diff --git a/cli/tools/standalone.rs b/cli/tools/standalone.rs index 9f24b5f08..d682ed88c 100644 --- a/cli/tools/standalone.rs +++ b/cli/tools/standalone.rs @@ -264,7 +264,7 @@ pub fn compile_to_runtime_flags( cache_blocklist: vec![], cache_path: None, cached_only: false, - config_path: None, + config_flag: Default::default(), coverage_dir: flags.coverage_dir.clone(), enable_testing_features: false, ignore: vec![], |