Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/bump_oxlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
inputs:
version:
required: true
description: 'The X.Y.Z version to bump to, no `v` prefix.'
type: string

env:
Expand All @@ -22,6 +23,11 @@ jobs:
with:
persist-credentials: false # should be fine, we give another token for PR creation

- name: Bump Version
env:
OXLINT_VERSION: ${{ inputs.version }}
run: npm version ${OXLINT_VERSION} --no-git-tag-version

- uses: oxc-project/setup-node@8958a8e040102244b619c4a94fccb657a44b1c21 # v1.0.6

- name: Generate version ${{ inputs.version }}
Expand All @@ -30,17 +36,11 @@ jobs:
run: |
pnpm install oxlint@${OXLINT_VERSION}
pnpm run generate # Generate rules
pnpm run format # run prettier over it

- name: Test and update snapshot
continue-on-error: true # we check in PR why it fails
run: pnpm run test -u # Update test snapshots

- name: Bump oxlint rules
env:
OXLINT_VERSION: ${{ inputs.version }}
run: npm version ${OXLINT_VERSION} --no-git-tag-version

- uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
with:
# bot account with PAT required for triggering workflow runs
Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/generate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,10 @@ jobs:
- uses: oxc-project/setup-node@8958a8e040102244b619c4a94fccb657a44b1c21 # v1.0.6

- name: Remove current generated code
run: rm -r ./src/generated/
run: rm -r ./src/generated/ && rm -r ./scripts/generated/

- name: Generate from source code
run: pnpm run generate

- name: Format generated code
run: pnpm run format

- name: Check for git diff
run: git diff --exit-code
2 changes: 1 addition & 1 deletion eslint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import tseslint from 'typescript-eslint';

