diff options
author | Geert-Jan Zwiers <geertjanzwiers@protonmail.com> | 2023-01-07 21:22:09 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-07 15:22:09 -0500 |
commit | 84ef26ac9b5f0e1199d77837cd97cb203baa8729 (patch) | |
tree | eb8f3422d397724d004dba0e9667b3f6c2b49a57 /cli/tools | |
parent | fac64478157ee563b185edb5734688e4523df3a1 (diff) |
refactor(cli/tools): move flag and config logic to CliOptions (#17008)
Co-authored-by: David Sherret <dsherret@gmail.com>
Diffstat (limited to 'cli/tools')
-rw-r--r-- | cli/tools/bench.rs | 116 | ||||
-rw-r--r-- | cli/tools/fmt.rs | 176 | ||||
-rw-r--r-- | cli/tools/lint.rs | 239 | ||||
-rw-r--r-- | cli/tools/test.rs | 120 | ||||
-rw-r--r-- | cli/tools/vendor/mod.rs | 5 |
5 files changed, 181 insertions, 475 deletions
diff --git a/cli/tools/bench.rs b/cli/tools/bench.rs index 2d54b260d..ed788fa7f 100644 --- a/cli/tools/bench.rs +++ b/cli/tools/bench.rs @@ -1,8 +1,7 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -use crate::args::BenchConfig; -use crate::args::BenchFlags; -use crate::args::Flags; +use crate::args::BenchOptions; +use crate::args::CliOptions; use crate::args::TypeCheckMode; use crate::colors; use crate::graph_util::contains_specifier; @@ -15,7 +14,6 @@ use crate::util::file_watcher; use crate::util::file_watcher::ResolutionResult; use crate::util::fs::collect_specifiers; use crate::util::path::is_supported_ext; -use crate::util::path::specifier_to_file_path; use crate::worker::create_main_worker_for_test_or_bench; use deno_core::error::generic_error; @@ -37,6 +35,7 @@ use serde::Serialize; use std::collections::HashSet; use std::path::Path; use std::path::PathBuf; +use std::sync::Arc; use tokio::sync::mpsc::unbounded_channel; use tokio::sync::mpsc::UnboundedSender; @@ -487,24 +486,18 @@ fn is_supported_bench_path(path: &Path) -> bool { } pub async fn run_benchmarks( - flags: Flags, - bench_flags: BenchFlags, + cli_options: CliOptions, + bench_options: BenchOptions, ) -> Result<(), AnyError> { - let ps = ProcState::build(flags).await?; + let ps = ProcState::from_options(Arc::new(cli_options)).await?; // Various bench files should not share the same permissions in terms of // `PermissionsContainer` - otherwise granting/revoking permissions in one // file would have impact on other files, which is undesirable. let permissions = Permissions::from_options(&ps.options.permissions_options())?; - let selection = - collect_include_ignore(&bench_flags, ps.options.to_bench_config()?); - - let specifiers = collect_specifiers( - selection.include, - &selection.ignore, - is_supported_bench_path, - )?; + let specifiers = + collect_specifiers(&bench_options.files, is_supported_bench_path)?; if specifiers.is_empty() { return Err(generic_error("No bench modules found")); @@ -517,7 +510,7 @@ pub async fn run_benchmarks( permissions, specifiers, BenchSpecifierOptions { - filter: bench_flags.filter, + filter: bench_options.filter, }, ) .await?; @@ -527,21 +520,22 @@ pub async fn run_benchmarks( // TODO(bartlomieju): heavy duplication of code with `cli/tools/test.rs` pub async fn run_benchmarks_with_watch( - flags: Flags, - bench_flags: BenchFlags, + cli_options: CliOptions, + bench_options: BenchOptions, ) -> Result<(), AnyError> { - let ps = ProcState::build(flags).await?; + let ps = ProcState::from_options(Arc::new(cli_options)).await?; // Various bench files should not share the same permissions in terms of // `PermissionsContainer` - otherwise granting/revoking permissions in one // file would have impact on other files, which is undesirable. let permissions = Permissions::from_options(&ps.options.permissions_options())?; - let selection = - collect_include_ignore(&bench_flags, ps.options.to_bench_config()?); - - let paths_to_watch: Vec<_> = - selection.include.iter().map(PathBuf::from).collect(); + let paths_to_watch: Vec<_> = bench_options + .files + .include + .iter() + .map(PathBuf::from) + .collect(); let no_check = ps.options.type_check_mode() == TypeCheckMode::None; let resolver = |changed: Option<Vec<PathBuf>>| { @@ -549,13 +543,11 @@ pub async fn run_benchmarks_with_watch( let paths_to_watch_clone = paths_to_watch.clone(); let files_changed = changed.is_some(); - let include = selection.include.clone(); - let ignore = selection.ignore.clone(); + let files = bench_options.files.clone(); let ps = ps.clone(); async move { - let bench_modules = - collect_specifiers(include.clone(), &ignore, is_supported_bench_path)?; + let bench_modules = collect_specifiers(&files, is_supported_bench_path)?; let mut paths_to_watch = paths_to_watch_clone; let mut modules_to_reload = if files_changed { @@ -615,7 +607,6 @@ pub async fn run_benchmarks_with_watch( } } } - // This bench module and all it's dependencies let mut modules = HashSet::new(); modules.insert(&specifier); @@ -664,27 +655,27 @@ pub async fn run_benchmarks_with_watch( }; let operation = |modules_to_reload: Vec<(ModuleSpecifier, ModuleKind)>| { - let filter = bench_flags.filter.clone(); - let include = selection.include.clone(); - let ignore = selection.ignore.clone(); let permissions = permissions.clone(); let ps = ps.clone(); + let filter = bench_options.filter.clone(); + let files = bench_options.files.clone(); async move { - let specifiers = - collect_specifiers(include.clone(), &ignore, is_supported_bench_path)? - .iter() - .filter(|specifier| contains_specifier(&modules_to_reload, specifier)) - .cloned() - .collect::<Vec<ModuleSpecifier>>(); + let specifiers = collect_specifiers(&files, is_supported_bench_path)? + .iter() + .filter(|specifier| contains_specifier(&modules_to_reload, specifier)) + .cloned() + .collect::<Vec<ModuleSpecifier>>(); check_specifiers(&ps, permissions.clone(), specifiers.clone()).await?; - let specifier_options = BenchSpecifierOptions { - filter: filter.clone(), - }; - bench_specifiers(ps, permissions.clone(), specifiers, specifier_options) - .await?; + bench_specifiers( + ps, + permissions.clone(), + specifiers, + BenchSpecifierOptions { filter }, + ) + .await?; Ok(()) } @@ -702,42 +693,3 @@ pub async fn run_benchmarks_with_watch( Ok(()) } - -struct IncludeIgnoreCollection { - include: Vec<String>, - ignore: Vec<PathBuf>, -} - -fn collect_include_ignore( - bench_flags: &BenchFlags, - maybe_bench_config: Option<BenchConfig>, -) -> IncludeIgnoreCollection { - let mut include = bench_flags.include.clone().unwrap_or_default(); - let mut ignore = bench_flags.ignore.clone(); - - if let Some(bench_config) = maybe_bench_config { - if include.is_empty() { - include = bench_config - .files - .include - .iter() - .map(|s| s.to_string()) - .collect::<Vec<_>>(); - } - - if ignore.is_empty() { - ignore = bench_config - .files - .exclude - .iter() - .filter_map(|s| specifier_to_file_path(s).ok()) - .collect::<Vec<_>>(); - } - } - - if include.is_empty() { - include.push(".".to_string()); - } - - IncludeIgnoreCollection { include, ignore } -} diff --git a/cli/tools/fmt.rs b/cli/tools/fmt.rs index d146c958e..56b6bd00b 100644 --- a/cli/tools/fmt.rs +++ b/cli/tools/fmt.rs @@ -8,7 +8,8 @@ //! the same functions as ops available in JS runtime. use crate::args::CliOptions; -use crate::args::FmtFlags; +use crate::args::FilesConfig; +use crate::args::FmtOptions; use crate::args::FmtOptionsConfig; use crate::args::ProseWrap; use crate::colors; @@ -17,7 +18,6 @@ use crate::util::file_watcher; use crate::util::file_watcher::ResolutionResult; use crate::util::fs::FileCollector; use crate::util::path::get_extension; -use crate::util::path::specifier_to_file_path; use crate::util::text_encoding; use deno_ast::ParsedSource; use deno_core::anyhow::bail; @@ -44,80 +44,41 @@ use crate::cache::IncrementalCache; /// Format JavaScript/TypeScript files. pub async fn format( - config: &CliOptions, - fmt_flags: FmtFlags, + cli_options: CliOptions, + fmt_options: FmtOptions, ) -> Result<(), AnyError> { - let maybe_fmt_config = config.to_fmt_config()?; - let deno_dir = config.resolve_deno_dir()?; - let FmtFlags { - files, - ignore, - check, - .. - } = fmt_flags.clone(); - - // First, prepare final configuration. - // Collect included and ignored files. CLI flags take precendence - // over config file, ie. if there's `files.ignore` in config file - // and `--ignore` CLI flag, only the flag value is taken into account. - let mut include_files = files.clone(); - let mut exclude_files = ignore; - - if let Some(fmt_config) = maybe_fmt_config.as_ref() { - if include_files.is_empty() { - include_files = fmt_config - .files - .include - .iter() - .filter_map(|s| specifier_to_file_path(s).ok()) - .collect::<Vec<_>>(); - } - - if exclude_files.is_empty() { - exclude_files = fmt_config - .files - .exclude - .iter() - .filter_map(|s| specifier_to_file_path(s).ok()) - .collect::<Vec<_>>(); - } + if fmt_options.is_stdin { + return format_stdin(fmt_options); } - if include_files.is_empty() { - include_files = [std::env::current_dir()?].to_vec(); - } - - // Now do the same for options - let fmt_options = resolve_fmt_options( - &fmt_flags, - maybe_fmt_config.map(|c| c.options).unwrap_or_default(), - ); + let files = fmt_options.files; + let check = fmt_options.check; + let fmt_config_options = fmt_options.options; let resolver = |changed: Option<Vec<PathBuf>>| { let files_changed = changed.is_some(); - let result = - collect_fmt_files(&include_files, &exclude_files).map(|files| { - let refmt_files = if let Some(paths) = changed { - if check { - files - .iter() - .any(|path| paths.contains(path)) - .then_some(files) - .unwrap_or_else(|| [].to_vec()) - } else { - files - .into_iter() - .filter(|path| paths.contains(path)) - .collect::<Vec<_>>() - } + let result = collect_fmt_files(&files).map(|files| { + let refmt_files = if let Some(paths) = changed { + if check { + files + .iter() + .any(|path| paths.contains(path)) + .then_some(files) + .unwrap_or_else(|| [].to_vec()) } else { files - }; - (refmt_files, fmt_options.clone()) - }); + .into_iter() + .filter(|path| paths.contains(path)) + .collect::<Vec<_>>() + } + } else { + files + }; + (refmt_files, fmt_config_options.clone()) + }); - let paths_to_watch = include_files.clone(); + let paths_to_watch = files.include.clone(); async move { if files_changed && matches!(result, Ok((ref files, _)) if files.is_empty()) @@ -131,6 +92,7 @@ pub async fn format( } } }; + let deno_dir = cli_options.resolve_deno_dir()?; let deno_dir = &deno_dir; let operation = |(paths, fmt_options): (Vec<PathBuf>, FmtOptionsConfig)| async move { let incremental_cache = Arc::new(IncrementalCache::new( @@ -148,40 +110,36 @@ pub async fn format( Ok(()) }; - if config.watch_paths().is_some() { + if cli_options.watch_paths().is_some() { file_watcher::watch_func( resolver, operation, file_watcher::PrintConfig { job_name: "Fmt".to_string(), - clear_screen: !config.no_clear_screen(), + clear_screen: !cli_options.no_clear_screen(), }, ) .await?; } else { - let files = - collect_fmt_files(&include_files, &exclude_files).and_then(|files| { - if files.is_empty() { - Err(generic_error("No target files found.")) - } else { - Ok(files) - } - })?; - operation((files, fmt_options.clone())).await?; + let files = collect_fmt_files(&files).and_then(|files| { + if files.is_empty() { + Err(generic_error("No target files found.")) + } else { + Ok(files) + } + })?; + operation((files, fmt_config_options)).await?; } Ok(()) } -fn collect_fmt_files( - include_files: &[PathBuf], - exclude_files: &[PathBuf], -) -> Result<Vec<PathBuf>, AnyError> { +fn collect_fmt_files(files: &FilesConfig) -> Result<Vec<PathBuf>, AnyError> { FileCollector::new(is_supported_ext_fmt) .ignore_git_folder() .ignore_node_modules() - .add_ignore_paths(exclude_files) - .collect_files(include_files) + .add_ignore_paths(&files.exclude) + .collect_files(&files.include) } /// Formats markdown (using <https://github.com/dprint/dprint-plugin-markdown>) and its code blocks @@ -275,11 +233,11 @@ pub fn format_file( pub fn format_parsed_source( parsed_source: &ParsedSource, - fmt_options: FmtOptionsConfig, + fmt_options: &FmtOptionsConfig, ) -> Result<Option<String>, AnyError> { dprint_plugin_typescript::format_parsed_source( parsed_source, - &get_resolved_typescript_config(&fmt_options), + &get_resolved_typescript_config(fmt_options), ) } @@ -501,19 +459,14 @@ fn format_ensure_stable( /// Format stdin and write result to stdout. /// Treats input as TypeScript or as set by `--ext` flag. /// Compatible with `--check` flag. -pub fn format_stdin( - fmt_flags: FmtFlags, - fmt_options: FmtOptionsConfig, -) -> Result<(), AnyError> { +fn format_stdin(fmt_options: FmtOptions) -> Result<(), AnyError> { let mut source = String::new(); if stdin().read_to_string(&mut source).is_err() { bail!("Failed to read from stdin"); } - let file_path = PathBuf::from(format!("_stdin.{}", fmt_flags.ext)); - let fmt_options = resolve_fmt_options(&fmt_flags, fmt_options); - - let formatted_text = format_file(&file_path, &source, &fmt_options)?; - if fmt_flags.check { + let file_path = PathBuf::from(format!("_stdin.{}", fmt_options.ext)); + let formatted_text = format_file(&file_path, &source, &fmt_options.options)?; + if fmt_options.check { if formatted_text.is_some() { println!("Not formatted stdin"); } @@ -531,41 +484,6 @@ fn files_str(len: usize) -> &'static str { } } -fn resolve_fmt_options( - fmt_flags: &FmtFlags, - options: FmtOptionsConfig, -) -> FmtOptionsConfig { - let mut options = options; - - if let Some(use_tabs) = fmt_flags.use_tabs { - options.use_tabs = Some(use_tabs); - } - - if let Some(line_width) = fmt_flags.line_width { - options.line_width = Some(line_width.get()); - } - - if let Some(indent_width) = fmt_flags.indent_width { - options.indent_width = Some(indent_width.get()); - } - - if let Some(single_quote) = fmt_flags.single_quote { - options.single_quote = Some(single_quote); - } - - if let Some(prose_wrap) = &fmt_flags.prose_wrap { - options.prose_wrap = Some(match prose_wrap.as_str() { - "always" => ProseWrap::Always, - "never" => ProseWrap::Never, - "preserve" => ProseWrap::Preserve, - // validators in `flags.rs` makes other values unreachable - _ => unreachable!(), - }); - } - - options -} - fn get_resolved_typescript_config( options: &FmtOptionsConfig, ) -> dprint_plugin_typescript::configuration::Configuration { diff --git a/cli/tools/lint.rs b/cli/tools/lint.rs index 4606375c1..413e3e34b 100644 --- a/cli/tools/lint.rs +++ b/cli/tools/lint.rs @@ -6,19 +6,19 @@ //! At the moment it is only consumed using CLI but in //! the future it can be easily extended to provide //! the same functions as ops available in JS runtime. -use crate::args::Flags; -use crate::args::LintConfig; -use crate::args::LintFlags; +use crate::args::CliOptions; +use crate::args::FilesConfig; +use crate::args::LintOptions; +use crate::args::LintReporterKind; +use crate::args::LintRulesConfig; use crate::colors; -use crate::proc_state::ProcState; use crate::tools::fmt::run_parallelized; use crate::util::file_watcher; use crate::util::file_watcher::ResolutionResult; use crate::util::fs::FileCollector; use crate::util::path::is_supported_ext; -use crate::util::path::specifier_to_file_path; use deno_ast::MediaType; -use deno_core::anyhow::anyhow; +use deno_core::anyhow::bail; use deno_core::error::generic_error; use deno_core::error::AnyError; use deno_core::error::JsStackFrame; @@ -45,13 +45,6 @@ use crate::cache::IncrementalCache; static STDIN_FILE_NAME: &str = "_stdin.ts"; -#[derive(Clone, Debug)] -pub enum LintReporterKind { - Pretty, - Json, - Compact, -} - fn create_reporter(kind: LintReporterKind) -> Box<dyn LintReporter + Send> { match kind { LintReporterKind::Pretty => Box::new(PrettyLintReporter::new()), @@ -60,102 +53,35 @@ fn create_reporter(kind: LintReporterKind) -> Box<dyn LintReporter + Send> { } } -pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> { - let LintFlags { - maybe_rules_tags, - maybe_rules_include, - maybe_rules_exclude, - files: args, - ignore, - json, - compact, - .. - } = lint_flags; - // First, prepare final configuration. - // Collect included and ignored files. CLI flags take precendence - // over config file, i.e. if there's `files.ignore` in config file - // and `--ignore` CLI flag, only the flag value is taken into account. - let mut include_files = args.clone(); - let mut exclude_files = ignore.clone(); - let mut maybe_reporter_kind = if json { - Some(LintReporterKind::Json) - } else if compact { - Some(LintReporterKind::Compact) - } else { - None - }; - - let ps = ProcState::build(flags).await?; - let maybe_lint_config = ps.options.to_lint_config()?; - - if let Some(lint_config) = maybe_lint_config.as_ref() { - if include_files.is_empty() { - include_files = lint_config - .files - .include - .iter() - .filter_map(|s| specifier_to_file_path(s).ok()) - .collect::<Vec<_>>(); - } - - if exclude_files.is_empty() { - exclude_files = lint_config - .files - .exclude - .iter() - .filter_map(|s| specifier_to_file_path(s).ok()) - .collect::<Vec<_>>(); - } - - if maybe_reporter_kind.is_none() { - maybe_reporter_kind = match lint_config.report.as_deref() { - Some("json") => Some(LintReporterKind::Json), - Some("compact") => Some(LintReporterKind::Compact), - Some("pretty") => Some(LintReporterKind::Pretty), - Some(_) => { - return Err(anyhow!("Invalid lint report type in config file")) - } - None => Some(LintReporterKind::Pretty), - } - } - } +pub async fn lint( + cli_options: CliOptions, + lint_options: LintOptions, +) -> Result<(), AnyError> { + // Try to get lint rules. If none were set use recommended rules. + let lint_rules = get_configured_rules(lint_options.rules); - if include_files.is_empty() { - include_files = [std::env::current_dir()?].to_vec(); + if lint_rules.is_empty() { + bail!("No rules have been configured") } - let reporter_kind = match maybe_reporter_kind { - Some(report) => report, - None => LintReporterKind::Pretty, - }; - - let has_error = Arc::new(AtomicBool::new(false)); - // Try to get configured rules. CLI flags take precendence - // over config file, ie. if there's `rules.include` in config file - // and `--rules-include` CLI flag, only the flag value is taken into account. - let lint_rules = get_configured_rules( - maybe_lint_config.as_ref(), - maybe_rules_tags, - maybe_rules_include, - maybe_rules_exclude, - )?; + let files = lint_options.files; + let reporter_kind = lint_options.reporter_kind; let resolver = |changed: Option<Vec<PathBuf>>| { let files_changed = changed.is_some(); - let result = - collect_lint_files(&include_files, &exclude_files).map(|files| { - if let Some(paths) = changed { - files - .iter() - .any(|path| paths.contains(path)) - .then_some(files) - .unwrap_or_else(|| [].to_vec()) - } else { - files - } - }); + let result = collect_lint_files(&files).map(|files| { + if let Some(paths) = changed { + files + .iter() + .any(|path| paths.contains(path)) + .then_some(files) + .unwrap_or_else(|| [].to_vec()) + } else { + files + } + }); - let paths_to_watch = include_files.clone(); + let paths_to_watch = files.include.clone(); async move { if files_changed && matches!(result, Ok(ref files) if files.is_empty()) { @@ -169,9 +95,12 @@ pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> { } }; + let has_error = Arc::new(AtomicBool::new(false)); + let deno_dir = cli_options.resolve_deno_dir()?; + let operation = |paths: Vec<PathBuf>| async { let incremental_cache = Arc::new(IncrementalCache::new( - &ps.dir.lint_incremental_cache_db_file_path(), + &deno_dir.lint_incremental_cache_db_file_path(), // use a hash of the rule names in order to bust the cache &{ // ensure this is stable by sorting it @@ -221,8 +150,8 @@ pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> { Ok(()) }; - if ps.options.watch_paths().is_some() { - if args.len() == 1 && args[0].to_string_lossy() == "-" { + if cli_options.watch_paths().is_some() { + if lint_options.is_stdin { return Err(generic_error( "Lint watch on standard input is not supported.", )); @@ -232,12 +161,12 @@ pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> { operation, file_watcher::PrintConfig { job_name: "Lint".to_string(), - clear_screen: !ps.options.no_clear_screen(), + clear_screen: !cli_options.no_clear_screen(), }, ) .await?; } else { - if args.len() == 1 && args[0].to_string_lossy() == "-" { + if lint_options.is_stdin { let reporter_lock = Arc::new(Mutex::new(create_reporter(reporter_kind.clone()))); let r = lint_stdin(lint_rules); @@ -249,14 +178,13 @@ pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> { ); reporter_lock.lock().unwrap().close(1); } else { - let target_files = collect_lint_files(&include_files, &exclude_files) - .and_then(|files| { - if files.is_empty() { - Err(generic_error("No target files found.")) - } else { - Ok(files) - } - })?; + let target_files = collect_lint_files(&files).and_then(|files| { + if files.is_empty() { + Err(generic_error("No target files found.")) + } else { + Ok(files) + } + })?; debug!("Found {} files", target_files.len()); operation(target_files).await?; }; @@ -269,15 +197,12 @@ pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> { Ok(()) } -fn collect_lint_files( - include_files: &[PathBuf], - exclude_files: &[PathBuf], -) -> Result<Vec<PathBuf>, AnyError> { +fn collect_lint_files(files: &FilesConfig) -> Result<Vec<PathBuf>, AnyError> { FileCollector::new(is_supported_ext) .ignore_git_folder() .ignore_node_modules() - .add_ignore_paths(exclude_files) - .collect_files(include_files) + .add_ignore_paths(&files.exclude) + .collect_files(&files.include) } pub fn print_rules_list(json: bool) { @@ -606,60 +531,17 @@ fn sort_diagnostics(diagnostics: &mut [LintDiagnostic]) { }); } -pub fn get_configured_rules( - maybe_lint_config: Option<&LintConfig>, - maybe_rules_tags: Option<Vec<String>>, - maybe_rules_include: Option<Vec<String>>, - maybe_rules_exclude: Option<Vec<String>>, -) -> Result<Vec<Arc<dyn LintRule>>, AnyError> { - if maybe_lint_config.is_none() - && maybe_rules_tags.is_none() - && maybe_rules_include.is_none() - && maybe_rules_exclude.is_none() +pub fn get_configured_rules(rules: LintRulesConfig) -> Vec<Arc<dyn LintRule>> { + if rules.tags.is_none() && rules.include.is_none() && rules.exclude.is_none() { - return Ok(rules::get_recommended_rules()); - } - - let (config_file_tags, config_file_include, config_file_exclude) = - if let Some(lint_config) = maybe_lint_config { - ( - lint_config.rules.tags.clone(), - lint_config.rules.include.clone(), - lint_config.rules.exclude.clone(), - ) - } else { - (None, None, None) - }; - - let maybe_configured_include = if maybe_rules_include.is_some() { - maybe_rules_include - } else { - config_file_include - }; - - let maybe_configured_exclude = if maybe_rules_exclude.is_some() { - maybe_rules_exclude - } else { - config_file_exclude - }; - - let maybe_configured_tags = if maybe_rules_tags.is_some() { - maybe_rules_tags + rules::get_recommended_rules() } else { - config_file_tags - }; - - let configured_rules = rules::get_filtered_rules( - maybe_configured_tags.or_else(|| Some(vec!["recommended".to_string()])), - maybe_configured_exclude, - maybe_configured_include, - ); - - if configured_rules.is_empty() { - return Err(anyhow!("No rules have been configured")); + rules::get_filtered_rules( + rules.tags.or_else(|| Some(vec!["recommended".to_string()])), + rules.exclude, + rules.include, + ) } - - Ok(configured_rules) } #[cfg(test)] @@ -671,15 +553,12 @@ mod test { #[test] fn recommended_rules_when_no_tags_in_config() { - let lint_config = LintConfig { - rules: LintRulesConfig { - exclude: Some(vec!["no-debugger".to_string()]), - ..Default::default() - }, - ..Default::default() + let rules_config = LintRulesConfig { + exclude: Some(vec!["no-debugger".to_string()]), + include: None, + tags: None, }; - let rules = - get_configured_rules(Some(&lint_config), None, None, None).unwrap(); + let rules = get_configured_rules(rules_config); let mut rule_names = rules .into_iter() .map(|r| r.code().to_string()) diff --git a/cli/tools/test.rs b/cli/tools/test.rs index 9d1774fff..4cac8a404 100644 --- a/cli/tools/test.rs +++ b/cli/tools/test.rs @@ -1,7 +1,8 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -use crate::args::Flags; -use crate::args::TestFlags; +use crate::args::CliOptions; +use crate::args::FilesConfig; +use crate::args::TestOptions; use crate::args::TypeCheckMode; use crate::colors; use crate::display; @@ -16,7 +17,6 @@ use crate::util::file_watcher::ResolutionResult; use crate::util::fs::collect_specifiers; use crate::util::path::get_extension; use crate::util::path::is_supported_ext; -use crate::util::path::specifier_to_file_path; use crate::worker::create_main_worker_for_test_or_bench; use deno_ast::swc::common::comments::CommentKind; @@ -1237,15 +1237,13 @@ fn is_supported_test_ext(path: &Path) -> bool { /// - Specifiers matching the `is_supported_test_path` are marked as `TestMode::Executable`. /// - Specifiers matching both predicates are marked as `TestMode::Both` fn collect_specifiers_with_test_mode( - include: Vec<String>, - ignore: Vec<PathBuf>, + files: FilesConfig, include_inline: bool, ) -> Result<Vec<(ModuleSpecifier, TestMode)>, AnyError> { - let module_specifiers = - collect_specifiers(include.clone(), &ignore, is_supported_test_path)?; + let module_specifiers = collect_specifiers(&files, is_supported_test_path)?; if include_inline { - return collect_specifiers(include, &ignore, is_supported_test_ext).map( + return collect_specifiers(&files, is_supported_test_ext).map( |specifiers| { specifiers .into_iter() @@ -1281,44 +1279,10 @@ fn collect_specifiers_with_test_mode( /// as well. async fn fetch_specifiers_with_test_mode( ps: &ProcState, - include: Vec<String>, - ignore: Vec<PathBuf>, - include_inline: bool, + files: FilesConfig, + doc: bool, ) -> Result<Vec<(ModuleSpecifier, TestMode)>, AnyError> { - let maybe_test_config = ps.options.to_test_config()?; - - let mut include_files = include.clone(); - let mut exclude_files = ignore.clone(); - - if let Some(test_config) = maybe_test_config.as_ref() { - if include_files.is_empty() { - include_files = test_config - .files - .include - .iter() - .map(|s| s.to_string()) - .collect::<Vec<_>>(); - } - - if exclude_files.is_empty() { - exclude_files = test_config - .files - .exclude - .iter() - .filter_map(|s| specifier_to_file_path(s).ok()) - .collect::<Vec<_>>(); - } - } - - if include_files.is_empty() { - include_files.push(".".to_string()); - } - - let mut specifiers_with_mode = collect_specifiers_with_test_mode( - include_files, - exclude_files, - include_inline, - )?; + let mut specifiers_with_mode = collect_specifiers_with_test_mode(files, doc)?; for (specifier, mode) in &mut specifiers_with_mode { let file = ps .file_fetcher @@ -1336,31 +1300,28 @@ async fn fetch_specifiers_with_test_mode( } pub async fn run_tests( - flags: Flags, - test_flags: TestFlags, + cli_options: CliOptions, + test_options: TestOptions, ) -> Result<(), AnyError> { - let ps = ProcState::build(flags).await?; + let ps = ProcState::from_options(Arc::new(cli_options)).await?; // Various test files should not share the same permissions in terms of // `PermissionsContainer` - otherwise granting/revoking permissions in one // file would have impact on other files, which is undesirable. let permissions = Permissions::from_options(&ps.options.permissions_options())?; - let specifiers_with_mode = fetch_specifiers_with_test_mode( - &ps, - test_flags.include, - test_flags.ignore.clone(), - test_flags.doc, - ) - .await?; - if !test_flags.allow_none && specifiers_with_mode.is_empty() { + let specifiers_with_mode = + fetch_specifiers_with_test_mode(&ps, test_options.files, test_options.doc) + .await?; + + if !test_options.allow_none && specifiers_with_mode.is_empty() { return Err(generic_error("No test modules found")); } check_specifiers(&ps, permissions.clone(), specifiers_with_mode.clone()) .await?; - if test_flags.no_run { + if test_options.no_run { return Ok(()); } @@ -1369,9 +1330,9 @@ pub async fn run_tests( permissions, specifiers_with_mode, TestSpecifierOptions { - concurrent_jobs: test_flags.concurrent_jobs, - fail_fast: test_flags.fail_fast, - filter: TestFilter::from_flag(&test_flags.filter), + concurrent_jobs: test_options.concurrent_jobs, + fail_fast: test_options.fail_fast, + filter: TestFilter::from_flag(&test_options.filter), }, ) .await?; @@ -1380,35 +1341,32 @@ pub async fn run_tests( } pub async fn run_tests_with_watch( - flags: Flags, - test_flags: TestFlags, + cli_options: CliOptions, + test_options: TestOptions, ) -> Result<(), AnyError> { - let ps = ProcState::build(flags).await?; + let ps = ProcState::from_options(Arc::new(cli_options)).await?; // Various test files should not share the same permissions in terms of // `PermissionsContainer` - otherwise granting/revoking permissions in one // file would have impact on other files, which is undesirable. let permissions = Permissions::from_options(&ps.options.permissions_options())?; - let include = test_flags.include; - let ignore = test_flags.ignore.clone(); - let paths_to_watch: Vec<_> = include.iter().map(PathBuf::from).collect(); + let paths_to_watch: Vec<_> = test_options.files.include.clone(); let no_check = ps.options.type_check_mode() == TypeCheckMode::None; + let test_options = &test_options; let resolver = |changed: Option<Vec<PathBuf>>| { let paths_to_watch = paths_to_watch.clone(); let paths_to_watch_clone = paths_to_watch.clone(); let files_changed = changed.is_some(); - let include = include.clone(); - let ignore = ignore.clone(); let ps = ps.clone(); async move { - let test_modules = if test_flags.doc { - collect_specifiers(include.clone(), &ignore, is_supported_test_ext) + let test_modules = if test_options.doc { + collect_specifiers(&test_options.files, is_supported_test_ext) } else { - collect_specifiers(include.clone(), &ignore, is_supported_test_path) + collect_specifiers(&test_options.files, is_supported_test_path) }?; let mut paths_to_watch = paths_to_watch_clone; @@ -1517,20 +1475,16 @@ pub async fn run_tests_with_watch( }) }; - let cli_options = ps.options.clone(); let operation = |modules_to_reload: Vec<(ModuleSpecifier, ModuleKind)>| { - let filter = test_flags.filter.clone(); - let include = include.clone(); - let ignore = ignore.clone(); let permissions = permissions.clone(); let ps = ps.clone(); + let test_options = test_options.clone(); async move { let specifiers_with_mode = fetch_specifiers_with_test_mode( &ps, - include.clone(), - ignore.clone(), - test_flags.doc, + test_options.files, + test_options.doc, ) .await? .iter() @@ -1543,7 +1497,7 @@ pub async fn run_tests_with_watch( check_specifiers(&ps, permissions.clone(), specifiers_with_mode.clone()) .await?; - if test_flags.no_run { + if test_options.no_run { return Ok(()); } @@ -1552,9 +1506,9 @@ pub async fn run_tests_with_watch( permissions.clone(), specifiers_with_mode, TestSpecifierOptions { - concurrent_jobs: test_flags.concurrent_jobs, - fail_fast: test_flags.fail_fast, - filter: TestFilter::from_flag(&filter), + concurrent_jobs: test_options.concurrent_jobs, + fail_fast: test_options.fail_fast, + filter: TestFilter::from_flag(&test_options.filter), }, ) .await?; @@ -1568,7 +1522,7 @@ pub async fn run_tests_with_watch( operation, file_watcher::PrintConfig { job_name: "Test".to_string(), - clear_screen: !cli_options.no_clear_screen(), + clear_screen: !ps.options.no_clear_screen(), }, ) .await?; diff --git a/cli/tools/vendor/mod.rs b/cli/tools/vendor/mod.rs index c15c7d1d3..aa306275c 100644 --- a/cli/tools/vendor/mod.rs +++ b/cli/tools/vendor/mod.rs @@ -153,9 +153,12 @@ fn maybe_update_config_file(output_dir: &Path, ps: &ProcState) -> bool { Some(f) => f, None => return false, }; + let fmt_config = ps .options - .to_fmt_config() + .get_maybe_config_file() + .as_ref() + .and_then(|config| config.to_fmt_config().ok()) .unwrap_or_default() .unwrap_or_default(); let result = update_config_file( |