diff --git a/.github/labeler.yml b/.github/labeler.yml index f046ca749e19..f260d2e1bdce 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -28,28 +28,21 @@ A-Linter: - changed-files: - any-glob-to-any-file: - crates/biome_analyze/** - - crates/biome_js_analyze/** - - crates/biome_json_analyze/** + - crates/biome_*_analyze/** A-Parser: - changed-files: - any-glob-to-any-file: - crates/biome_parser/** - - crates/biome_js_parser/** - - crates/biome_js_syntax/** - - crates/biome_json_parser/** - - crates/biome_json_syntax/** - - crates/biome_css_parser/** - - crates/biome_css_syntax/** + - crates/biome_*_parser/** + - crates/biome_*_syntax/** A-Formatter: - changed-files: - any-glob-to-any-file: - crates/biome_formatter/** - crates/biome_formatter_test/** - - crates/biome_js_formatter/** - - crates/biome_json_formatter/** - - crates/biome_css_formatter/** + - crates/biome_*_formatter/** A-Editors: - changed-files: diff --git a/.github/workflows/bench_cli.yml b/.github/workflows/bench_cli.yml index fd2964abaf61..7591f406e6e6 100644 --- a/.github/workflows/bench_cli.yml +++ b/.github/workflows/bench_cli.yml @@ -39,6 +39,8 @@ jobs: channel: stable cache-target: release cache-base: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Install hyperfine run: cargo install hyperfine diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index d7f79fb66186..59fa4af12250 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -44,6 +44,8 @@ jobs: cache-target: release bins: cargo-codspeed cache-base: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Compile run: cargo codspeed build --features codspeed -p xtask_bench diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2ab150cb8c00..3c09ffc4b5fa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -33,6 +33,8 @@ jobs: components: rustfmt bins: taplo-cli cache-base: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Run rustfmt run: | cargo fmt --all --verbose -- --check @@ -51,6 +53,8 @@ jobs: with: components: clippy cache-base: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Run cargo check run: cargo check --workspace --all-targets --release - name: Run clippy @@ -69,6 +73,8 @@ jobs: with: channel: nightly cache: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Install udeps run: cargo install cargo-udeps --locked - name: Run udeps @@ -92,6 +98,8 @@ jobs: uses: moonrepo/setup-rust@e013866c4215f77c925f42f60257dec7dd18836e # v1.2.1 with: cache-base: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Run tests on ${{ matrix.os }} run: cargo test --workspace @@ -118,6 +126,8 @@ jobs: with: cache-target: release cache-base: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Compile run: cargo build --release --locked -p xtask_coverage - name: Run Test262 suite diff --git a/.github/workflows/parser_conformance.yml b/.github/workflows/parser_conformance.yml index f35806f8d797..8257b0d54aaf 100644 --- a/.github/workflows/parser_conformance.yml +++ b/.github/workflows/parser_conformance.yml @@ -43,6 +43,8 @@ jobs: with: cache-target: release cache-base: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Compile run: cargo build --release --locked -p xtask_coverage diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index cb8beda8a175..2fdae0fd1b6c 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -38,6 +38,8 @@ jobs: components: rustfmt bins: taplo-cli cache-base: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Run format run: | cargo fmt --all --check @@ -56,6 +58,8 @@ jobs: with: components: clippy cache-base: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Run clippy run: | cargo lint @@ -93,6 +97,8 @@ jobs: uses: moonrepo/setup-rust@e013866c4215f77c925f42f60257dec7dd18836e # v1.2.1 with: cache-base: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Run tests run: cargo test --workspace @@ -109,6 +115,8 @@ jobs: with: cache-target: release cache-base: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Build main binary run: cargo build -p biome_cli --release - name: Install Node.js @@ -152,6 +160,8 @@ jobs: uses: moonrepo/setup-rust@e013866c4215f77c925f42f60257dec7dd18836e # v1.2.1 with: cache-base: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Run doc command run: cargo documentation @@ -167,6 +177,8 @@ jobs: uses: moonrepo/setup-rust@e013866c4215f77c925f42f60257dec7dd18836e # v1.2.1 with: cache-base: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Run the grammar codegen run: cargo codegen grammar - name: Run the analyzer codegen diff --git a/.github/workflows/release_knope.yml b/.github/workflows/release_knope.yml index bf31af078080..c22d6db10be1 100644 --- a/.github/workflows/release_knope.yml +++ b/.github/workflows/release_knope.yml @@ -5,6 +5,7 @@ on: types: [ closed ] branches: [ main ] + jobs: retrieve-version: if: github.head_ref == 'release/automated-ci' && github.event.pull_request.merged == true @@ -81,6 +82,8 @@ jobs: channel: stable cache-target: release cache-base: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Install arm64 toolchain if: matrix.code-target == 'linux-arm64' || matrix.code-target == 'linux-arm64-musl' @@ -245,6 +248,8 @@ jobs: channel: stable cache-target: release cache-base: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - uses: katyo/publish-crates@v2 with: registry-token: ${{ secrets.CARGO_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 8509c065cfed..3c2baef6940d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,42 @@ New entries must be placed in a section entitled `Unreleased`. Read our [guidelines for writing a good changelog entry](https://github.com/biomejs/biome/blob/main/CONTRIBUTING.md#changelog). +## Unreleased + +## v1.9.1 (2024-09-15) + +### Analyzer + +### CLI + +#### Bug fixes + +- `useEditorConfig` now loads the editorconfig when running `biome ci` [#3864](https://github.com/biomejs/biome/issues/3864). Contributed by @dyc3 + +- Revert [#3731](https://github.com/biomejs/biome/pull/3731) to fix broken quick fixes and code actions. Contributed by @nhedger + +### Configuration + +### Editors + +### Formatter + +### JavaScript APIs + +### Linter + +#### New Features + +- Add [nursery/noProcessEnv](https://biomejs.dev/linter/rules/no-process-env/). Contributed by @unvalley + +#### Bug fixes + +- [useSemanticElements](https://biomejs.dev/linter/rules/use-semantic-elements/) now ignores `alert` and `alertdialog` roles ([3858](https://github.com/biomejs/biome/issues/3858)). Contributed by @Conaclos + +- [noUndeclaredDependencies](https://biomejs.dev/linter/rules/no-undeclared-dependencies/) now ignores `@/` imports and recognizes type imports from Definitely Typed and `bun` imports. Contributed by @Conaclos + +### Parser + ## v1.9.0 (2024-09-12) ### Analyzer @@ -375,7 +411,7 @@ The following JavaScript rules are promoted: - Add [nursery/useTrimStartEnd](https://biomejs.dev/linter/rules/use-trim-start-end/). Contributed by @chansuke -- Add [nursery/noIrreguluarWhitespace](https://biomejs.dev/linter/rules/no-irreguluar-whitespace/). Contributed by @DerTimonius +- Add [nursery/noIrregularWhitespace](https://biomejs.dev/linter/rules/no-irreguluar-whitespace/). Contributed by @DerTimonius #### Enhancements diff --git a/crates/biome_analyze/src/rule.rs b/crates/biome_analyze/src/rule.rs index fda3954f06f0..6b5b027ec0b4 100644 --- a/crates/biome_analyze/src/rule.rs +++ b/crates/biome_analyze/src/rule.rs @@ -122,6 +122,8 @@ pub enum RuleSource { EslintMysticatea(&'static str), /// Rules from [Eslint Plugin Barrel Files](https://github.com/thepassle/eslint-plugin-barrel-files) EslintBarrelFiles(&'static str), + /// Rules from [Eslint Plugin N](https://github.com/eslint-community/eslint-plugin-n) + EslintN(&'static str), /// Rules from [Stylelint](https://github.com/stylelint/stylelint) Stylelint(&'static str), } @@ -152,6 +154,7 @@ impl std::fmt::Display for RuleSource { Self::EslintUnusedImports(_) => write!(f, "eslint-plugin-unused-imports"), Self::EslintMysticatea(_) => write!(f, "@mysticatea/eslint-plugin"), Self::EslintBarrelFiles(_) => write!(f, "eslint-plugin-barrel-files"), + Self::EslintN(_) => write!(f, "eslint-plugin-n"), Self::Stylelint(_) => write!(f, "Stylelint"), } } @@ -199,6 +202,7 @@ impl RuleSource { | Self::EslintUnusedImports(rule_name) | Self::EslintMysticatea(rule_name) | Self::EslintBarrelFiles(rule_name) + | Self::EslintN(rule_name) | Self::Stylelint(rule_name) => rule_name, } } @@ -221,6 +225,7 @@ impl RuleSource { Self::EslintUnusedImports(rule_name) => format!("unused-imports/{rule_name}"), Self::EslintMysticatea(rule_name) => format!("@mysticatea/{rule_name}"), Self::EslintBarrelFiles(rule_name) => format!("barrel-files/{rule_name}"), + Self::EslintN(rule_name) => format!("n/{rule_name}"), Self::Stylelint(rule_name) => format!("stylelint/{rule_name}"), } } @@ -237,13 +242,14 @@ impl RuleSource { Self::EslintReact(rule_name) => format!("https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/{rule_name}.md"), Self::EslintReactHooks(_) => "https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/README.md".to_string(), Self::EslintTypeScript(rule_name) => format!("https://typescript-eslint.io/rules/{rule_name}"), - Self::EslintSolid(rule_name) => format!("https://github.com/solidjs-community/eslint-plugin-solid/blob/main/docs/{rule_name}.md"), + Self::EslintSolid(rule_name) => format!("https://github.com/solidjs-community/eslint-plugin-solid/blob/main/packages/eslint-plugin-solid/docs/{rule_name}.md"), Self::EslintSonarJs(rule_name) => format!("https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/{rule_name}.md"), Self::EslintStylistic(rule_name) => format!("https://eslint.style/rules/default/{rule_name}"), Self::EslintUnicorn(rule_name) => format!("https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/{rule_name}.md"), Self::EslintUnusedImports(rule_name) => format!("https://github.com/sweepline/eslint-plugin-unused-imports/blob/master/docs/rules/{rule_name}.md"), Self::EslintMysticatea(rule_name) => format!("https://github.com/mysticatea/eslint-plugin/blob/master/docs/rules/{rule_name}.md"), Self::EslintBarrelFiles(rule_name) => format!("https://github.com/thepassle/eslint-plugin-barrel-files/blob/main/docs/rules/{rule_name}.md"), + Self::EslintN(rule_name) => format!("https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/{rule_name}.md"), Self::Stylelint(rule_name) => format!("https://github.com/stylelint/stylelint/blob/main/lib/rules/{rule_name}/README.md"), } } diff --git a/crates/biome_aria/src/roles.rs b/crates/biome_aria/src/roles.rs index eb3fac5eb288..d80f54d9395b 100644 --- a/crates/biome_aria/src/roles.rs +++ b/crates/biome_aria/src/roles.rs @@ -195,7 +195,6 @@ define_role! { AlertRole { PROPS: [], ROLES: ["section"], - CONCEPTS: &[("alert", &[])], } } define_role! { @@ -203,7 +202,6 @@ define_role! { AlertDialogRole { PROPS: [], ROLES: ["structure"], - CONCEPTS: &[("alert", &[])], } } define_role! { @@ -849,8 +847,6 @@ impl<'a> AriaRoles { "button", "article", "dialog", - "alert", - "alertdialog", "cell", "columnheader", "definition", @@ -1228,8 +1224,6 @@ impl<'a> AriaRoles { "button" => &ButtonRole as &dyn AriaRoleDefinitionWithConcepts, "article" => &ArticleRole as &dyn AriaRoleDefinitionWithConcepts, "dialog" => &DialogRole as &dyn AriaRoleDefinitionWithConcepts, - "alert" => &AlertRole as &dyn AriaRoleDefinitionWithConcepts, - "alertdialog" => &AlertDialogRole as &dyn AriaRoleDefinitionWithConcepts, "cell" => &CellRole as &dyn AriaRoleDefinitionWithConcepts, "columnheader" => &ColumnHeaderRole as &dyn AriaRoleDefinitionWithConcepts, "definition" => &DefinitionRole as &dyn AriaRoleDefinitionWithConcepts, @@ -1289,8 +1283,6 @@ impl<'a> AriaRoles { "button" => &ButtonRole as &dyn AriaRoleDefinitionWithConcepts, "article" => &ArticleRole as &dyn AriaRoleDefinitionWithConcepts, "dialog" => &DialogRole as &dyn AriaRoleDefinitionWithConcepts, - "alert" => &AlertRole as &dyn AriaRoleDefinitionWithConcepts, - "alertdialog" => &AlertDialogRole as &dyn AriaRoleDefinitionWithConcepts, "cell" => &CellRole as &dyn AriaRoleDefinitionWithConcepts, "columnheader" => &ColumnHeaderRole as &dyn AriaRoleDefinitionWithConcepts, "definition" => &DefinitionRole as &dyn AriaRoleDefinitionWithConcepts, diff --git a/crates/biome_cli/src/commands/ci.rs b/crates/biome_cli/src/commands/ci.rs index 7d4ba89cf0d5..82ee9db9a2aa 100644 --- a/crates/biome_cli/src/commands/ci.rs +++ b/crates/biome_cli/src/commands/ci.rs @@ -6,9 +6,11 @@ use crate::{execute_mode, setup_cli_subscriber, CliDiagnostic, CliSession, Execu use biome_configuration::analyzer::assists::PartialAssistsConfiguration; use biome_configuration::{organize_imports::PartialOrganizeImports, PartialConfiguration}; use biome_configuration::{PartialFormatterConfiguration, PartialLinterConfiguration}; +use biome_console::{markup, ConsoleExt}; use biome_deserialize::Merge; +use biome_diagnostics::PrintDiagnostic; use biome_service::configuration::{ - load_configuration, LoadedConfiguration, PartialConfigurationExt, + load_configuration, load_editorconfig, LoadedConfiguration, PartialConfigurationExt, }; use biome_service::workspace::{RegisterProjectFolderParams, UpdateSettingsParams}; use std::ffi::OsString; @@ -49,11 +51,44 @@ pub(crate) fn ci(session: CliSession, payload: CiCommandPayload) -> Result<(), C cli_options.verbose, )?; + let editorconfig_search_path = loaded_configuration.directory_path.clone(); let LoadedConfiguration { - configuration: mut fs_configuration, + configuration: biome_configuration, directory_path: configuration_path, .. } = loaded_configuration; + + let should_use_editorconfig = configuration + .as_ref() + .and_then(|c| c.formatter.as_ref()) + .and_then(|f| f.use_editorconfig) + .unwrap_or( + biome_configuration + .formatter + .as_ref() + .and_then(|f| f.use_editorconfig) + .unwrap_or_default(), + ); + let mut fs_configuration = if should_use_editorconfig { + let (editorconfig, editorconfig_diagnostics) = { + let search_path = editorconfig_search_path.unwrap_or_else(|| { + let fs = &session.app.fs; + fs.working_directory().unwrap_or_default() + }); + load_editorconfig(&session.app.fs, search_path)? + }; + for diagnostic in editorconfig_diagnostics { + session.app.console.error(markup! { + {PrintDiagnostic::simple(&diagnostic)} + }) + } + editorconfig.unwrap_or_default() + } else { + Default::default() + }; + // this makes biome configuration take precedence over editorconfig configuration + fs_configuration.merge_with(biome_configuration); + let formatter = fs_configuration .formatter .get_or_insert_with(PartialFormatterConfiguration::default); diff --git a/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs b/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs index 2fb83088aa24..69cc5880e960 100644 --- a/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs +++ b/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs @@ -697,6 +697,14 @@ pub(crate) fn migrate_eslint_any_rule( let rule = group.no_positive_tabindex.get_or_insert(Default::default()); rule.set_level(rule_severity.into()); } + "n/no-process-env" => { + if !options.include_nursery { + return false; + } + let group = rules.nursery.get_or_insert_with(Default::default); + let rule = group.no_process_env.get_or_insert(Default::default()); + rule.set_level(rule_severity.into()); + } "no-array-constructor" => { let group = rules.correctness.get_or_insert_with(Default::default); let rule = group.use_array_literals.get_or_insert(Default::default()); diff --git a/crates/biome_cli/tests/cases/editorconfig.rs b/crates/biome_cli/tests/cases/editorconfig.rs index c015fef114d8..4fd50b74732b 100644 --- a/crates/biome_cli/tests/cases/editorconfig.rs +++ b/crates/biome_cli/tests/cases/editorconfig.rs @@ -360,3 +360,95 @@ indent_style = space result, )); } + +#[test] +fn should_use_editorconfig_ci() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + let editorconfig = Path::new(".editorconfig"); + fs.insert( + editorconfig.into(), + r#" +[*] +max_line_length = 300 +"#, + ); + + let test_file = Path::new("test.js"); + let contents = r#"console.log("really long string that should cause a break if the line width remains at the default 80 characters"); +"#; + fs.insert(test_file.into(), contents); + + let result = run_cli( + DynRef::Borrowed(&mut fs), + &mut console, + Args::from( + [ + ("ci"), + ("--use-editorconfig=true"), + test_file.as_os_str().to_str().unwrap(), + ] + .as_slice(), + ), + ); + + assert!(result.is_ok(), "run_cli returned {result:?}"); + + assert_file_contents(&fs, test_file, contents); + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "should_use_editorconfig_ci", + fs, + console, + result, + )); +} + +#[test] +fn should_use_editorconfig_ci_enabled_from_biome_conf() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + let editorconfig = Path::new(".editorconfig"); + fs.insert( + editorconfig.into(), + r#" +[*] +max_line_length = 300 +"#, + ); + + let biomeconfig = Path::new("biome.json"); + fs.insert( + biomeconfig.into(), + r#"{ + "formatter": { + "useEditorconfig": true + } +} +"#, + ); + + let test_file = Path::new("test.js"); + let contents = r#"console.log("really long string that should cause a break if the line width remains at the default 80 characters"); +"#; + fs.insert(test_file.into(), contents); + + let result = run_cli( + DynRef::Borrowed(&mut fs), + &mut console, + Args::from([("ci"), test_file.as_os_str().to_str().unwrap()].as_slice()), + ); + + assert!(result.is_ok(), "run_cli returned {result:?}"); + + assert_file_contents(&fs, test_file, contents); + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "should_use_editorconfig_ci_enabled_from_biome_conf", + fs, + console, + result, + )); +} diff --git a/crates/biome_cli/tests/snapshots/main_cases_editorconfig/should_use_editorconfig_ci.snap b/crates/biome_cli/tests/snapshots/main_cases_editorconfig/should_use_editorconfig_ci.snap new file mode 100644 index 000000000000..b7d09bc8e354 --- /dev/null +++ b/crates/biome_cli/tests/snapshots/main_cases_editorconfig/should_use_editorconfig_ci.snap @@ -0,0 +1,25 @@ +--- +source: crates/biome_cli/tests/snap_test.rs +expression: content +--- +## `.editorconfig` + +```editorconfig + +[*] +max_line_length = 300 + +``` + +## `test.js` + +```js +console.log("really long string that should cause a break if the line width remains at the default 80 characters"); + +``` + +# Emitted Messages + +```block +Checked 1 file in