export default [
eslint.configs.recommended,
unicorn.configs['flat/recommended'],
unicorn.configs['recommended'],
...tseslint.configs.recommended,
...oxlint.buildFromOxlintConfigFile('.oxlintrc.json', {
typeAware: true,
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
},
"scripts": {
"prepare": "husky",
"generate": "node --import @oxc-node/core/register ./scripts/generate.ts",
"generate": "node --import @oxc-node/core/register ./scripts/generate-vitest-rules.ts && node --import @oxc-node/core/register ./scripts/generate.ts && pnpm format",
"build": "vite build",
"lint": "npx oxlint --type-aware --type-check && npx eslint",
"format": "npx oxfmt",
Expand Down Expand Up @@ -79,7 +79,7 @@
"vitest": "^4.0.0"
},
"lint-staged": {
"*.{js,cjs,ts}": "eslint",
"*.{js,cjs,ts}": "pnpm run lint",
"*": "oxfmt ."
},
"volta": {
Expand Down
33 changes: 33 additions & 0 deletions scripts/generate-vitest-rules.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import fs from 'node:fs';
import path from 'node:path';
import packageJson from '../package.json' with { type: 'json' };

// --- Generate the vitest rules file ---

const __dirname = new URL('.', import.meta.url).pathname;
// `<repo>/scripts/generated/`
const scriptsGenerateFolder = path.resolve(__dirname, `generated`);

if (!fs.existsSync(scriptsGenerateFolder)) {
fs.mkdirSync(scriptsGenerateFolder);
}

// Generate the vitest-compatible-jest-rules.json file by pulling it from the oxc repository.
// This keeps the two in sync.
// Use the version of the package to determine which git reference to pull from.
const gitReference = `oxlint_v${packageJson.version}`;

const githubURL = `https://raw.githubusercontent.com/oxc-project/oxc/${gitReference}/crates/oxc_linter/data/vitest_compatible_jest_rules.json`;
const response = await fetch(githubURL);

if (!response.ok) {
throw new Error(
`Failed to fetch vitest-compatible-jest-rules.json: ${response.status} ${response.statusText}`
);
}

const vitestRules = await response.text();
const vitestRulesPath = path.resolve(scriptsGenerateFolder, 'vitest-compatible-jest-rules.json');
fs.writeFileSync(vitestRulesPath, vitestRules, 'utf8');

console.log('vitest-compatible-jest-rules.json copied successfully from the oxc repo.');
2 changes: 2 additions & 0 deletions scripts/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ const promises = [rulesGenerator, configGenerator].map(async (generator) => {
});

await Promise.all(promises);

console.log('Rules generated successfully.');
43 changes: 43 additions & 0 deletions scripts/generated/vitest-compatible-jest-rules.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
[
"consistent-test-it",
"expect-expect",
"max-expects",
"max-nested-describe",
"no-alias-methods",
"no-commented-out-tests",
"no-conditional-expect",
"no-conditional-in-test",
"no-disabled-tests",
"no-duplicate-hooks",
"no-focused-tests",
"no-hooks",
"no-identical-title",
"no-interpolation-in-snapshots",
"no-large-snapshots",
"no-mocks-import",
"no-restricted-jest-methods",
"no-restricted-matchers",
"no-standalone-expect",
"no-test-prefixes",
"no-test-return-statement",
"prefer-called-with",
"prefer-comparison-matcher",
"prefer-each",
"prefer-equality-matcher",
"prefer-expect-resolves",
"prefer-hooks-in-order",
"prefer-hooks-on-top",
"prefer-lowercase-title",
"prefer-mock-promise-shorthand",
"prefer-spy-on",
"prefer-strict-equal",
"prefer-to-be",
"prefer-to-contain",
"prefer-to-have-length",
"prefer-todo",
"require-hook",
"require-to-throw-message",
"require-top-level-describe",
"valid-describe-callback",
"valid-expect"
]
File renamed without changes.
4 changes: 2 additions & 2 deletions scripts/traverse-rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import {
reactHookRulesInsideReactScope,
typescriptRulesExtendEslintRules,
unicornRulesExtendEslintRules,
viteTestCompatibleRules,
} from '../src/constants.js';
import vitestCompatibleRules from './generated/vitest-compatible-jest-rules.json' with { type: 'json' };

export type Rule = {
value: string;
Expand Down Expand Up @@ -63,7 +63,7 @@ function getAliasRules(rule: Rule): Rule | undefined {
};
}

if (rule.scope === 'jest' && viteTestCompatibleRules.includes(rule.value)) {
if (rule.scope === 'jest' && vitestCompatibleRules.includes(rule.value)) {
return {
value: `vitest/${rule.value}`,
scope: 'vitest',
Expand Down
9 changes: 3 additions & 6 deletions src/build-from-oxlint-config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ import {
import fs from 'node:fs';
import { execSync } from 'node:child_process';
import type { Linter } from 'eslint';
import {
typescriptRulesExtendEslintRules,
unicornRulesExtendEslintRules,
viteTestCompatibleRules,
} from './constants.js';
import { typescriptRulesExtendEslintRules, unicornRulesExtendEslintRules } from './constants.js';
import vitestCompatibleRules from '../scripts/generated/vitest-compatible-jest-rules.json' with { type: 'json' };

describe('buildFromOxlintConfigFile', () => {
it('successfully parse oxlint json config', () => {
Expand Down Expand Up @@ -163,7 +160,7 @@ describe('integration test with oxlint', () => {

// special case for vitest / jest alias rules
if (config.plugins?.includes('vitest')) {
expectedCount += viteTestCompatibleRules.filter(
expectedCount += vitestCompatibleRules.filter(
(aliasRule) => `vitest/${aliasRule}` in buildConfig.rules!
).length;
}
Expand Down
5 changes: 3 additions & 2 deletions src/build-from-oxlint-config/rules.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, expect, it } from 'vitest';
import { handleRulesScope } from './rules.js';
import { unicornRulesExtendEslintRules, viteTestCompatibleRules } from '../constants.js';
import { unicornRulesExtendEslintRules } from '../constants.js';
import vitestCompatibleRules from '../../scripts/generated/vitest-compatible-jest-rules.json' with { type: 'json' };

describe('handleRulesScope', () => {
for (const ruleSetting of ['error', ['error'], 'warn', ['warn'], 1, [1], 2, [2]]) {
Expand Down Expand Up @@ -118,7 +119,7 @@ describe('handleRulesScope', () => {
expect(rules).toStrictEqual({});
});

for (const alias of viteTestCompatibleRules) {
for (const alias of vitestCompatibleRules) {
it(`disables vitest jest alias rules for ${alias}`, () => {
for (const rule of [`jest/${alias}`, `vitest/${alias}`]) {
const rules = {};
Expand Down
47 changes: 0 additions & 47 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,53 +41,6 @@ export const typescriptRulesExtendEslintRules = [
'no-useless-constructor',
];

// Some vitest rules are re-implemented version of jest rules.
// Since oxlint supports these rules under jest/*, we need to remap them.
// remapping in source-code: <https://github.com/oxc-project/oxc/blob/b48d5f15b25bd31a3fc09399f33c6e5a9e6abdd2/crates/oxc_linter/src/utils/mod.rs>
export const viteTestCompatibleRules = [
'consistent-test-it',
'expect-expect',
'max-expects',
'max-nested-describe',
'no-alias-methods',
'no-commented-out-tests',
'no-conditional-expect',
'no-conditional-in-test',
'no-disabled-tests',
'no-duplicate-hooks',
'no-focused-tests',
'no-hooks',
'no-identical-title',
'no-interpolation-in-snapshots',
'no-large-snapshots',
'no-mocks-import',
'no-restricted-jest-methods',
'no-restricted-matchers',
'no-standalone-expect',
'no-test-prefixes',
'no-test-return-statement',
'prefer-called-with',
'prefer-comparison-matcher',
'prefer-each',
'prefer-equality-matcher',
'prefer-expect-resolves',
'prefer-hooks-in-order',
'prefer-hooks-on-top',
'prefer-lowercase-title',
'prefer-mock-promise-shorthand',
'prefer-spy-on',
'prefer-strict-equal',
'prefer-to-be',
'prefer-to-contain',
'prefer-to-have-length',
'prefer-todo',
'require-hook',
'require-to-throw-message',
'require-top-level-describe',
'valid-describe-callback',
'valid-expect',
];

export const unicornRulesExtendEslintRules = ['no-negated-condition'];

// All rules from `eslint-plugin-react-hooks`
Expand Down