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
11 changes: 5 additions & 6 deletions .github/workflows/bump_oxlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,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: ./.github/actions/pnpm

- name: Generate version ${{ inputs.version }}
Expand All @@ -31,17 +36,11 @@ jobs:
run: |
pnpm install oxlint@${OXLINT_VERSION}
pnpm run generate # Generate rules
pnpm run format # run oxfmt 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 Version
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 @@ -30,13 +30,10 @@ jobs:
- uses: ./.github/actions/pnpm

- name: Remove current generated code
Comment thread
connorshea marked this conversation as resolved.
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 package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,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",
"format": "oxfmt",
"lint": "oxlint --type-aware --type-check",
"test": "vitest",
Expand Down
47 changes: 0 additions & 47 deletions scripts/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,53 +14,6 @@ export const aliasPluginNames: Record<string, string> = {
jsx_a11y: 'jsx-a11y',
};

// 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/94320ab6f60ef6aaedeb901b04ccb57e953f66bf/crates/oxc_linter/src/utils/mod.rs>
export const viteTestCompatibleRules = [
Copy link
Copy Markdown
Member Author

@connorshea connorshea Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed that this is identical to the JSON file (except that require-hook is alphabetically sorted in the JSON file and it was out of order here)

'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',
'require-hook',
'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-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
38 changes: 38 additions & 0 deletions scripts/generate-vitest-rules.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
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 ref to pull from.
const gitRef = `oxlint_v${packageJson.version}`;

const githubURL = `https://raw.githubusercontent.com/oxc-project/oxc/${gitRef}/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, 'utf-8');

console.log(
'vitest-compatible-jest-rules.json copied successfully from the oxc repo.'
);
9 changes: 6 additions & 3 deletions scripts/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import path from 'node:path';
import { RulesGenerator } from './generator.js';
import { traverseRules } from './traverse-rules.js';

const __dirname = new URL('.', import.meta.url).pathname;

const result = traverseRules();
const generator = new RulesGenerator(result);

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

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

const generator = new RulesGenerator(result);
await generator.generateRules(generateFolder);

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 @@
[
Comment thread
connorshea marked this conversation as resolved.
"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"
]
5 changes: 3 additions & 2 deletions scripts/traverse-rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import {
aliasPluginNames,
reactHookRulesInsideReactScope,
unicornRulesExtendEslintRules,
viteTestCompatibleRules,
} from './constants.js';

import vitestCompatibleRules from './generated/vitest-compatible-jest-rules.json' with { type: 'json' };
import { typescriptRulesExtendEslintRules } from '../src/constants.js';

export type Rule = {
Expand Down Expand Up @@ -70,7 +71,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