diff --git a/.changeset/bright-tires-report.md b/.changeset/bright-tires-report.md new file mode 100644 index 000000000000..f6aa16470827 --- /dev/null +++ b/.changeset/bright-tires-report.md @@ -0,0 +1,14 @@ +--- +"@biomejs/biome": patch +--- + +Fixed [#8148](https://github.com/biomejs/biome/issues/8148). [`noInvalidUseBeforeDeclaration`](https://biomejs.dev/linter/rules/no-invalid-use-before-declaration/) no longer reports some valid use before declarations. + +The following code is no longer reported as invalid: + +```ts +class classA { + C = C; +} +const C = 0; +``` diff --git a/.changeset/chilly-jokes-decide.md b/.changeset/chilly-jokes-decide.md new file mode 100644 index 000000000000..9a17e469ed1b --- /dev/null +++ b/.changeset/chilly-jokes-decide.md @@ -0,0 +1,29 @@ +--- +"@biomejs/biome": minor +--- + +Added a new assist action `useSortedInterfaceMembers` that sorts TypeScript interface members, for readability. + +It includes an autofix. + +Invalid example. + +```ts,expect_diagnostic +interface MixedMembers { + z: string; + a: number; + (): void; + y: boolean; +} +``` + +Valid example (after using the assist). + +```ts +interface MixedMembers { + a: number; + y: boolean; + z: string; + (): void; +} +``` diff --git a/.changeset/lemon-planes-knock.md b/.changeset/lemon-planes-knock.md deleted file mode 100644 index 9ffecb931fe6..000000000000 --- a/.changeset/lemon-planes-knock.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@biomejs/biome": patch ---- - -Refactored formatter to use strict `Token` element for better performance. The new `Token` variant is optimized for static, ASCII-only text (keywords, operators, punctuation) with the following constraints: - -- ASCII only (no Unicode characters) -- No newlines (`\n`, `\r`) -- No tab characters (`\t`) - -This enables faster printing and fitting logic by using bulk string operations (`push_str`, `len()`) instead of character-by-character iteration with Unicode width calculations. diff --git a/.changeset/mighty-bats-grow.md b/.changeset/mighty-bats-grow.md deleted file mode 100644 index c5ac30992175..000000000000 --- a/.changeset/mighty-bats-grow.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -"@biomejs/biome": patch ---- - -Fixed [#7943](https://github.com/biomejs/biome/issues/7943). Rules' `options` are now properly merged with the inherited `options` from a shared configuration. - -This means that you can now override a specific option from a rule without resetting the other options to their default. - -Given the following shared configuration: - -```json -{ - "linter": { - "rules": { - "style": { - "useNamingConvention": { - "level": "on", - "options": { - "strictCase": false, - "conventions": [{ - "selector": { "kind": "variable", "scope": "global" }, - "formats": ["CONSTANT_CASE"] - }] - } - } - } - } - } -} -``` - -And the user configuration that extends this shared configuration: - -```json -{ - "extends": ["shared.json"], - "linter": { - "rules": { - "style": { - "useNamingConvention": { - "level": "on", - "options": { "strictCase": true } - } - } - } - } -} -``` - -The obtained merged configuration is now as follows: - -```json -{ - "extends": ["shared.json"], - "linter": { - "rules": { - "style": { - "useNamingConvention": { - "level": "on", - "options": { - "strictCase": true, - "conventions": [{ - "selector": { "kind": "variable", "scope": "global" }, - "formats": ["CONSTANT_CASE"] - }] - } - } - } - } - } -} -``` diff --git a/.changeset/nine-bottles-float.md b/.changeset/nine-bottles-float.md deleted file mode 100644 index 794f81fe5504..000000000000 --- a/.changeset/nine-bottles-float.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@biomejs/biome": patch ---- - -Added support for the Svelte syntax `{@debug}`. The Biome HTML parser is now able to parse and format the blocks: - -```diff --{@debug foo,bar, something} -+{@debug foo, bar, something} -``` diff --git a/.changeset/ten-ears-stand.md b/.changeset/ten-ears-stand.md deleted file mode 100644 index a3ad4adb0407..000000000000 --- a/.changeset/ten-ears-stand.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@biomejs/biome": patch ---- - -Fixed [#7854](https://github.com/biomejs/biome/issues/7854): The CSS parser, with `tailwindDirectives` enabled, will now parse `@source inline("underline");`. diff --git a/.changeset/yellow-crews-guess.md b/.changeset/yellow-crews-guess.md deleted file mode 100644 index 17b6ba336fd5..000000000000 --- a/.changeset/yellow-crews-guess.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -"@biomejs/biome": patch ---- - -Added the nursery rule [`noContinue`](https://biomejs.dev/linter/rules/no-continue/). Disallowing the usage of the `continue` statement, structured control flow statements such as `if` should be used instead. - -**Invalid:** -```js -let sum = 0, - i; - -for(i = 0; i < 10; i++) { - if(i >= 5) { - continue; - } - - sum += i; -} -``` - -**Valid:** -```js -let sum = 0, - i; - -for(i = 0; i < 10; i++) { - if(i < 5) { - sum += i; - } -} -``` diff --git a/.coderabbit.yaml b/.coderabbit.yaml index 169f857a436b..f827324d8169 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -24,17 +24,20 @@ reviews: - "!**/backend-jsonrpc/src/workspace.ts" auto_review: enabled: true - base_branches: ["main", "next"] + base_branches: [ "main", "next" ] drafts: false tools: biome: enabled: false # We use our own Biome workflow :) clippy: enabled: false # Same for Clippy + finishing_touches: + docstrings: + enabled: false tone_instructions: "Please keep it short and to the point. Be patient, especially with new contributors. Feel free to be witty with maintainers." knowledge_base: code_guidelines: enabled: true - filePatterns: ["**/CLAUDE.md", "**/CONTRIBUTING.md"] + filePatterns: [ "**/CLAUDE.md", "**/CONTRIBUTING.md" ] chat: auto_reply: false diff --git a/.github/workflows/benchmark_css.yml b/.github/workflows/benchmark_css.yml index c2d63f1762c8..b5410e0ec6c7 100644 --- a/.github/workflows/benchmark_css.yml +++ b/.github/workflows/benchmark_css.yml @@ -13,6 +13,7 @@ on: - 'crates/biome_css_formatter/**/*.rs' - 'crates/biome_css_parser/**/*.rs' - 'crates/biome_css_*/**/*.rs' + - 'crates/biome_formatter/**/*.rs' - 'crates/biome_rowan/**/*.rs' - 'crates/biome_parser/**/*.rs' push: @@ -25,6 +26,7 @@ on: - 'crates/biome_css_formatter/**/*.rs' - 'crates/biome_css_parser/**/*.rs' - 'crates/biome_css_*/**/*.rs' + - 'crates/biome_formatter/**/*.rs' - 'crates/biome_rowan/**/*.rs' - 'crates/biome_parser/**/*.rs' diff --git a/.github/workflows/benchmark_graphql.yml b/.github/workflows/benchmark_graphql.yml index db71151d2ac9..68149bf5dc4c 100644 --- a/.github/workflows/benchmark_graphql.yml +++ b/.github/workflows/benchmark_graphql.yml @@ -12,6 +12,7 @@ on: - 'crates/biome_graphql_formatter/**/*.rs' - 'crates/biome_graphql_parser/**/*.rs' - 'crates/biome_graphql_*/**/*.rs' + - 'crates/biome_formatter/**/*.rs' - 'crates/biome_rowan/**/*.rs' - 'crates/biome_parser/**/*.rs' push: @@ -23,6 +24,7 @@ on: - 'crates/biome_graphql_formatter/**/*.rs' - 'crates/biome_graphql_parser/**/*.rs' - 'crates/biome_graphql_*/**/*.rs' + - 'crates/biome_formatter/**/*.rs' - 'crates/biome_rowan/**/*.rs' - 'crates/biome_parser/**/*.rs' diff --git a/.github/workflows/benchmark_js.yml b/.github/workflows/benchmark_js.yml index 535ca35f3ae9..742d0d460407 100644 --- a/.github/workflows/benchmark_js.yml +++ b/.github/workflows/benchmark_js.yml @@ -13,6 +13,7 @@ on: - 'crates/biome_js_formatter/**/*.rs' - 'crates/biome_js_parser/**/*.rs' - 'crates/biome_js_*/**/*.rs' + - 'crates/biome_formatter/**/*.rs' - 'crates/biome_rowan/**/*.rs' - 'crates/biome_parser/**/*.rs' push: @@ -25,6 +26,7 @@ on: - 'crates/biome_js_formatter/**/*.rs' - 'crates/biome_js_parser/**/*.rs' - 'crates/biome_js_*/**/*.rs' + - 'crates/biome_formatter/**/*.rs' - 'crates/biome_rowan/**/*.rs' - 'crates/biome_parser/**/*.rs' diff --git a/.github/workflows/benchmark_json.yml b/.github/workflows/benchmark_json.yml index ceaec2d8cccd..cad12e309a91 100644 --- a/.github/workflows/benchmark_json.yml +++ b/.github/workflows/benchmark_json.yml @@ -13,6 +13,7 @@ on: - 'crates/biome_json_formatter/**/*.rs' - 'crates/biome_json_parser/**/*.rs' - 'crates/biome_json_*/**/*.rs' + - 'crates/biome_formatter/**/*.rs' - 'crates/biome_rowan/**/*.rs' - 'crates/biome_parser/**/*.rs' push: @@ -25,6 +26,7 @@ on: - 'crates/biome_json_formatter/**/*.rs' - 'crates/biome_json_parser/**/*.rs' - 'crates/biome_json_*/**/*.rs' + - 'crates/biome_formatter/**/*.rs' - 'crates/biome_rowan/**/*.rs' - 'crates/biome_parser/**/*.rs' diff --git a/.github/workflows/benchmark_tailwind.yml b/.github/workflows/benchmark_tailwind.yml new file mode 100644 index 000000000000..5addc443a8e1 --- /dev/null +++ b/.github/workflows/benchmark_tailwind.yml @@ -0,0 +1,69 @@ +name: Benchmarks Tailwind + +on: + workflow_dispatch: + pull_request: + types: [opened, synchronize] + branches: + - main + - next + paths: + - "Cargo.lock" + - "crates/biome_tailwind_parser/**/*.rs" + - "crates/biome_tailwind_*/**/*.rs" + - "crates/biome_rowan/**/*.rs" + - "crates/biome_parser/**/*.rs" + push: + branches: + - main + - next + paths: + - "Cargo.lock" + - "crates/biome_tailwind_parser/**/*.rs" + - "crates/biome_tailwind_*/**/*.rs" + - "crates/biome_rowan/**/*.rs" + - "crates/biome_parser/**/*.rs" + +env: + RUST_LOG: info + +jobs: + bench: + permissions: + contents: read + pull-requests: write + name: Bench + runs-on: depot-ubuntu-24.04-arm-16 + strategy: + matrix: + package: + - biome_tailwind_parser + + steps: + - name: Checkout PR Branch + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} + + - name: Install toolchain + uses: moonrepo/setup-rust@ede6de059f8046a5e236c94046823e2af11ca670 # v1.2.2 + with: + channel: stable + cache-target: release + bins: cargo-codspeed + cache-base: main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Compile + timeout-minutes: 20 + run: cargo codspeed build -p ${{ matrix.package }} + env: + CARGO_BUILD_JOBS: 3 # Default is 4 (equals to the vCPU count of the runner), which leads OOM on cargo build + + - name: Run the benchmarks + uses: CodSpeedHQ/action@76578c2a7ddd928664caa737f0e962e3085d4e7c # v3.8.1 + timeout-minutes: 50 + with: + run: cargo codspeed run + token: ${{ secrets.CODSPEED_TOKEN }} diff --git a/.github/workflows/beta.yml b/.github/workflows/beta.yml index 421bd6f81d26..5d2fa6237d5a 100644 --- a/.github/workflows/beta.yml +++ b/.github/workflows/beta.yml @@ -70,7 +70,7 @@ jobs: sudo apt-get install -y musl-tools - name: Install cargo-audit - uses: taiki-e/install-action@81ee1d48d9194cdcab880cbdc7d36e87d39874cb # v2.62.45 + uses: taiki-e/install-action@537c30d2b45cc3aa3fb35e2bbcfb61ef93fd6f02 # v2.62.52 if: matrix.code-target == 'linux-x64-musl' with: tool: cargo-audit @@ -124,7 +124,7 @@ jobs: name: Package ${{ matrix.code-target }} runs-on: ${{ matrix.os }} container: - image: rust:1.89.0-bullseye@sha256:8f72d971a31b278cebdb2eb64a44c3900ff27c716a4ef6f4db05946d10c9ae4e + image: rust:1.91.1-bullseye@sha256:8d9b5e80062dcdb7f037b4eef92a6649632034d6811652e028706ea93db64159 env: version: ${{ needs.version.outputs.version }} @@ -220,7 +220,7 @@ jobs: - name: Install Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 20.19.5 + node-version: 24.11.1 registry-url: 'https://registry.npmjs.org' - name: Pin Corepack 0.20 @@ -241,14 +241,12 @@ jobs: run: | for package in packages/@biomejs/*; do if [ $package != "packages/@biomejs/js-api" ] && [ $package != "packages/@biomejs/plugin-api" ]; then - npm publish $package --tag beta --access public --provenance + npm publish $package --tag beta --access public fi done - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Create GitHub release and tag - uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1 + uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/.github/workflows/beta_js_api.yml b/.github/workflows/beta_js_api.yml index 4c87d9978ffb..ec6fde088a31 100644 --- a/.github/workflows/beta_js_api.yml +++ b/.github/workflows/beta_js_api.yml @@ -40,7 +40,7 @@ jobs: - name: Install Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 20.19.5 + node-version: 24.11.1 - name: Install wasm-pack run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh @@ -98,19 +98,17 @@ jobs: - name: Install Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 20.19.5 + node-version: 24.11.1 registry-url: 'https://registry.npmjs.org' - name: Set beta version run: node packages/@biomejs/js-api/scripts/update-beta-version.mjs - name: Publish npm package as beta - run: npm publish packages/@biomejs/js-api --tag beta --access public --provenance - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: npm publish packages/@biomejs/js-api --tag beta --access public - name: Create GitHub release and tag - uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1 + uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/.github/workflows/close-issue.yml b/.github/workflows/close-issue.yml index a3d62a75b943..b29f739ae6bd 100644 --- a/.github/workflows/close-issue.yml +++ b/.github/workflows/close-issue.yml @@ -14,7 +14,7 @@ jobs: runs-on: depot-ubuntu-24.04-arm-small steps: - name: Close issue without reproduction - uses: actions-cool/issues-helper@ca1b238fecb728f25584d2beb288d7f1727f9fa6 # v3.7.0 + uses: actions-cool/issues-helper@9861779a695cf1898bd984c727f685f351cfc372 # v3.7.2 with: actions: "close-issues" token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/needs-repro.yml b/.github/workflows/needs-repro.yml index 04d4c3ffc39d..bfd618c635e2 100644 --- a/.github/workflows/needs-repro.yml +++ b/.github/workflows/needs-repro.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Remove triaging label if: contains(github.event.issue.labels.*.name, 'S-Bug-confirmed') && contains(github.event.issue.labels.*.name, 'S-Needs triage') - uses: actions-cool/issues-helper@ca1b238fecb728f25584d2beb288d7f1727f9fa6 # v3.7.0 + uses: actions-cool/issues-helper@9861779a695cf1898bd984c727f685f351cfc372 # v3.7.2 with: actions: "remove-labels" token: ${{ secrets.GITHUB_TOKEN }} @@ -23,7 +23,7 @@ jobs: - name: Needs reproduction if: github.event.label.name == 'S-Needs repro' - uses: actions-cool/issues-helper@ca1b238fecb728f25584d2beb288d7f1727f9fa6 # v3.7.0 + uses: actions-cool/issues-helper@9861779a695cf1898bd984c727f685f351cfc372 # v3.7.2 with: actions: "create-comment, remove-labels" token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 287b6a138584..add5e3611294 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -62,7 +62,7 @@ jobs: sudo apt-get install -y musl-tools - name: Install cargo-audit - uses: taiki-e/install-action@81ee1d48d9194cdcab880cbdc7d36e87d39874cb # v2.62.45 + uses: taiki-e/install-action@537c30d2b45cc3aa3fb35e2bbcfb61ef93fd6f02 # v2.62.52 if: matrix.code-target == 'linux-x64-musl' with: tool: cargo-audit @@ -116,7 +116,7 @@ jobs: name: Package ${{ matrix.code-target }} runs-on: ${{ matrix.os }} container: - image: rust:1.89.0-bullseye@sha256:8f72d971a31b278cebdb2eb64a44c3900ff27c716a4ef6f4db05946d10c9ae4e + image: rust:1.91.1-bullseye@sha256:8d9b5e80062dcdb7f037b4eef92a6649632034d6811652e028706ea93db64159 steps: - name: Checkout repository @@ -206,7 +206,7 @@ jobs: - name: Install Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 20.19.5 + node-version: 24.11.1 registry-url: 'https://registry.npmjs.org' - name: Pin Corepack 0.20 diff --git a/.github/workflows/pull_request_markdown.yml b/.github/workflows/pull_request_markdown.yml index e5091fd583fc..755e62c6f349 100644 --- a/.github/workflows/pull_request_markdown.yml +++ b/.github/workflows/pull_request_markdown.yml @@ -11,8 +11,8 @@ jobs: lint: runs-on: depot-ubuntu-24.04-arm steps: - - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - - uses: DavidAnson/markdownlint-cli2-action@451cad2cde7304d9c243aaaf2e894d74b428c4be + - uses: actions/checkout@71cf2267d89c5cb81562390fa70a37fa40b1305e + - uses: DavidAnson/markdownlint-cli2-action@30a0e04f1870d58f8d717450cc6134995f993c63 with: globs: | **/*.md diff --git a/.github/workflows/pull_request_node.yml b/.github/workflows/pull_request_node.yml index 3ef7372b8f20..59ab24d0258b 100644 --- a/.github/workflows/pull_request_node.yml +++ b/.github/workflows/pull_request_node.yml @@ -42,7 +42,7 @@ jobs: - name: Install Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 20.19.5 + node-version: 24.11.1 - name: Cache pnpm modules uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bbd648ad9b65..05aa5594dd30 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,10 +28,10 @@ jobs: - name: Checkout Repo uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - - name: Setup Node.js 22.x + - name: Install Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 22.21.1 + node-version: 24.11.1 - name: Install pnpm run: | @@ -83,10 +83,10 @@ jobs: - name: Checkout Repo uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - - name: Setup Node.js 22.x + - name: Install Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 22.21.1 + node-version: 24.11.1 - name: Check CLI version changes id: cli-version-changed @@ -146,7 +146,7 @@ jobs: sudo apt-get install -y musl-tools - name: Install cargo-audit - uses: taiki-e/install-action@81ee1d48d9194cdcab880cbdc7d36e87d39874cb # v2.62.45 + uses: taiki-e/install-action@537c30d2b45cc3aa3fb35e2bbcfb61ef93fd6f02 # v2.62.52 if: matrix.code-target == 'linux-x64-musl' with: tool: cargo-audit @@ -203,7 +203,7 @@ jobs: name: Package ${{ matrix.code-target }} runs-on: ${{ matrix.os }} container: - image: rust:1.89.0-bullseye@sha256:8f72d971a31b278cebdb2eb64a44c3900ff27c716a4ef6f4db05946d10c9ae4e + image: rust:1.91.1-bullseye@sha256:8d9b5e80062dcdb7f037b4eef92a6649632034d6811652e028706ea93db64159 steps: - name: Checkout repository @@ -280,7 +280,7 @@ jobs: - name: Install Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 20.19.5 + node-version: 24.11.1 - name: Install wasm-pack run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh @@ -345,8 +345,8 @@ jobs: - name: Install Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 20.19.5 - registry-url: "https://registry.npmjs.org" + node-version: 24.11.1 + registry-url: 'https://registry.npmjs.org' - name: Install pnpm run: | @@ -368,16 +368,14 @@ jobs: run: node packages/@biomejs/biome/scripts/generate-packages.mjs - name: Publish npm packages as latest - run: for package in packages/@biomejs/*; do if [ $package != "packages/@biomejs/js-api" ] && [ $package != "packages/@biomejs/plugin-api" ]; then npm publish $package --tag latest --access public --provenance; fi; done - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: for package in packages/@biomejs/*; do if [ $package != "packages/@biomejs/js-api" ] && [ $package != "packages/@biomejs/plugin-api" ]; then npm publish $package --tag latest --access public; fi; done - name: Publish release for @biomejs/biome run: | bash scripts/print-changelog.sh ${{ needs.build-binaries.outputs.version }} >| ${{ github.workspace }}/RELEASE_NOTES - name: Create GitHub @biomejs/biome release and tag - uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1 + uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -428,8 +426,8 @@ jobs: - name: Install Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 20.19.5 - registry-url: "https://registry.npmjs.org" + node-version: 24.11.1 + registry-url: 'https://registry.npmjs.org' - name: Install pnpm run: | @@ -442,15 +440,13 @@ jobs: - name: Publish npm package as latest run: pnpm publish packages/@biomejs/js-api --no-git-checks --tag latest --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Publish release for @biomejs/js-api run: | bash scripts/print-changelog.sh ${{ needs.build-js-api.outputs.version }} packages/@biomejs/js-api/CHANGELOG.md >| ${{ github.workspace }}/JS_RELEASE_NOTES - name: Create GitHub @biomejs/js-api release and tag - uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1 + uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/.github/workflows/release_cli.yml b/.github/workflows/release_cli.yml index 6b2b934dbfc8..0ae8fd10b78c 100644 --- a/.github/workflows/release_cli.yml +++ b/.github/workflows/release_cli.yml @@ -87,7 +87,7 @@ jobs: sudo apt-get install -y musl-tools - name: Install cargo-audit - uses: taiki-e/install-action@81ee1d48d9194cdcab880cbdc7d36e87d39874cb # v2.62.45 + uses: taiki-e/install-action@537c30d2b45cc3aa3fb35e2bbcfb61ef93fd6f02 # v2.62.52 if: matrix.code-target == 'linux-x64-musl' with: tool: cargo-audit @@ -237,7 +237,7 @@ jobs: - name: Install Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 20.19.5 + node-version: 24.11.1 registry-url: 'https://registry.npmjs.org' - name: Set release infos @@ -247,21 +247,17 @@ jobs: run: node packages/@biomejs/biome/scripts/generate-packages.mjs - name: Publish npm packages as latest - run: for package in packages/@biomejs/*; do if [ $package != "packages/@biomejs/js-api" ] && [ $package != "packages/@biomejs/plugin-api" ]; then npm publish $package --tag latest --access public --provenance; fi; done + run: for package in packages/@biomejs/*; do if [ $package != "packages/@biomejs/js-api" ] && [ $package != "packages/@biomejs/plugin-api" ]; then npm publish $package --tag latest --access public; fi; done if: needs.build.outputs.prerelease != 'true' - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Publish npm packages as nightly - run: for package in packages/@biomejs/*; do if [ $package != "packages/@biomejs/js-api" ] && [ $package != "packages/@biomejs/plugin-api" ]; then npm publish $package --tag nightly --access public --provenance; fi; done + run: for package in packages/@biomejs/*; do if [ $package != "packages/@biomejs/js-api" ] && [ $package != "packages/@biomejs/plugin-api" ]; then npm publish $package --tag nightly --access public; fi; done if: needs.build.outputs.prerelease == 'true' - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Extract changelog run: | bash scripts/print-changelog.sh ${{ needs.build.outputs.version }} >| ${{ github.workspace }}/RELEASE_NOTES - name: Create GitHub release and tag - uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1 + uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/.github/workflows/release_js_api.yml b/.github/workflows/release_js_api.yml index 8a5045038aea..0a2c1aecdd27 100644 --- a/.github/workflows/release_js_api.yml +++ b/.github/workflows/release_js_api.yml @@ -57,7 +57,7 @@ jobs: - name: Install Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 20.19.5 + node-version: 24.11.1 - name: Install wasm-pack run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh @@ -123,7 +123,7 @@ jobs: - name: Install Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 20.19.5 + node-version: 24.11.1 registry-url: 'https://registry.npmjs.org' - name: Set release infos @@ -131,21 +131,18 @@ jobs: run: node packages/@biomejs/js-api/scripts/update-nightly-version.mjs - name: Publish npm package as latest - run: npm publish packages/@biomejs/js-api --tag latest --access public --provenance + run: npm publish packages/@biomejs/js-api --tag latest --access public if: needs.build.outputs.prerelease != 'true' - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Publish npm package as nightly - run: npm publish packages/@biomejs/js-api --tag nightly --access public --provenance + run: npm publish packages/@biomejs/js-api --tag nightly --access public if: needs.build.outputs.prerelease == 'true' - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Extract changelog run: | bash scripts/print-changelog.sh ${{ needs.build.outputs.version }} >| ${{ github.workspace }}/RELEASE_NOTES - name: Create GitHub release and tag - uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1 + uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/.github/workflows/repository_dispatch.yml b/.github/workflows/repository_dispatch.yml index 4e610e1e3e99..885655cc7bbb 100644 --- a/.github/workflows/repository_dispatch.yml +++ b/.github/workflows/repository_dispatch.yml @@ -67,7 +67,7 @@ jobs: - name: Setup node uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 20.19.5 + node-version: 24.11.1 cache: pnpm - name: Update package.json diff --git a/Cargo.lock b/Cargo.lock index edfd28a12987..f8b34c9e720c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,9 +70,9 @@ checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "append-only-vec" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7992085ec035cfe96992dd31bfd495a2ebd31969bb95f624471cb6c0b349e571" +checksum = "2114736faba96bcd79595c700d03183f61357b9fbce14852515e59f3bee4ed4a" [[package]] name = "approx" @@ -91,9 +91,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "ascii_table" -version = "4.0.7" +version = "4.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3cd3541590f14025990035bb02b205870f8ca3f5297956dd2c6b32e6470fa1" +checksum = "f4ef8ee0b4eedc5a877a8a768fecfabbe4c8b9791e17763225139a858dabd8e7" [[package]] name = "autocfg" @@ -113,7 +113,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -131,26 +131,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bindgen" -version = "0.72.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" -dependencies = [ - "bitflags 2.9.3", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 2.1.1", - "shlex", - "syn 2.0.106", -] - [[package]] name = "biome_analyze" version = "0.5.7" @@ -488,6 +468,7 @@ dependencies = [ "quote", "schemars", "serde", + "serde_json", ] [[package]] @@ -605,6 +586,7 @@ dependencies = [ "camino", "insta", "jiff", + "rustc-hash 2.1.1", "schemars", "serde", "tests_macros", @@ -794,6 +776,7 @@ dependencies = [ "biome_html_parser", "biome_html_syntax", "biome_rowan", + "biome_rule_options", "biome_string_case", "biome_suppression", "biome_test_utils", @@ -1441,7 +1424,7 @@ dependencies = [ "rustc-hash 2.1.1", "schemars", "serde", - "windows", + "windows 0.62.2", ] [[package]] @@ -1505,6 +1488,7 @@ dependencies = [ "rustc-hash 2.1.1", "schemars", "serde", + "serde_json", "smallvec", ] @@ -1580,6 +1564,7 @@ dependencies = [ "bpaf", "camino", "crossbeam", + "either", "enumflags2", "getrandom 0.2.15", "ignore", @@ -1646,11 +1631,13 @@ dependencies = [ "biome_test_utils", "biome_unicode_table", "camino", + "codspeed-criterion-compat", "insta", "mimalloc", "quickcheck", "quickcheck_macros", "tests_macros", + "tikv-jemallocator", "tracing", ] @@ -1740,6 +1727,7 @@ dependencies = [ "schemars", "serde", "serde-wasm-bindgen", + "serde_json", "wasm-bindgen", ] @@ -2064,15 +2052,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - [[package]] name = "cfg-if" version = "1.0.4" @@ -2087,9 +2066,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ "num-traits", ] @@ -2121,17 +2100,6 @@ dependencies = [ "half", ] -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - [[package]] name = "clap" version = "4.4.0" @@ -2178,21 +2146,20 @@ dependencies = [ [[package]] name = "codspeed" -version = "4.0.4" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f62ea8934802f8b374bf691eea524c3aa444d7014f604dd4182a3667b69510" +checksum = "c3b847e05a34be5c38f3f2a5052178a3bd32e6b5702f3ea775efde95c483a539" dependencies = [ "anyhow", - "bindgen", "cc", "colored 2.2.0", + "getrandom 0.2.15", "glob", "libc", "nix 0.30.1", "serde", "serde_json", "statrs", - "uuid", ] [[package]] @@ -2235,12 +2202,12 @@ dependencies = [ [[package]] name = "codspeed-divan-compat" -version = "4.0.4" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b4214b974f8f5206497153e89db90274e623f06b00bf4b9143eeb7735d975d" +checksum = "f0f0e9fe5eaa39995ec35e46407f7154346cc25bd1300c64c21636f3d00cb2cc" dependencies = [ "clap", - "codspeed 4.0.4", + "codspeed 4.1.0", "codspeed-divan-compat-macros", "codspeed-divan-compat-walltime", "regex", @@ -2248,9 +2215,9 @@ dependencies = [ [[package]] name = "codspeed-divan-compat-macros" -version = "4.0.4" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a53f34a16cb70ce4fd9ad57e1db016f0718e434f34179ca652006443b9a39967" +checksum = "88c8babf2a40fd2206a2e030cf020d0d58144cd56e1dc408bfba02cdefb08b4f" dependencies = [ "divan-macros", "itertools 0.14.0", @@ -2262,13 +2229,13 @@ dependencies = [ [[package]] name = "codspeed-divan-compat-walltime" -version = "4.0.4" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a5099050c8948dce488b8eaa2e68dc5cf571cb8f9fce99aaaecbdddb940bcd" +checksum = "7f26092328e12a36704ffc552f379c6405dd94d3149970b79b22d371717c2aae" dependencies = [ "cfg-if", "clap", - "codspeed 4.0.4", + "codspeed 4.1.0", "condtype", "divan-macros", "libc", @@ -2321,7 +2288,7 @@ dependencies = [ "encode_unicode 1.0.0", "libc", "once_cell", - "unicode-width 0.2.0", + "unicode-width 0.2.2", "windows-sys 0.60.2", ] @@ -2643,9 +2610,9 @@ checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" [[package]] name = "dyn-clone" -version = "1.0.11" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "dynify" @@ -2669,9 +2636,9 @@ dependencies = [ [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "elsa" @@ -2991,16 +2958,15 @@ dependencies = [ [[package]] name = "generator" -version = "0.8.7" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2" +checksum = "cc6bd114ceda131d3b1d665eba35788690ad37f5916457286b32ab6fd3c438dd" dependencies = [ - "cc", "cfg-if", "libc", "log", "rustversion", - "windows", + "windows 0.58.0", ] [[package]] @@ -3432,20 +3398,18 @@ checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", "hashbrown 0.16.0", - "serde", - "serde_core", ] [[package]] name = "indicatif" -version = "0.18.0" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a646d946d06bedbbc4cac4c218acf4bbf2d87757a784857025f4d447e4e1cd" +checksum = "9375e112e4b463ec1b1c6c011953545c65a30164fbab5b581df32b3abf0dcb88" dependencies = [ "console 0.16.0", "portable-atomic", "unicode-segmentation", - "unicode-width 0.2.0", + "unicode-width 0.2.2", "unit-prefix", "web-time", ] @@ -3529,15 +3493,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.14.0" @@ -3555,24 +3510,24 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" dependencies = [ "jiff-static", "jiff-tzdb-platform", "log", "portable-atomic", "portable-atomic-util", - "serde", - "windows-sys 0.59.0", + "serde_core", + "windows-sys 0.61.2", ] [[package]] name = "jiff-static" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" dependencies = [ "proc-macro2", "quote", @@ -3605,9 +3560,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.81" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" +checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" dependencies = [ "once_cell", "wasm-bindgen", @@ -3663,16 +3618,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "libloading" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" -dependencies = [ - "cfg-if", - "windows-link 0.2.1", -] - [[package]] name = "libmimalloc-sys" version = "0.1.44" @@ -3809,12 +3754,6 @@ dependencies = [ "libmimalloc-sys", ] -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.8.0" @@ -3839,9 +3778,9 @@ dependencies = [ [[package]] name = "newtype-uuid" -version = "1.1.3" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8781e2ef64806278a55ad223f0bc875772fd40e1fe6e73e8adbf027817229d" +checksum = "5c012d14ef788ab066a347d19e3dda699916c92293b05b85ba2c76b8c82d2830" dependencies = [ "uuid", ] @@ -3870,16 +3809,6 @@ dependencies = [ "libc", ] -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "notify" version = "8.2.0" @@ -4049,7 +3978,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -4302,9 +4231,9 @@ checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae" [[package]] name = "quick-junit" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed1a693391a16317257103ad06a88c6529ac640846021da7c435a06fffdacd7" +checksum = "6ee9342d671fae8d66b3ae9fd7a9714dfd089c04d2a8b1ec0436ef77aee15e5f" dependencies = [ "chrono", "indexmap", @@ -4317,9 +4246,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.37.1" +version = "0.38.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f22f29bdff3987b4d8632ef95fd6424ec7e4e0a57e2f4fc63e489e75357f6a03" +checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" dependencies = [ "memchr", ] @@ -4348,9 +4277,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.41" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -4466,6 +4395,26 @@ dependencies = [ "thiserror 2.0.17", ] +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "regex" version = "1.12.2" @@ -4658,15 +4607,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "rustls-pki-types" version = "1.11.0" @@ -4713,12 +4653,13 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.22" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289" dependencies = [ "dyn-clone", "indexmap", + "ref-cast", "schemars_derive", "serde", "serde_json", @@ -4727,9 +4668,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.22" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" +checksum = "301858a4023d78debd2353c7426dc486001bddc91ae31a76fb1f55132f7e2633" dependencies = [ "proc-macro2", "quote", @@ -4817,9 +4758,9 @@ dependencies = [ [[package]] name = "serde_derive_internals" -version = "0.29.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", @@ -5004,9 +4945,9 @@ dependencies = [ [[package]] name = "strip-ansi-escapes" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ff8ef943b384c414f54aefa961dd2bd853add74ec75e7ac74cf91dba62bcfa" +checksum = "2a8f8038e7e7969abb3f1b7c2a811225e9296da208539e0f79c5251d6cac0025" dependencies = [ "vte", ] @@ -5086,9 +5027,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-triple" -version = "0.1.3" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a4d50cdb458045afc8131fd91b64904da29548bcb63c7236e0844936c13078" +checksum = "591ef38edfb78ca4771ee32cf494cb8771944bee237a9b91fc9c1424ac4b777b" [[package]] name = "termcolor" @@ -5517,9 +5458,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.111" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ded9fdb81f30a5708920310bfcd9ea7482ff9cba5f54601f7a19a877d5c2392" +checksum = "3e17e807bff86d2a06b52bca4276746584a78375055b6e45843925ce2802b335" dependencies = [ "glob", "serde", @@ -5565,9 +5506,9 @@ checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" [[package]] name = "unicode-width" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unit-prefix" @@ -5589,9 +5530,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "3.1.2" +version = "3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ba1025f18a4a3fc3e9b48c868e9beb4f24f4b4b1a325bada26bd4119f46537" +checksum = "d39cb1dbab692d82a977c0392ffac19e188bd9186a9f32806f0aaa859d75585a" dependencies = [ "base64", "cookie_store", @@ -5599,7 +5540,6 @@ dependencies = [ "log", "percent-encoding", "rustls", - "rustls-pemfile", "rustls-pki-types", "serde", "serde_json", @@ -5650,12 +5590,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - [[package]] name = "uuid" version = "1.18.1" @@ -5687,22 +5621,11 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "vte" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197" -dependencies = [ - "utf8parse", - "vte_generate_state_changes", -] - -[[package]] -name = "vte_generate_state_changes" -version = "0.1.1" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" +checksum = "231fdcd7ef3037e8330d8e17e61011a2c244126acc0a982f4040ac3f9f0bc077" dependencies = [ - "proc-macro2", - "quote", + "memchr", ] [[package]] @@ -5732,9 +5655,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.104" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" +checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" dependencies = [ "cfg-if", "once_cell", @@ -5745,25 +5668,11 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.106", - "wasm-bindgen-shared", -] - [[package]] name = "wasm-bindgen-macro" -version = "0.2.104" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" +checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5771,22 +5680,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.104" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" +checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn 2.0.106", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.104" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" +checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" dependencies = [ "unicode-ident", ] @@ -5853,55 +5762,88 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.61.3" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" dependencies = [ "windows-collections", - "windows-core", + "windows-core 0.62.2", "windows-future", - "windows-link 0.1.3", "windows-numerics", ] [[package]] name = "windows-collections" -version = "0.2.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" dependencies = [ - "windows-core", + "windows-core 0.62.2", ] [[package]] name = "windows-core" -version = "0.61.2" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ - "windows-implement", - "windows-interface", - "windows-link 0.1.3", - "windows-result", - "windows-strings", + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement 0.60.2", + "windows-interface 0.59.3", + "windows-link", + "windows-result 0.4.1", + "windows-strings 0.5.1", ] [[package]] name = "windows-future" -version = "0.2.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" dependencies = [ - "windows-core", - "windows-link 0.1.3", + "windows-core 0.62.2", + "windows-link", "windows-threading", ] [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -5910,9 +5852,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", @@ -5920,10 +5862,15 @@ dependencies = [ ] [[package]] -name = "windows-link" -version = "0.1.3" +name = "windows-interface" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] [[package]] name = "windows-link" @@ -5933,30 +5880,49 @@ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-numerics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core 0.62.2", + "windows-link", +] + +[[package]] +name = "windows-result" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "windows-core", - "windows-link 0.1.3", + "windows-targets 0.52.6", ] [[package]] name = "windows-result" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link 0.1.3", + "windows-link", ] [[package]] name = "windows-strings" -version = "0.4.2" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows-link 0.1.3", + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", ] [[package]] @@ -6025,7 +5991,7 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -6092,11 +6058,11 @@ dependencies = [ [[package]] name = "windows-threading" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" dependencies = [ - "windows-link 0.1.3", + "windows-link", ] [[package]] @@ -6330,13 +6296,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0637d3a5566a82fa5214bae89087bc8c9fb94cd8e8a3c07feb691bb8d9c632db" -[[package]] -name = "xtask" -version = "0.0.0" -dependencies = [ - "anyhow", -] - [[package]] name = "xtask_codegen" version = "0.0.0" @@ -6376,7 +6335,7 @@ dependencies = [ "serde", "serde_json", "ureq", - "xtask", + "xtask_glue", ] [[package]] @@ -6404,10 +6363,17 @@ dependencies = [ "tracing", "tracing-subscriber", "walkdir", - "xtask", + "xtask_glue", "yastl", ] +[[package]] +name = "xtask_glue" +version = "0.0.0" +dependencies = [ + "anyhow", +] + [[package]] name = "yastl" version = "0.1.2" diff --git a/Cargo.toml b/Cargo.toml index b68e7f125cf4..cff6542a9348 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,16 +1,24 @@ [workspace] # Use the newer version of the cargo resolver # https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions -members = ["crates/*", "xtask/codegen", "xtask/coverage", "xtask/rules_check"] +members = ["crates/*", "xtask/glue", "xtask/codegen", "xtask/coverage", "xtask/rules_check"] resolver = "2" [workspace.lints.rust] -absolute_paths_not_starting_with_crate = "warn" -dead_code = "warn" -trivial_numeric_casts = "warn" -unused_import_braces = "warn" -unused_lifetimes = "warn" -unused_macro_rules = "warn" +# https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html +ambiguous-negative-literals = "warn" +dead_code = "warn" +explicit-outlives-requirements = "warn" +impl-trait-overcaptures = "warn" +impl-trait-redundant-captures = "warn" +missing-unsafe-on-extern = "warn" +redundant-lifetimes = "warn" +trivial_numeric_casts = "warn" +unit-bindings = "warn" +unsafe-attr-outside-unsafe = "warn" +unused_import_braces = "warn" +unused_lifetimes = "warn" +unused_macro_rules = "warn" [workspace.lints.clippy] allow_attributes = "deny" @@ -188,6 +196,9 @@ biome_ruledoc_utils = { path = "./crates/biome_ruledoc_utils" } biome_service = { path = "./crates/biome_service" } biome_test_utils = { path = "./crates/biome_test_utils" } tests_macros = { path = "./crates/tests_macros" } +xtask_codegen = { path = "xtask/codegen" } +xtask_coverage = { path = "xtask/coverage" } +xtask_glue = { path = "xtask/glue" } # Crates needed in the workspace anyhow = "1.0.100" @@ -199,6 +210,7 @@ countme = "3.0.1" crossbeam = "0.8.4" dashmap = "6.1.0" dirs = "6.0.0" +either = "1.15.0" enumflags2 = "0.7.12" getrandom = "0.2.15" globset = "0.4.18" @@ -208,7 +220,7 @@ hashbrown = { version = "0.15.5", default-features = false } ignore = "0.4.25" indexmap = { version = "2.12.0" } insta = "1.43.2" -jiff = "0.2.15" +jiff = "0.2.16" libc = "0.2.177" mimalloc = "0.1.48" papaya = "0.2.3" @@ -217,12 +229,12 @@ proc-macro-error2 = { version = "2.0.1", default-features = false } proc-macro2 = "1.0.103" quickcheck = "1.0.3" quickcheck_macros = "1.1.0" -quote = "1.0.41" +quote = "1.0.42" rayon = "1.11.0" regex = "1.12.2" rust-lapper = "1.2.0" rustc-hash = "2.1.1" -schemars = { version = "0.8.22", features = ["indexmap2", "smallvec"] } +schemars = { version = "1.1.0", features = ["indexmap2", "smallvec1"] } serde = { version = "1.0.228", features = ["derive"] } serde_json = "1.0.145" similar = "2.7.0" @@ -239,12 +251,12 @@ tracing = { version = "0.1.41", default-features = false, features tracing-subscriber = "0.3.20" unicode-bom = "2.0.3" unicode-width = "0.1.12" -ureq = "3.1.2" +ureq = "3.1.4" url = "2.5.7" uuid = "1.18.1" walkdir = "2.5.0" web-time = "1.1.0" -windows = "0.61.3" +windows = "0.62.2" [profile.dev.package.biome_wasm] debug = true diff --git a/Dockerfile.benchmark b/Dockerfile.benchmark index 598db515fc55..d25b81b4ca8d 100644 --- a/Dockerfile.benchmark +++ b/Dockerfile.benchmark @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1@sha256:b6afd42430b15f2d2a4c5a02b919e98a525b785b1aaff16747d2f623364e39b6 -FROM rust:1.89.0-bookworm@sha256:948f9b08a66e7fe01b03a98ef1c7568292e07ec2e4fe90d88c07bb14563c84ff +FROM rust:1.91.1-bookworm@sha256:af8fc166ddc0b7aa469f695dbb57c6f859dd440162dab6130d7e4714cbbf8dca WORKDIR /usr/src/ # https://github.com/nodesource/distributions diff --git a/RELEASES.md b/RELEASES.md index da7ee4618a1b..1feffeac4b7e 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -2,13 +2,13 @@ This document is meant to explain the release process of Biome, and hopefully answer some questions. -The team doesn't provide ETAs (Estimated Time of Arrival). The team believes that enforcing deadlines to a group of volunteers is counterproductive, and can have negative effects on people. +The team doesn't provide ETAs (Estimated Time of Arrival). The team believes that enforcing deadlines for a group of volunteers is counterproductive, and can have negative effects on people. ## `npm` packages ### Prerelease -We publish pre-releases of the main `@biomejs/biome` package twice a week. These releases are built from `main`, they are meant for testing and verify that bugs are fixed. +We publish pre-releases of the main `@biomejs/biome` package twice a week. These releases are built from `main`, they are meant for testing and verifying that bugs are fixed. These releases are published to `pkg.pr.new`, and an automated message is sent on [Discord](https://biomejs.dev/chat), in the `#release` channel. @@ -17,7 +17,7 @@ These releases are published to `pkg.pr.new`, and an automated message is sent o ### Beta release -Beta releases are published manually by the [Core Contributors team](/GOVERNANCE.md#core-contributor), only this team has the rights to publish these releases. +Beta releases are published manually by the [Core Contributors team](/GOVERNANCE.md#core-contributor), only this team has the right to publish these releases. These releases can be released on request, usually right before a stable release. @@ -25,7 +25,7 @@ Beta releases are published on GitHub, and `npmjs.org` under the `beta` tag. ### Stable release -Beta releases are published manually by the [Core Contributors team](/GOVERNANCE.md#core-contributor), only this team has the rights to publish these releases. +Stable releases are published manually by the [Core Contributors team](/GOVERNANCE.md#core-contributor), only this team has the right to publish these releases. Stable releases are published on GitHub, and `npmjs.org` under the `latest` tag. @@ -37,4 +37,4 @@ You can reach us out on [discord](https://biomejs.dev/chat) if you require a ver As for now, no changelogs or tags are published when new crates are released. -All Biome crates are published under a one single version. +All Biome crates are published under a single version. diff --git a/ROME_CHANGELOG.md b/ROME_CHANGELOG.md index 6e3d8d7d37d1..5a775985cc5a 100644 --- a/ROME_CHANGELOG.md +++ b/ROME_CHANGELOG.md @@ -1,7 +1,7 @@ # Rome changelog Biome is a fork of [Rome Tools](https://github.com/rome/tools). -This CHANGELOG describes all released of Rome Tools. +This CHANGELOG describes all releases of Rome Tools. All releases of Biome are described in its own [CHANGELOG](./CHANGELOG.md). @@ -85,14 +85,14 @@ the correct rules to apply [#4502](https://github.com/rome/tools/issues/4502) #### Other changes -- Refactored the underling argument parsing logic. Changed the look and feel of the help +- Refactored the underlying argument parsing logic. Changed the look and feel of the help output. [#4405](https://github.com/rome/tools/pull/4405). - The command `rome check` can accept input from `stdin`. - Add the argument `--stdin-file-path` to use when running `rome check` via `stdin`. - Add the argument `--formatter-enabled` to the command `rome check` to control the formatter via CLI. - Add the argument `--linter-enabled` to the command `rome check` to control the linter via CLI. - Add the argument `--organize-imports-enabled` to the command `rome check` to control the import sorting via CLI. -- Add new command `rome migrate` the transform the configuration file `rome.json` +- Add a new command `rome migrate` the transform the configuration file `rome.json` when there are breaking changes. ### Configuration @@ -108,14 +108,14 @@ output. [#4405](https://github.com/rome/tools/pull/4405). #### Other changes - Fix an issue where the VSCode extension duplicates text when using VSCode git utilities [#4338](https://github.com/rome/tools/issues/4338) -- Remove code assists from being added to the code actions when apply fixes; +- Remove code assists from being added to the code actions when applying fixes; - When requesting code actions, ignored files should not throw errors. Fixes [#4434](https://github.com/rome/tools/issues/4434) ### Formatter #### Other changes -- Fix an issue where formatting of JSX string literals property values were using incorrect quotes [#4054](https://github.com/rome/tools/issues/4054) +- Fix an issue where formatting of JSX string literals property values was using incorrect quotes [#4054](https://github.com/rome/tools/issues/4054) - Changed import assertion grammar to the new import attribute assertion ```diff - import "module" assert {} @@ -241,9 +241,9 @@ if there are still diagnostics to be addressed. - `rome check` now checks import statements. This is an experimental feature that needs to be enabled via configuration. Import can be sorted using `rome check --apply-unsafe` -- Rome is able to auto discover the configuration file. If Rome doesn't fine a configuration in the +- Rome is able to auto discover the configuration file. If Rome doesn't find a configuration in the working directory, it will try to find one in the parent directories. -- Add a new global options called `--config-path`. It tells Rome to try and discover a `rome.json` file +- Add a new global option called `--config-path`. It tells Rome to try and discover a `rome.json` file in the given path. ```shell rome format --config-path=../../other/path/ @@ -509,7 +509,7 @@ Please give them a try by manually enabling them in your configuration and pleas - The concept of `backend` has been removed, in favor of the concept of `distribution`. - Removed the possibility to connect to the daemon, for the time being. -- The APIs are asynchronous anymore. +- The APIs are asynchronous now. #### Other changes @@ -548,7 +548,7 @@ Please give them a try by manually enabling them in your configuration and pleas - Added a new argument `--linter-enabled` to the command `rome ci`. - Added the new `format` option `--trailing-comma` to configure where to add trailing commas. - Correctly show the supported options for `rome ci`, closes [#3456](https://github.com/rome/tools/issues/3456). -- Fixed the command `rome ci` command to run the linter even if the formatter is disabled, closes [#3495](https://github.com/rome/tools/issues/3495). +- Fixed the `rome ci` command to run the linter even if the formatter is disabled, closes [#3495](https://github.com/rome/tools/issues/3495). - Fixed the messaging of some diagnostics, [#3460](https://github.com/rome/tools/pull/3460). ### Configuration @@ -565,7 +565,7 @@ Please give them a try by manually enabling them in your configuration and pleas - Added the new trailing comma option that configures where to add trailing commas. Supports the values: `all`, `es5` and `none`; refer to the [documentation](https://rome.tools/docs/#javascriptformattertrailingcomma) to learn more. - Improved JSX formatting [#3499](https://github.com/rome/tools/issues/3499), [#3211](https://github.com/rome/tools/issues/3211), [#3377](https://github.com/rome/tools/issues/3377) -- Better formatting of object destructing +- Better formatting of object destructuring - Improved formatting of test calls - Fixed formatting of trailing comments in arrow functions @@ -829,7 +829,7 @@ configuration file `rome.json` to change the Rome's defaults. ### Formatter -- JSX and TSX are now formatted by default! Make sure to enable Rome as default formatter in the VSCode extension. +- JSX and TSX are now formatted by default! Make sure to enable Rome as the default formatter in the VSCode extension. - Improved the consistency of formatting of various statements: - call arguments; - object property members; @@ -858,7 +858,7 @@ Fixes a regression introduced in the `rome format` command ([#2670](https://gith - TypeScript's formatting is better in line with what Prettier does. - Better formatting of string literals. Removing unnecessary quotes in string literals and quotes from member names. -Correctly choose the correct quote based on quantity of quotes inside a literal: +Correctly choose the correct quote based on the quantity of quotes inside a literal: ```js // original code let a = { @@ -875,12 +875,12 @@ Correctly choose the correct quote based on quantity of quotes inside a literal: let c = '"content" \' '; ``` - Better formatting of various statements -- Improved the performance of the formatter an average of 20%-30%! Check the relevant +- Improved the performance of the formatter by an average of 20%-30%! Check the relevant PRs [1](https://github.com/rome/tools/pull/2456), [2](https://github.com/rome/tools/pull/2638), [3](https://github.com/rome/tools/pull/2612), [4](https://github.com/rome/tools/pull/2462), [5](https://github.com/rome/tools/pull/2634) if you're interested in what the team did. To reach better compatibility with Prettier, the team had to revise the foundation of our printer, which caused some regressions around how comments are printed. These are known issues that we -plan to close by next release. +plan to close by the next release. ### Linter @@ -891,7 +891,7 @@ Refer to the [website](https://rome.tools/#linter) to learn how to start using i ## 0.5.0 -- BREAKING CHANGES: the `format` command doesn't write on disk by default. Now the command prints on terminal. +- BREAKING CHANGES: the `format` command doesn't write on disk by default. Now the command prints on the terminal. **Migration**: add the `--write` argument when calling `rome format` diff --git a/benchmark/package.json b/benchmark/package.json index f3a0f8f7377f..0ed75efddf20 100644 --- a/benchmark/package.json +++ b/benchmark/package.json @@ -11,10 +11,10 @@ "node": ">20.0.0" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "8.37.0", - "@typescript-eslint/parser": "8.37.0", + "@typescript-eslint/eslint-plugin": "8.46.4", + "@typescript-eslint/parser": "8.46.4", "dprint": "0.50.2", - "eslint": "9.39.0", + "eslint": "9.39.1", "prettier": "3.6.2" } } diff --git a/crates/biome_analyze/src/categories.rs b/crates/biome_analyze/src/categories.rs index e425eab0d8c7..13e5c33b5fda 100644 --- a/crates/biome_analyze/src/categories.rs +++ b/crates/biome_analyze/src/categories.rs @@ -438,11 +438,11 @@ impl<'de> serde::Deserialize<'de> for RuleCategories { #[cfg(feature = "schema")] impl schemars::JsonSchema for RuleCategories { - fn schema_name() -> String { - String::from("RuleCategories") + fn schema_name() -> std::borrow::Cow<'static, str> { + std::borrow::Cow::Borrowed("RuleCategories") } - fn json_schema(generator: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema { + fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::Schema { >::json_schema(generator) } } diff --git a/crates/biome_analyze/src/rule.rs b/crates/biome_analyze/src/rule.rs index ff22def153c3..8cca7f71e2b4 100644 --- a/crates/biome_analyze/src/rule.rs +++ b/crates/biome_analyze/src/rule.rs @@ -97,36 +97,54 @@ impl TryFrom for Applicability { pub enum RuleSource { /// Rules from [Rust Clippy](https://rust-lang.github.io/rust-clippy/master/index.html) Clippy(&'static str), + /// Rules from [Deno Lint](https://github.com/denoland/deno_lint) + DenoLint(&'static str), /// Rules from [Eslint](https://eslint.org/) Eslint(&'static str), + /// Rules from [Eslint Plugin Barrel Files](https://github.com/thepassle/eslint-plugin-barrel-files) + EslintBarrelFiles(&'static str), /// Rules from [GraphQL-ESLint](https://github.com/graphql-hive/graphql-eslint) EslintGraphql(&'static str), - /// Rules from [graphql-schema-linter](https://github.com/cjoudrey/graphql-schema-linter) - GraphqlSchemaLinter(&'static str), /// Rules from [Eslint Plugin Import](https://github.com/import-js/eslint-plugin-import) EslintImport(&'static str), /// Rules from [Eslint Plugin Import Access](https://github.com/uhyo/eslint-plugin-import-access) EslintImportAccess(&'static str), /// Rules from [Eslint Plugin Jest](https://github.com/jest-community/eslint-plugin-jest) EslintJest(&'static str), - /// Rules from [Eslint Plugin JSX A11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y) - EslintJsxA11y(&'static str), /// Rules from [Eslint Plugin JSDOc](https://github.com/gajus/eslint-plugin-jsdoc) EslintJsDoc(&'static str), + /// Rules from [Eslint Plugin JSX A11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y) + EslintJsxA11y(&'static str), + /// Rules from [Eslint Plugin Mysticatea](https://github.com/mysticatea/eslint-plugin) + EslintMysticatea(&'static str), + /// Rules from [Eslint Plugin N](https://github.com/eslint-community/eslint-plugin-n) + EslintN(&'static str), + /// Rules from [Eslint Plugin Next](https://github.com/vercel/next.js/tree/canary/packages/eslint-plugin-next) + EslintNext(&'static str), + /// Rules from [Eslint Plugin No Secrets](https://github.com/nickdeis/eslint-plugin-no-secrets) + EslintNoSecrets(&'static str), + /// Rules from [Eslint Plugin Package.json](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json) + EslintPackageJson(&'static str), + /// Rules from [Eslint Plugin Package.json Dependencies](https://github.com/idan-at/eslint-plugin-package-json-dependencies) + EslintPackageJsonDependencies(&'static str), /// Rules from [Eslint Plugin Perfectionist](https://perfectionist.dev/) EslintPerfectionist(&'static str), + /// Rules from [Eslint Plugin Qwik](https://github.com/QwikDev/qwik) + EslintQwik(&'static str), /// Rules from [Eslint Plugin React](https://github.com/jsx-eslint/eslint-plugin-react) EslintReact(&'static str), /// Rules from [Eslint Plugin React Hooks](https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/README.md) EslintReactHooks(&'static str), + /// Rules from [Eslint Plugin React Prefer Function Component](https://github.com/tatethurston/eslint-plugin-react-prefer-function-component) + EslintReactPreferFunctionComponent(&'static str), /// Rules from [Eslint Plugin React Refresh](https://github.com/ArnaudBarre/eslint-plugin-react-refresh) EslintReactRefresh(&'static str), /// Rules from [eslint-react.xyz](https://eslint-react.xyz/) EslintReactX(&'static str), /// Rules from [eslint-react.xyz](https://eslint-react.xyz/) EslintReactXyz(&'static str), - /// Rules from [Eslint Plugin React Prefer Function Component](https://github.com/tatethurston/eslint-plugin-react-prefer-function-component) - ReactPreferFunctionComponent(&'static str), + /// Rules from [Eslint Plugin Regexp](https://github.com/ota-meshi/eslint-plugin-regexp) + EslintRegexp(&'static str), /// Rules from [Eslint Plugin Solid](https://github.com/solidjs-community/eslint-plugin-solid) EslintSolid(&'static str), /// Rules from [Eslint Plugin Sonar](https://github.com/SonarSource/eslint-plugin-sonarjs) @@ -139,32 +157,14 @@ pub enum RuleSource { EslintUnicorn(&'static str), /// Rules from [Eslint Plugin Unused Imports](https://github.com/sweepline/eslint-plugin-unused-imports) EslintUnusedImports(&'static str), - /// Rules from [Eslint Plugin Mysticatea](https://github.com/mysticatea/eslint-plugin) - 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 [Eslint Plugin Next](https://github.com/vercel/next.js/tree/canary/packages/eslint-plugin-next) - EslintNext(&'static str), - /// Rules from [Eslint Plugin Qwik](https://github.com/QwikDev/qwik) - EslintQwik(&'static str), - /// Rules from [Stylelint](https://github.com/stylelint/stylelint) - Stylelint(&'static str), - /// Rules from [Eslint Plugin No Secrets](https://github.com/nickdeis/eslint-plugin-no-secrets) - EslintNoSecrets(&'static str), - /// Rules from [Eslint Plugin Regexp](https://github.com/ota-meshi/eslint-plugin-regexp) - EslintRegexp(&'static str), - /// Rules from [deno lint](https://github.com/denoland/deno_lint) - DenoLint(&'static str), /// Rules from [Eslint Plugin Vitest](https://github.com/vitest-dev/eslint-plugin-vitest) EslintVitest(&'static str), /// Rules from [Eslint Plugin Vue.js](https://eslint.vuejs.org/) EslintVueJs(&'static str), - /// Rules from [Eslint Plugin Package.json](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json) - EslintPackageJson(&'static str), - /// Rules from [Eslint Plugin Package.json Dependencies](https://github.com/idan-at/eslint-plugin-package-json-dependencies) - EslintPackageJsonDependencies(&'static str), + /// Rules from [graphql-schema-linter](https://github.com/cjoudrey/graphql-schema-linter) + GraphqlSchemaLinter(&'static str), + /// Rules from [Stylelint](https://github.com/stylelint/stylelint) + Stylelint(&'static str), } impl PartialEq for RuleSource { @@ -177,44 +177,44 @@ impl std::fmt::Display for RuleSource { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::Clippy(_) => write!(f, "Clippy"), + Self::DenoLint(_) => write!(f, "Deno Lint"), Self::Eslint(_) => write!(f, "ESLint"), + Self::EslintBarrelFiles(_) => write!(f, "eslint-plugin-barrel-files"), Self::EslintGraphql(_) => write!(f, "GraphQL-ESLint"), - Self::GraphqlSchemaLinter(_) => write!(f, "graphql-schema-linter"), Self::EslintImport(_) => write!(f, "eslint-plugin-import"), Self::EslintImportAccess(_) => write!(f, "eslint-plugin-import-access"), Self::EslintJest(_) => write!(f, "eslint-plugin-jest"), - Self::EslintJsxA11y(_) => write!(f, "eslint-plugin-jsx-a11y"), Self::EslintJsDoc(_) => write!(f, "eslint-plugin-jsdoc"), + Self::EslintJsxA11y(_) => write!(f, "eslint-plugin-jsx-a11y"), + Self::EslintMysticatea(_) => write!(f, "@mysticatea/eslint-plugin"), + Self::EslintN(_) => write!(f, "eslint-plugin-n"), + Self::EslintNext(_) => write!(f, "@next/eslint-plugin-next"), + Self::EslintNoSecrets(_) => write!(f, "eslint-plugin-no-secrets"), + Self::EslintPackageJson(_) => write!(f, "eslint-plugin-package-json"), + Self::EslintPackageJsonDependencies(_) => { + write!(f, "eslint-plugin-package-json-dependencies") + } Self::EslintPerfectionist(_) => write!(f, "eslint-plugin-perfectionist"), + Self::EslintQwik(_) => write!(f, "eslint-plugin-qwik"), Self::EslintReact(_) => write!(f, "eslint-plugin-react"), Self::EslintReactHooks(_) => write!(f, "eslint-plugin-react-hooks"), + Self::EslintReactPreferFunctionComponent(_) => { + write!(f, "eslint-plugin-react-prefer-function-component") + } Self::EslintReactRefresh(_) => write!(f, "eslint-plugin-react-refresh"), Self::EslintReactX(_) => write!(f, "eslint-plugin-react-x"), Self::EslintReactXyz(_) => write!(f, "@eslint-react/eslint-plugin"), - Self::ReactPreferFunctionComponent(_) => { - write!(f, "eslint-plugin-react-prefer-function-component") - } + Self::EslintRegexp(_) => write!(f, "eslint-plugin-regexp"), Self::EslintSolid(_) => write!(f, "eslint-plugin-solid"), Self::EslintSonarJs(_) => write!(f, "eslint-plugin-sonarjs"), - Self::EslintStylistic(_) => write!(f, "eslint-plugin-stylistic"), + Self::EslintStylistic(_) => write!(f, "@stylistic/eslint-plugin"), Self::EslintTypeScript(_) => write!(f, "typescript-eslint"), Self::EslintUnicorn(_) => write!(f, "eslint-plugin-unicorn"), 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::EslintNext(_) => write!(f, "@next/eslint-plugin-next"), - Self::EslintQwik(_) => write!(f, "eslint-plugin-qwik"), - Self::Stylelint(_) => write!(f, "Stylelint"), - Self::EslintNoSecrets(_) => write!(f, "eslint-plugin-no-secrets"), - Self::EslintRegexp(_) => write!(f, "eslint-plugin-regexp"), - Self::DenoLint(_) => write!(f, "deno-lint"), Self::EslintVitest(_) => write!(f, "@vitest/eslint-plugin"), Self::EslintVueJs(_) => write!(f, "eslint-plugin-vue"), - Self::EslintPackageJson(_) => write!(f, "eslint-plugin-package-json"), - Self::EslintPackageJsonDependencies(_) => { - write!(f, "eslint-plugin-package-json-dependencies") - } + Self::GraphqlSchemaLinter(_) => write!(f, "graphql-schema-linter"), + Self::Stylelint(_) => write!(f, "Stylelint"), } } } @@ -261,124 +261,124 @@ impl RuleSource { pub fn as_rule_name(&self) -> &'static str { match self { Self::Clippy(rule_name) + | Self::DenoLint(rule_name) | Self::Eslint(rule_name) + | Self::EslintBarrelFiles(rule_name) | Self::EslintGraphql(rule_name) - | Self::GraphqlSchemaLinter(rule_name) | Self::EslintImport(rule_name) | Self::EslintImportAccess(rule_name) | Self::EslintJest(rule_name) - | Self::EslintJsxA11y(rule_name) | Self::EslintJsDoc(rule_name) + | Self::EslintJsxA11y(rule_name) + | Self::EslintMysticatea(rule_name) + | Self::EslintN(rule_name) + | Self::EslintNext(rule_name) + | Self::EslintNoSecrets(rule_name) + | Self::EslintPackageJson(rule_name) + | Self::EslintPackageJsonDependencies(rule_name) | Self::EslintPerfectionist(rule_name) + | Self::EslintQwik(rule_name) | Self::EslintReact(rule_name) | Self::EslintReactHooks(rule_name) + | Self::EslintReactPreferFunctionComponent(rule_name) | Self::EslintReactRefresh(rule_name) | Self::EslintReactX(rule_name) | Self::EslintReactXyz(rule_name) - | Self::ReactPreferFunctionComponent(rule_name) - | Self::EslintTypeScript(rule_name) + | Self::EslintRegexp(rule_name) | Self::EslintSolid(rule_name) | Self::EslintSonarJs(rule_name) | Self::EslintStylistic(rule_name) + | Self::EslintTypeScript(rule_name) | Self::EslintUnicorn(rule_name) | Self::EslintUnusedImports(rule_name) - | Self::EslintMysticatea(rule_name) - | Self::EslintBarrelFiles(rule_name) - | Self::EslintN(rule_name) - | Self::EslintNext(rule_name) - | Self::EslintQwik(rule_name) - | Self::EslintNoSecrets(rule_name) - | Self::EslintRegexp(rule_name) - | Self::Stylelint(rule_name) - | Self::DenoLint(rule_name) | Self::EslintVitest(rule_name) | Self::EslintVueJs(rule_name) - | Self::EslintPackageJson(rule_name) - | Self::EslintPackageJsonDependencies(rule_name) => rule_name, + | Self::GraphqlSchemaLinter(rule_name) + | Self::Stylelint(rule_name) => rule_name, } } pub fn to_namespaced_rule_name(&self) -> String { match self { Self::Clippy(rule_name) + | Self::DenoLint(rule_name) | Self::Eslint(rule_name) - | Self::GraphqlSchemaLinter(rule_name) => (*rule_name).to_string(), + | Self::GraphqlSchemaLinter(rule_name) + | Self::Stylelint(rule_name) => (*rule_name).to_string(), + Self::EslintBarrelFiles(rule_name) => format!("barrel-files/{rule_name}"), Self::EslintGraphql(rule_name) => format!("@graphql-eslint/{rule_name}"), Self::EslintImport(rule_name) => format!("import/{rule_name}"), Self::EslintImportAccess(rule_name) => format!("import-access/{rule_name}"), Self::EslintJest(rule_name) => format!("jest/{rule_name}"), - Self::EslintJsxA11y(rule_name) => format!("jsx-a11y/{rule_name}"), Self::EslintJsDoc(rule_name) => format!("jsdoc/{rule_name}"), + Self::EslintJsxA11y(rule_name) => format!("jsx-a11y/{rule_name}"), + Self::EslintMysticatea(rule_name) => format!("@mysticatea/{rule_name}"), + Self::EslintN(rule_name) => format!("n/{rule_name}"), + Self::EslintNext(rule_name) => format!("@next/next/{rule_name}"), + Self::EslintNoSecrets(rule_name) => format!("no-secrets/{rule_name}"), + Self::EslintPackageJson(rule_name) => format!("package-json/{rule_name}"), + Self::EslintPackageJsonDependencies(rule_name) => { + format!("package-json-dependencies/{rule_name}") + } Self::EslintPerfectionist(rule_name) => format!("perfectionist/{rule_name}"), + Self::EslintQwik(rule_name) => format!("qwik/{rule_name}"), Self::EslintReact(rule_name) => format!("react/{rule_name}"), Self::EslintReactHooks(rule_name) => format!("react-hooks/{rule_name}"), + Self::EslintReactPreferFunctionComponent(rule_name) => { + format!("react-prefer-function-component/{rule_name}") + } Self::EslintReactRefresh(rule_name) => format!("react-refresh/{rule_name}"), Self::EslintReactX(rule_name) => format!("react-x/{rule_name}"), Self::EslintReactXyz(rule_name) => format!("@eslint-react/{rule_name}"), - Self::ReactPreferFunctionComponent(rule_name) => { - format!("react-prefer-function-component/{rule_name}") - } - Self::EslintTypeScript(rule_name) => format!("@typescript-eslint/{rule_name}"), - Self::EslintSolid(rule_name) => format!("solidjs/{rule_name}"), + Self::EslintRegexp(rule_name) => format!("regexp/{rule_name}"), + Self::EslintSolid(rule_name) => format!("solid/{rule_name}"), Self::EslintSonarJs(rule_name) => format!("sonarjs/{rule_name}"), Self::EslintStylistic(rule_name) => format!("@stylistic/{rule_name}"), + Self::EslintTypeScript(rule_name) => format!("@typescript-eslint/{rule_name}"), Self::EslintUnicorn(rule_name) => format!("unicorn/{rule_name}"), 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::EslintNext(rule_name) => format!("@next/{rule_name}"), - Self::EslintQwik(rule_name) => format!("qwik/{rule_name}"), - Self::Stylelint(rule_name) => format!("stylelint/{rule_name}"), - Self::EslintNoSecrets(rule_name) => format!("no-secrets/{rule_name}"), - Self::EslintRegexp(rule_name) => format!("regexp/{rule_name}"), - Self::DenoLint(rule_name) => format!("deno-lint/{rule_name}"), Self::EslintVitest(rule_name) => format!("vitest/{rule_name}"), Self::EslintVueJs(rule_name) => format!("vue/{rule_name}"), - Self::EslintPackageJson(rule_name) => format!("package-json/{rule_name}"), - Self::EslintPackageJsonDependencies(rule_name) => { - format!("package-json-dependencies/{rule_name}") - } } } pub fn to_rule_url(&self) -> String { match self { Self::Clippy(rule_name) => format!("https://rust-lang.github.io/rust-clippy/master/#{rule_name}"), + Self::DenoLint(rule_name) => format!("https://lint.deno.land/rules/{rule_name}"), Self::Eslint(rule_name) => format!("https://eslint.org/docs/latest/rules/{rule_name}"), + Self::EslintBarrelFiles(rule_name) => format!("https://github.com/thepassle/eslint-plugin-barrel-files/blob/main/docs/rules/{rule_name}.md"), Self::EslintGraphql(rule_name) => format!("https://the-guild.dev/graphql/eslint/rules/{rule_name}"), - Self::GraphqlSchemaLinter(rule_name) => format!("https://github.com/cjoudrey/graphql-schema-linter?tab=readme-ov-file#{rule_name}"), Self::EslintImport(rule_name) => format!("https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/{rule_name}.md"), Self::EslintImportAccess(_) => "https://github.com/uhyo/eslint-plugin-import-access".to_string(), Self::EslintJest(rule_name) => format!("https://github.com/jest-community/eslint-plugin-jest/blob/main/docs/rules/{rule_name}.md"), - Self::EslintJsxA11y(rule_name) => format!("https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/{rule_name}.md"), Self::EslintJsDoc(rule_name) => format!("https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/{rule_name}.md"), + Self::EslintJsxA11y(rule_name) => format!("https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/{rule_name}.md"), + Self::EslintMysticatea(rule_name) => format!("https://github.com/mysticatea/eslint-plugin/blob/master/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::EslintNext(rule_name) => format!("https://nextjs.org/docs/messages/{rule_name}"), + Self::EslintNoSecrets(_) => "https://github.com/nickdeis/eslint-plugin-no-secrets/blob/master/README.md".to_string(), + Self::EslintPackageJson(rule_name) => format!("https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/blob/main/docs/rules/{rule_name}.md"), + Self::EslintPackageJsonDependencies(rule_name) => format!("https://github.com/idan-at/eslint-plugin-package-json-dependencies/blob/master/docs/rules/{rule_name}.md"), Self::EslintPerfectionist(rule_name) => format!("https://perfectionist.dev/rules/{rule_name}"), + Self::EslintQwik(rule_name) => format!("https://qwik.dev/docs/advanced/eslint/#{rule_name}"), 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::EslintReactPreferFunctionComponent(_) => "https://github.com/tatethurston/eslint-plugin-react-prefer-function-component".to_string(), Self::EslintReactRefresh(_) => "https://github.com/ArnaudBarre/eslint-plugin-react-refresh".to_string(), Self::EslintReactX(rule_name) => format!("https://eslint-react.xyz/docs/rules/{rule_name}"), Self::EslintReactXyz(rule_name) => format!("https://eslint-react.xyz/docs/rules/{rule_name}"), - Self::ReactPreferFunctionComponent(_) => "https://github.com/tatethurston/eslint-plugin-react-prefer-function-component".to_string(), - Self::EslintTypeScript(rule_name) => format!("https://typescript-eslint.io/rules/{rule_name}"), + Self::EslintRegexp(rule_name) => format!("https://ota-meshi.github.io/eslint-plugin-regexp/rules/{rule_name}.html"), 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::EslintTypeScript(rule_name) => format!("https://typescript-eslint.io/rules/{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::EslintNext(rule_name) => format!("https://nextjs.org/docs/messages/{rule_name}"), - Self::EslintQwik(rule_name) => format!("https://qwik.dev/docs/advanced/eslint/#{rule_name}"), - Self::Stylelint(rule_name) => format!("https://github.com/stylelint/stylelint/blob/main/lib/rules/{rule_name}/README.md"), - Self::EslintNoSecrets(_) => "https://github.com/nickdeis/eslint-plugin-no-secrets/blob/master/README.md".to_string(), - Self::EslintRegexp(rule_name) => format!("https://ota-meshi.github.io/eslint-plugin-regexp/rules/{rule_name}.html"), - Self::DenoLint(rule_name) => format!("https://lint.deno.land/rules/{rule_name}"), Self::EslintVitest(rule_name) => format!("https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/{rule_name}.md"), Self::EslintVueJs(rule_name) => format!("https://eslint.vuejs.org/rules/{rule_name}"), - Self::EslintPackageJson(rule_name) => format!("https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/blob/main/docs/rules/{rule_name}.md"), - Self::EslintPackageJsonDependencies(rule_name) => format!("https://github.com/idan-at/eslint-plugin-package-json-dependencies/blob/master/docs/rules/{rule_name}.md"), + Self::GraphqlSchemaLinter(rule_name) => format!("https://github.com/cjoudrey/graphql-schema-linter?tab=readme-ov-file#{rule_name}"), + Self::Stylelint(rule_name) => format!("https://github.com/stylelint/stylelint/blob/main/lib/rules/{rule_name}/README.md"), } } @@ -393,7 +393,14 @@ impl RuleSource { /// All ESLint plugins, exception for the TypeScript one pub const fn is_eslint_plugin(&self) -> bool { - !matches!(self, Self::Clippy(_) | Self::Eslint(_) | Self::Stylelint(_)) + !matches!( + self, + Self::Clippy(_) + | Self::DenoLint(_) + | Self::Eslint(_) + | Self::GraphqlSchemaLinter(_) + | Self::Stylelint(_) + ) } pub const fn is_stylelint(&self) -> bool { diff --git a/crates/biome_aria_metadata/build.rs b/crates/biome_aria_metadata/build.rs index 321ea7361b09..782b7900c691 100644 --- a/crates/biome_aria_metadata/build.rs +++ b/crates/biome_aria_metadata/build.rs @@ -32,15 +32,21 @@ const ISO_COUNTRIES: &[&str] = &[ const ISO_LANGUAGES: &[&str] = &[ "ab", "aa", "af", "sq", "am", "ar", "an", "hy", "as", "ay", "az", "ba", "eu", "bn", "dz", "bh", - "bi", "br", "bg", "my", "be", "km", "ca", "zh", "zh-Hans", "zh-Hant", "co", "hr", "cs", "da", - "nl", "en", "eo", "et", "fo", "fa", "fj", "fi", "fr", "fy", "gl", "gd", "gv", "ka", "de", "el", - "kl", "gn", "gu", "ht", "ha", "he", "iw", "hi", "hu", "is", "io", "id", "in", "ia", "ie", "iu", - "ik", "ga", "it", "ja", "jv", "kn", "ks", "kk", "rw", "ky", "rn", "ko", "ku", "lo", "la", "lv", - "li", "ln", "lt", "mk", "mg", "ms", "ml", "mt", "mi", "mr", "mo", "mn", "na", "ne", "no", "nb", - "nn", "oc", "or", "om", "ps", "pl", "pt", "pa", "qu", "rm", "ro", "ru", "sm", "sg", "sa", "sr", - "sh", "st", "tn", "sn", "ii", "sd", "si", "ss", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", - "tg", "ta", "tt", "te", "th", "bo", "ti", "to", "ts", "tr", "tk", "tw", "ug", "uk", "ur", "uz", - "vi", "vo", "wa", "cy", "wo", "xh", "yi", "ji", "yo", "zu", + "bi", "br", "bg", "my", "be", "km", "ca", "zh", "co", "hr", "cs", "da", "nl", "en", "eo", "et", + "fo", "fa", "fj", "fi", "fr", "fy", "gl", "gd", "gv", "ka", "de", "el", "kl", "gn", "gu", "ht", + "ha", "he", "iw", "hi", "hu", "is", "io", "id", "in", "ia", "ie", "iu", "ik", "ga", "it", "ja", + "jv", "kn", "ks", "kk", "rw", "ky", "rn", "ko", "ku", "lo", "la", "lv", "li", "ln", "lt", "mk", + "mg", "ms", "ml", "mt", "mi", "mr", "mo", "mn", "na", "ne", "no", "nb", "nn", "oc", "or", "om", + "ps", "pl", "pt", "pa", "qu", "rm", "ro", "ru", "sm", "sg", "sa", "sr", "sh", "st", "tn", "sn", + "ii", "sd", "si", "ss", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", "tg", "ta", "tt", "te", + "th", "bo", "ti", "to", "ts", "tr", "tk", "tw", "ug", "uk", "ur", "uz", "vi", "vo", "wa", "cy", + "wo", "xh", "yi", "ji", "yo", "zu", +]; + +const ISO_SCRIPTS: &[&str] = &[ + "Arab", "Armn", "Beng", "Cyrl", "Deva", "Ethi", "Grek", "Gujr", "Guru", "Hang", "Hani", "Hans", + "Hant", "Hebr", "Hira", "Kana", "Khmr", "Laoo", "Latn", "Mlym", "Mymr", "Orya", "Sinh", "Taml", + "Telu", "Thai", "Tibt", "Zyyy", ]; #[derive(Debug, Default, biome_deserialize_macros::Merge, serde::Deserialize)] @@ -266,12 +272,14 @@ fn main() -> io::Result<()> { let iso_countries = generate_enums(ISO_COUNTRIES, "IsoCountries"); let iso_languages = generate_enums(ISO_LANGUAGES, "IsoLanguages"); + let iso_scripts = generate_enums(ISO_SCRIPTS, "IsoScripts"); let tokens = quote! { #aria_attributes #aria_roles #iso_countries #iso_languages + #iso_scripts }; let ast = tokens.to_string(); diff --git a/crates/biome_aria_metadata/src/lib.rs b/crates/biome_aria_metadata/src/lib.rs index 5e592466873d..c6e58a59f0a0 100644 --- a/crates/biome_aria_metadata/src/lib.rs +++ b/crates/biome_aria_metadata/src/lib.rs @@ -20,17 +20,23 @@ pub const ISO_COUNTRIES: [&str; 233] = [ "UZ", "VU", "VE", "VN", "WF", "EH", "YE", "ZM", "ZW", ]; -pub const ISO_LANGUAGES: [&str; 152] = [ +pub const ISO_LANGUAGES: [&str; 150] = [ "ab", "aa", "af", "sq", "am", "ar", "an", "hy", "as", "ay", "az", "ba", "eu", "bn", "dz", "bh", - "bi", "br", "bg", "my", "be", "km", "ca", "zh", "zh-Hans", "zh-Hant", "co", "hr", "cs", "da", - "nl", "en", "eo", "et", "fo", "fa", "fj", "fi", "fr", "fy", "gl", "gd", "gv", "ka", "de", "el", - "kl", "gn", "gu", "ht", "ha", "he", "iw", "hi", "hu", "is", "io", "id", "in", "ia", "ie", "iu", - "ik", "ga", "it", "ja", "jv", "kn", "ks", "kk", "rw", "ky", "rn", "ko", "ku", "lo", "la", "lv", - "li", "ln", "lt", "mk", "mg", "ms", "ml", "mt", "mi", "mr", "mo", "mn", "na", "ne", "no", "nb", - "nn", "oc", "or", "om", "ps", "pl", "pt", "pa", "qu", "rm", "ro", "ru", "sm", "sg", "sa", "sr", - "sh", "st", "tn", "sn", "ii", "sd", "si", "ss", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", - "tg", "ta", "tt", "te", "th", "bo", "ti", "to", "ts", "tr", "tk", "tw", "ug", "uk", "ur", "uz", - "vi", "vo", "wa", "cy", "wo", "xh", "yi", "ji", "yo", "zu", + "bi", "br", "bg", "my", "be", "km", "ca", "zh", "co", "hr", "cs", "da", "nl", "en", "eo", "et", + "fo", "fa", "fj", "fi", "fr", "fy", "gl", "gd", "gv", "ka", "de", "el", "kl", "gn", "gu", "ht", + "ha", "he", "iw", "hi", "hu", "is", "io", "id", "in", "ia", "ie", "iu", "ik", "ga", "it", "ja", + "jv", "kn", "ks", "kk", "rw", "ky", "rn", "ko", "ku", "lo", "la", "lv", "li", "ln", "lt", "mk", + "mg", "ms", "ml", "mt", "mi", "mr", "mo", "mn", "na", "ne", "no", "nb", "nn", "oc", "or", "om", + "ps", "pl", "pt", "pa", "qu", "rm", "ro", "ru", "sm", "sg", "sa", "sr", "sh", "st", "tn", "sn", + "ii", "sd", "si", "ss", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", "tg", "ta", "tt", "te", + "th", "bo", "ti", "to", "ts", "tr", "tk", "tw", "ug", "uk", "ur", "uz", "vi", "vo", "wa", "cy", + "wo", "xh", "yi", "ji", "yo", "zu", +]; + +pub const ISO_SCRIPTS: [&str; 28] = [ + "Arab", "Armn", "Beng", "Cyrl", "Deva", "Ethi", "Grek", "Gujr", "Guru", "Hang", "Hani", "Hans", + "Hant", "Hebr", "Hira", "Kana", "Khmr", "Laoo", "Latn", "Mlym", "Mymr", "Orya", "Sinh", "Taml", + "Telu", "Thai", "Tibt", "Zyyy", ]; /// Returns a list of valid ISO countries @@ -43,6 +49,11 @@ pub fn is_valid_language(language: &str) -> bool { IsoLanguages::from_str(language).is_ok() } +/// Returns whether the given script code is a valid ISO script +pub fn is_valid_script(script: &str) -> bool { + IsoScripts::from_str(script).is_ok() +} + /// An array of all available countries pub fn countries() -> &'static [&'static str] { &ISO_COUNTRIES @@ -53,6 +64,11 @@ pub fn languages() -> &'static [&'static str] { &ISO_LANGUAGES } +/// An array of all available scripts +pub fn scripts() -> &'static [&'static str] { + &ISO_SCRIPTS +} + #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub enum AriaAttributeKind { Property, diff --git a/crates/biome_cli/Cargo.toml b/crates/biome_cli/Cargo.toml index f7bd66713912..49b4e8d800fe 100644 --- a/crates/biome_cli/Cargo.toml +++ b/crates/biome_cli/Cargo.toml @@ -55,7 +55,7 @@ camino = { workspace = true } crossbeam = { workspace = true } dashmap = { workspace = true } path-absolutize = { workspace = true } -quick-junit = "0.5.1" +quick-junit = "0.5.2" rayon = { workspace = true } regex = { workspace = true } rustc-hash = { workspace = true } 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 aa7841af5812..e8f996268e2c 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 @@ -53,7 +53,7 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } - "@next/google-font-display" => { + "@next/next/google-font-display" => { let group = rules.suspicious.get_or_insert_with(Default::default); let rule = group .unwrap_group_as_mut() @@ -61,7 +61,7 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } - "@next/google-font-preconnect" => { + "@next/next/google-font-preconnect" => { let group = rules.performance.get_or_insert_with(Default::default); let rule = group .unwrap_group_as_mut() @@ -69,7 +69,7 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } - "@next/no-async-client-component" => { + "@next/next/no-async-client-component" => { if !options.include_nursery { results.add(eslint_name, eslint_to_biome::RuleMigrationResult::Nursery); return false; @@ -81,7 +81,7 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } - "@next/no-document-import-in-page" => { + "@next/next/no-document-import-in-page" => { let group = rules.suspicious.get_or_insert_with(Default::default); let rule = group .unwrap_group_as_mut() @@ -89,7 +89,7 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } - "@next/no-head-element" => { + "@next/next/no-head-element" => { let group = rules.style.get_or_insert_with(Default::default); let rule = group .unwrap_group_as_mut() @@ -97,7 +97,7 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } - "@next/no-head-import-in-document" => { + "@next/next/no-head-import-in-document" => { let group = rules.suspicious.get_or_insert_with(Default::default); let rule = group .unwrap_group_as_mut() @@ -105,7 +105,7 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } - "@next/no-img-element" => { + "@next/next/no-img-element" => { let group = rules.performance.get_or_insert_with(Default::default); let rule = group .unwrap_group_as_mut() @@ -113,7 +113,19 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } - "@next/no-unwanted-polyfillio" => { + "@next/next/no-sync-scripts" => { + if !options.include_nursery { + results.add(eslint_name, eslint_to_biome::RuleMigrationResult::Nursery); + return false; + } + let group = rules.nursery.get_or_insert_with(Default::default); + let rule = group + .unwrap_group_as_mut() + .no_sync_scripts + .get_or_insert(Default::default()); + rule.set_level(rule.level().max(rule_severity.into())); + } + "@next/next/no-unwanted-polyfillio" => { let group = rules.performance.get_or_insert_with(Default::default); let rule = group .unwrap_group_as_mut() @@ -353,6 +365,22 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } + "@typescript-eslint/no-for-in-array" => { + if !options.include_inspired { + results.add(eslint_name, eslint_to_biome::RuleMigrationResult::Inspired); + return false; + } + if !options.include_nursery { + results.add(eslint_name, eslint_to_biome::RuleMigrationResult::Nursery); + return false; + } + let group = rules.nursery.get_or_insert_with(Default::default); + let rule = group + .unwrap_group_as_mut() + .no_for_in + .get_or_insert(Default::default()); + rule.set_level(rule.level().max(rule_severity.into())); + } "@typescript-eslint/no-inferrable-types" => { let group = rules.style.get_or_insert_with(Default::default); let rule = group @@ -573,6 +601,18 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } + "@typescript-eslint/prefer-find" => { + if !options.include_nursery { + results.add(eslint_name, eslint_to_biome::RuleMigrationResult::Nursery); + return false; + } + let group = rules.nursery.get_or_insert_with(Default::default); + let rule = group + .unwrap_group_as_mut() + .use_find + .get_or_insert(Default::default()); + rule.set_level(rule.level().max(rule_severity.into())); + } "@typescript-eslint/prefer-for-of" => { let group = rules.style.get_or_insert_with(Default::default); let rule = group @@ -621,6 +661,18 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } + "@typescript-eslint/require-array-sort-compare" => { + if !options.include_nursery { + results.add(eslint_name, eslint_to_biome::RuleMigrationResult::Nursery); + return false; + } + let group = rules.nursery.get_or_insert_with(Default::default); + let rule = group + .unwrap_group_as_mut() + .use_array_sort_compare + .get_or_insert(Default::default()); + rule.set_level(rule.level().max(rule_severity.into())); + } "@typescript-eslint/require-await" => { let group = rules.suspicious.get_or_insert_with(Default::default); let rule = group @@ -737,14 +789,6 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } - "deno-lint/no-process-global" => { - let group = rules.correctness.get_or_insert_with(Default::default); - let rule = group - .unwrap_group_as_mut() - .no_process_global - .get_or_insert(Default::default()); - rule.set_level(rule.level().max(rule_severity.into())); - } "dot-notation" => { let group = rules.complexity.get_or_insert_with(Default::default); let rule = group @@ -2173,6 +2217,18 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } + "prefer-spread" => { + if !options.include_nursery { + results.add(eslint_name, eslint_to_biome::RuleMigrationResult::Nursery); + return false; + } + let group = rules.nursery.get_or_insert_with(Default::default); + let rule = group + .unwrap_group_as_mut() + .use_spread + .get_or_insert(Default::default()); + rule.set_level(rule.level().max(rule_severity.into())); + } "prefer-template" => { let group = rules.style.get_or_insert_with(Default::default); let rule = group @@ -2497,7 +2553,7 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } - "solidjs/no-destructure" => { + "solid/no-destructure" => { if !options.include_inspired { results.add(eslint_name, eslint_to_biome::RuleMigrationResult::Inspired); return false; @@ -2509,7 +2565,7 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } - "solidjs/no-react-specific-props" => { + "solid/no-react-specific-props" => { let group = rules.suspicious.get_or_insert_with(Default::default); let rule = group .unwrap_group_as_mut() @@ -2517,7 +2573,7 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } - "solidjs/prefer-for" => { + "solid/prefer-for" => { if !options.include_inspired { results.add(eslint_name, eslint_to_biome::RuleMigrationResult::Inspired); return false; diff --git a/crates/biome_cli/src/logging.rs b/crates/biome_cli/src/logging.rs index 8fcaa8552142..0cb802945bc1 100644 --- a/crates/biome_cli/src/logging.rs +++ b/crates/biome_cli/src/logging.rs @@ -8,6 +8,7 @@ use tracing::Metadata; use tracing::subscriber::Interest; use tracing_subscriber::filter::LevelFilter; use tracing_subscriber::fmt::format::FmtSpan; +use tracing_subscriber::fmt::writer::MakeWriterExt; use tracing_subscriber::layer::{Context, Filter, SubscriberExt}; use tracing_subscriber::util::SubscriberInitExt; use tracing_subscriber::{Layer as _, registry}; @@ -88,70 +89,40 @@ pub fn setup_cli_subscriber( kind: LoggingKind, colors: Option<&ColorsArg>, ) { + use tracing_subscriber_ext::*; + if level == LoggingLevel::None { return; } - let mut format = tracing_subscriber::fmt::layer() + let fmt_span = matches!(level, LoggingLevel::Tracing) + .then_some(FmtSpan::CLOSE) + .unwrap_or(FmtSpan::NONE); + + let make_writer = file + .map(File::create) + .transpose() + .expect("Failed to create log file") + .optional() + .or_else(std::io::stdout); + + let layer = tracing_subscriber::fmt::layer() .with_level(true) .with_target(false) .with_thread_names(true) .with_file(true) - .with_ansi(colors.is_none_or(|c| c.is_enabled())); + .with_ansi(colors.is_none_or(|c| c.is_enabled())) + .with_span_events(fmt_span) + .with_writer(make_writer); - if level == LoggingLevel::Tracing { - format = format.with_span_events(FmtSpan::CLOSE); + let layer = match kind { + LoggingKind::Pretty => layer.pretty().first(), + LoggingKind::Compact => layer.compact().second(), + LoggingKind::Json => layer.json().flatten_event(true).third(), } + .with_filter(LoggingFilter { level }); - // FIXME: I hate the duplication here, and I tried to make a function that - // could take `impl Layer` so the compiler could expand - // this for us... but I got dragged into a horrible swamp of generic - // constraints... - if let Some(file) = file { - let file = File::create(file).expect("Failed to create log file"); - let format = format.with_writer(file); - match kind { - LoggingKind::Pretty => { - let format = format.pretty(); - registry() - .with(format.with_filter(LoggingFilter { level })) - .init() - } - LoggingKind::Compact => { - let format = format.compact(); - registry() - .with(format.with_filter(LoggingFilter { level })) - .init() - } - LoggingKind::Json => { - let format = format.json().flatten_event(true); - registry() - .with(format.with_filter(LoggingFilter { level })) - .init() - } - } - } else { - match kind { - LoggingKind::Pretty => { - let format = format.pretty(); - registry() - .with(format.with_filter(LoggingFilter { level })) - .init() - } - LoggingKind::Compact => { - let format = format.compact(); - registry() - .with(format.with_filter(LoggingFilter { level })) - .init() - } - LoggingKind::Json => { - let format = format.json().flatten_event(true); - registry() - .with(format.with_filter(LoggingFilter { level })) - .init() - } - } - }; + registry().with(layer).init(); } #[derive(Copy, Debug, Default, Clone, Ord, PartialOrd, Eq, PartialEq)] @@ -289,3 +260,182 @@ impl FromStr for LoggingKind { } } } + +mod tracing_subscriber_ext { + //! Extensions module for [tracing_subscriber]. + //! + //! This module is kept private to preserve API flexibility. + + use tracing::{Metadata, Subscriber}; + use tracing_subscriber::{ + Layer, + fmt::{MakeWriter, writer::OptionalWriter}, + }; + + /// A wrapper type for an optional [MakeWriter]. + /// + /// Implements [MakeWriter] for `Option` where `M: MakeWriter`. + /// + /// XXX: Remove after [PR](https://github.com/tokio-rs/tracing/pull/3196) is merged. + pub(super) struct OptionMakeWriter(Option); + + impl<'a, M> MakeWriter<'a> for OptionMakeWriter + where + M: MakeWriter<'a> + 'a, + { + type Writer = OptionalWriter; + + fn make_writer(&'a self) -> Self::Writer { + match &self.0 { + Some(inner) => OptionalWriter::some(inner.make_writer()), + None => OptionalWriter::none(), + } + } + + fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer { + match &self.0 { + Some(inner) => OptionalWriter::some(inner.make_writer_for(meta)), + None => OptionalWriter::none(), + } + } + } + + /// Extension trait for creating [OptionMakeWriter]. + pub(super) trait OptionMakeWriterExt { + fn optional(self) -> OptionMakeWriter + where + Self: Sized; + } + + impl OptionMakeWriterExt for Option { + fn optional(self) -> OptionMakeWriter { + OptionMakeWriter(self) + } + } + + /// A wrapper type for one of three possible values. + /// + /// Implements [Layer] if `First`, `Second`, and `Third` all implement [Layer]. + pub(super) enum OrderedVariants { + First(First), + Second(Second), + Third(Third), + } + + impl Layer for OrderedVariants + where + First: Layer, + Second: Layer, + Third: Layer, + S: Subscriber, + { + } + + /// Extension trait for creating [OrderedVariants]. + pub(super) trait OrderedVariantsExt { + /// Wraps `self` in the [OrderedVariants::First] variant. + fn first(self) -> OrderedVariants + where + Self: Sized, + { + OrderedVariants::First(self) + } + + /// Wraps `self` in the [OrderedVariants::Second] variant. + fn second(self) -> OrderedVariants + where + Self: Sized, + { + OrderedVariants::Second(self) + } + + /// Wraps `self` in the [OrderedVariants::Third] variant. + fn third(self) -> OrderedVariants + where + Self: Sized, + { + OrderedVariants::Third(self) + } + } + + impl OrderedVariantsExt for T {} +} + +#[cfg(test)] +mod tests { + use std::{ + io::Write, + sync::{Arc, Mutex}, + }; + + struct MockWriter { + bytes: Mutex>, + } + + impl MockWriter { + /// Creates a new, empty `Arc`. + fn new() -> Arc { + Arc::new(Self { + bytes: Mutex::new(Vec::new()), + }) + } + + /// Wraps `Arc` in `Some`. + fn some(self: Arc) -> Option> { + Some(self) + } + + /// Wraps `Arc` in `None`. + fn none(self: Arc) -> Option> { + None + } + + /// Asserts that something was written to this writer. + fn assert_written(&self) { + assert!(!self.bytes.lock().unwrap().is_empty()) + } + } + + impl std::io::Write for &MockWriter { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.bytes.lock().unwrap().extend_from_slice(buf); + + Ok(buf.len()) + } + + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } + } + + #[test] + fn optional_writer_or_else_test() { + use super::tracing_subscriber_ext::*; + use tracing_subscriber::fmt::{MakeWriter, writer::MakeWriterExt}; + + let writer_one = MockWriter::new(); + let writer_two = MockWriter::new(); + + let make_writer = writer_one + .clone() + .some() + .optional() + .or_else(writer_two.clone()); + + let mut writer = make_writer.make_writer(); + + writer.write_all(b"Hello, world!").unwrap(); + + writer_one.assert_written(); + + let writer_one = MockWriter::new(); + let writer_two = MockWriter::new(); + + let make_writer = writer_one.none().optional().or_else(writer_two.clone()); + let mut writer = make_writer.make_writer(); + + writer.write_all(b"Hello, world!").unwrap(); + + writer_two.assert_written(); + } +} diff --git a/crates/biome_cli/src/reporter/gitlab.rs b/crates/biome_cli/src/reporter/gitlab.rs index 20b40cb1ec66..f93fd89cf50e 100644 --- a/crates/biome_cli/src/reporter/gitlab.rs +++ b/crates/biome_cli/src/reporter/gitlab.rs @@ -3,6 +3,7 @@ use biome_console::fmt::{Display, Formatter}; use biome_console::{Console, ConsoleExt, markup}; use biome_diagnostics::display::SourceFile; use biome_diagnostics::{Error, PrintDescription, Resource, Severity}; +use biome_rowan::{TextRange, TextSize}; use camino::{Utf8Path, Utf8PathBuf}; use path_absolutize::Absolutize; use serde::Serialize; @@ -204,7 +205,9 @@ impl<'a> GitLabDiagnostic<'a> { fingerprint: u64, ) -> Option { let location = diagnostic.location(); - let span = location.span?; + let span = location + .span + .unwrap_or(TextRange::new(TextSize::from(1), TextSize::from(1))); let source_code = location.source_code?; let description = PrintDescription(diagnostic).to_string(); let begin = match SourceFile::new(source_code).location(span.start()) { diff --git a/crates/biome_cli/tests/cases/handle_astro_files.rs b/crates/biome_cli/tests/cases/handle_astro_files.rs index 4010616d591a..8c2808a146d1 100644 --- a/crates/biome_cli/tests/cases/handle_astro_files.rs +++ b/crates/biome_cli/tests/cases/handle_astro_files.rs @@ -223,6 +223,9 @@ let schema = z.object().optional(); schema + sure() --- + + + Astro + + +"# + .as_bytes(), + ); + + let (fs, result) = run_cli( + fs, + &mut console, + Args::from(["format", "--write", astro_file_path.as_str()].as_slice()), + ); + + assert!(result.is_ok(), "run_cli returned {result:?}"); + + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "dont_indent_frontmatter", + fs, + console, + result, + )); +} diff --git a/crates/biome_cli/tests/cases/handle_vue_files.rs b/crates/biome_cli/tests/cases/handle_vue_files.rs index 1c98fb509f9a..aa7c97bb38b6 100644 --- a/crates/biome_cli/tests/cases/handle_vue_files.rs +++ b/crates/biome_cli/tests/cases/handle_vue_files.rs @@ -568,6 +568,121 @@ const props: Props = { title: "Hello" }; )); } +#[test] +fn full_support_tsx() { + let fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + fs.insert( + "biome.json".into(), + r#"{ "html": { "formatter": {"enabled": true}, "linter": {"enabled": true}, "experimentalFullSupportEnabled": true } }"#.as_bytes(), + ); + + let vue_file_path = Utf8Path::new("file.vue"); + fs.insert( + vue_file_path.into(), + r#" + + + + +"# + .as_bytes(), + ); + + let (fs, result) = run_cli( + fs, + &mut console, + Args::from(["check", "--write", "--unsafe", vue_file_path.as_str()].as_slice()), + ); + + assert!(result.is_ok(), "run_cli returned {result:?}"); + + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "full_support_tsx", + fs, + console, + result, + )); +} + +#[test] +fn full_support_jsx() { + let fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + fs.insert( + "biome.json".into(), + r#"{ "html": { "formatter": {"enabled": true}, "linter": {"enabled": true}, "experimentalFullSupportEnabled": true } }"#.as_bytes(), + ); + + let vue_file_path = Utf8Path::new("file.vue"); + fs.insert( + vue_file_path.into(), + r#" + + + + +"# + .as_bytes(), + ); + + let (fs, result) = run_cli( + fs, + &mut console, + Args::from(["check", "--write", "--unsafe", vue_file_path.as_str()].as_slice()), + ); + + assert!(result.is_ok(), "run_cli returned {result:?}"); + + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "full_support_jsx", + fs, + console, + result, + )); +} + #[test] fn format_stdin_successfully() { let fs = MemoryFileSystem::default(); diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/dont_indent_frontmatter.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/dont_indent_frontmatter.snap new file mode 100644 index 000000000000..9ea776f16eba --- /dev/null +++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/dont_indent_frontmatter.snap @@ -0,0 +1,51 @@ +--- +source: crates/biome_cli/tests/snap_test.rs +expression: redactor(content) +--- +## `biome.json` + +```json +{ + "html": { + "formatter": { "enabled": true, "indentScriptAndStyle": true }, + "linter": { "enabled": true }, + "experimentalFullSupportEnabled": true + } +} +``` + +## `file.astro` + +```astro +--- +import Foo from "./Foo.astro"; +const bar = 123; +if (bar > 1) { + console.log(bar + 1); +} +--- + +{bar} + + + + + +``` + +# Emitted Messages + +```block +Formatted 1 file in