From 4ac2e990a2ce3b5b8510eb5ae9319ca7a11ad996 Mon Sep 17 00:00:00 2001 From: Tapan Prakash Date: Tue, 14 Jan 2025 11:19:42 +0530 Subject: [PATCH] feat(oxlint): implement `--init` cli option (#8453) Implemented --init cli option to create oxlint configuration files with default values. close https://github.com/oxc-project/oxc/issues/7453 --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- apps/oxlint/src/command/lint.rs | 4 ++ apps/oxlint/src/lint.rs | 43 ++++++++++++++++--- apps/oxlint/src/result.rs | 5 +++ tasks/website/src/linter/snapshots/cli.snap | 2 + .../src/linter/snapshots/cli_terminal.snap | 1 + 5 files changed, 48 insertions(+), 7 deletions(-) diff --git a/apps/oxlint/src/command/lint.rs b/apps/oxlint/src/command/lint.rs index c2435c1a1fc57..d170574ca0e54 100644 --- a/apps/oxlint/src/command/lint.rs +++ b/apps/oxlint/src/command/lint.rs @@ -71,6 +71,10 @@ pub struct BasicOptions { /// TypeScript `tsconfig.json` path for reading path alias and project references for import plugin #[bpaf(argument("./tsconfig.json"), hide_usage)] pub tsconfig: Option, + + /// Initialize oxlint configuration with default values + #[bpaf(switch, hide_usage)] + pub init: bool, } // This is formatted according to diff --git a/apps/oxlint/src/lint.rs b/apps/oxlint/src/lint.rs index 5ca498dfcc0d6..c3f2400ab0d38 100644 --- a/apps/oxlint/src/lint.rs +++ b/apps/oxlint/src/lint.rs @@ -1,5 +1,5 @@ use std::{ - env, + env, fs, io::BufWriter, path::{Path, PathBuf}, time::Instant, @@ -118,15 +118,32 @@ impl Runner for LintRunner { enable_plugins.apply_overrides(&mut oxlintrc.plugins); - let oxlintrc_for_print = - if misc_options.print_config { Some(oxlintrc.clone()) } else { None }; + let oxlintrc_for_print = if misc_options.print_config || basic_options.init { + Some(oxlintrc.clone()) + } else { + None + }; let config_builder = ConfigStoreBuilder::from_oxlintrc(false, oxlintrc).with_filters(filter); if let Some(basic_config_file) = oxlintrc_for_print { - return CliRunResult::PrintConfigResult { - config_file: config_builder.resolve_final_config_file(basic_config_file), - }; + let config_file = config_builder.resolve_final_config_file(basic_config_file); + if misc_options.print_config { + return CliRunResult::PrintConfigResult { config_file }; + } else if basic_options.init { + match fs::write(Self::DEFAULT_OXLINTRC, config_file) { + Ok(()) => { + return CliRunResult::ConfigFileInitResult { + message: "Configuration file created".to_string(), + } + } + Err(_) => { + return CliRunResult::ConfigFileInitResult { + message: "Failed to create configuration file".to_string(), + } + } + } + } } let mut options = LintServiceOptions::new(self.cwd, paths) @@ -283,7 +300,7 @@ impl LintRunner { #[cfg(test)] mod test { - use std::{env, path::MAIN_SEPARATOR_STR}; + use std::{env, fs, path::MAIN_SEPARATOR_STR}; use super::LintRunner; use crate::cli::{lint_command, CliRunResult, LintResult, Runner}; @@ -750,6 +767,18 @@ mod test { assert_eq!(config, expect_json.trim()); } + #[test] + fn test_init_config() { + let args = &["--init"]; + let options = lint_command().run_inner(args).unwrap(); + let ret = LintRunner::new(options).run(); + let CliRunResult::ConfigFileInitResult { message } = ret else { + panic!("Expected configuration file to be created, got {ret:?}") + }; + assert_eq!(message, "Configuration file created"); + fs::remove_file(LintRunner::DEFAULT_OXLINTRC).unwrap(); + } + #[test] fn test_overrides() { let result = diff --git a/apps/oxlint/src/result.rs b/apps/oxlint/src/result.rs index 49f01e213881b..78c7eddb55fc5 100644 --- a/apps/oxlint/src/result.rs +++ b/apps/oxlint/src/result.rs @@ -11,6 +11,7 @@ pub enum CliRunResult { PathNotFound { paths: Vec }, LintResult(LintResult), PrintConfigResult { config_file: String }, + ConfigFileInitResult { message: String }, } /// A summary of a complete linter run. @@ -93,6 +94,10 @@ impl Termination for CliRunResult { println!("{config_file}"); ExitCode::from(0) } + Self::ConfigFileInitResult { message } => { + println!("{message}"); + ExitCode::from(0) + } } } } diff --git a/tasks/website/src/linter/snapshots/cli.snap b/tasks/website/src/linter/snapshots/cli.snap index d2766eb69aee8..ba44d6240edf1 100644 --- a/tasks/website/src/linter/snapshots/cli.snap +++ b/tasks/website/src/linter/snapshots/cli.snap @@ -15,6 +15,8 @@ snapshot_kind: text If not provided, Oxlint will look for `.oxlintrc.json` in the current working directory. - **` --tsconfig`**=_`<./tsconfig.json>`_ — TypeScript `tsconfig.json` path for reading path alias and project references for import plugin +- **` --init`** — + Initialize oxlint configuration with default values diff --git a/tasks/website/src/linter/snapshots/cli_terminal.snap b/tasks/website/src/linter/snapshots/cli_terminal.snap index fef1bf28b61fc..8896e922ac411 100644 --- a/tasks/website/src/linter/snapshots/cli_terminal.snap +++ b/tasks/website/src/linter/snapshots/cli_terminal.snap @@ -11,6 +11,7 @@ Basic Configuration * tries to be compatible with the ESLint v8's format --tsconfig=<./tsconfig.json> TypeScript `tsconfig.json` path for reading path alias and project references for import plugin + --init Initialize oxlint configuration with default values Allowing / Denying Multiple Lints Accumulate rules and categories from left to right on the command-line.