0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 09:31:22 -05:00

feat: add --no-config flag (#14555)

This flag disables loading of configuration file, ie. it will not be
automatically discovered and loaded. Of course this flag conflicts
with "--config" flag and they cannot be used together.
This commit is contained in:
Bartek Iwańczuk 2022-05-13 17:40:50 +02:00 committed by GitHub
parent b543e84b39
commit 939a070c8c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 129 additions and 54 deletions

View file

@ -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)
}
}

View file

@ -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());
}
}

View file

@ -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"),

View file

@ -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

View file

@ -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 {

View file

@ -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![],