Skip to content

Commit

Permalink
feat: add support for flat config (#139)
Browse files Browse the repository at this point in the history
* feat: add support for flat config

* Create rare-grapes-call.md

* fix
  • Loading branch information
ota-meshi authored Apr 10, 2024
1 parent 9d6f4a5 commit 1ef872c
Show file tree
Hide file tree
Showing 15 changed files with 197 additions and 61 deletions.
5 changes: 5 additions & 0 deletions .changeset/rare-grapes-call.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"eslint-plugin-node-dependencies": minor
---

feat: add support for flat config
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
!/.vscode
!/.github
/tests/fixtures/integrations/eslint-plugin
/tests/fixtures/integrations/eslint-plugin-legacy-config
!/docs/.vitepress
/docs/.vitepress/dist
/docs/.vitepress/cache
14 changes: 11 additions & 3 deletions .github/workflows/NodeCI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
- name: Install Packages
run: npm i --legacy-peer-deps
run: npm i -f
- name: Build
run: npm run build
- name: Test
run: npm test
test-with-eslint9:
Expand All @@ -43,6 +45,8 @@ jobs:
npm i -D eslint@^9.0.0-0 -f
npx rimraf node_modules
npm install -f
- name: Build
run: npm run build
- name: Test
run: npm test
test-with-eslint6:
Expand All @@ -57,6 +61,8 @@ jobs:
npm i -D eslint@6
npx rimraf node_modules
npm install
- name: Build
run: npm run build
- name: Test
run: npm test
test-and-coverage:
Expand All @@ -65,7 +71,9 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- name: Install Packages
run: npm i --legacy-peer-deps
run: npm i -f
- name: Build
run: npm run build
- name: Test
run: npm run test:nyc
- name: Coveralls GitHub Action
Expand All @@ -78,7 +86,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- name: Install Packages
run: npm i --legacy-peer-deps
run: npm i -f
- name: Build
run: npm run build
- name: Update
Expand Down
35 changes: 32 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,27 @@ npm install --save-dev eslint eslint-plugin-node-dependencies

<!--USAGE_SECTION_START-->

Add `node-dependencies` to the plugins section of your `.eslintrc` configuration file (you can omit the `eslint-plugin-` prefix)
Add `node-dependencies` to the plugins section of your `eslint.config.js` or `.eslintrc` configuration file (you can omit the `eslint-plugin-` prefix)
and either use one of the two configurations available (`recommended`) or configure the rules you want:

### The recommended configuration
### The recommended configuration (New Config)

The `plugin.configs["flat/recommended"]` config enables a subset of [the rules](#white_check_mark-rules) that should be most useful to most users.
*See [lib/configs/rules/recommended.ts](https://github.com/ota-meshi/eslint-plugin-node-dependencies/blob/main/lib/configs/rules/recommended.ts) for more details.*

```js
// eslint.config.js
import * as nodeDependenciesPlugin from "eslint-plugin-node-dependencies"

export default [
...nodeDependenciesPlugin.configs["flat/recommended"],
];
```

### The recommended configuration (Legacy Config)

The `plugin:node-dependencies/recommended` config enables a subset of [the rules](#white_check_mark-rules) that should be most useful to most users.
*See [lib/configs/recommended.ts](https://github.com/ota-meshi/eslint-plugin-node-dependencies/blob/main/lib/configs/recommended.ts) for more details.*
*See [lib/configs/rules/recommended.ts](https://github.com/ota-meshi/eslint-plugin-node-dependencies/blob/main/lib/configs/rules/recommended.ts) for more details.*

```js
// .eslintrc.js
Expand All @@ -67,6 +81,21 @@ module.exports = {

Override/add specific rules configurations. *See also: [http://eslint.org/docs/user-guide/configuring](http://eslint.org/docs/user-guide/configuring)*.

```js
// eslint.config.js
import * as nodeDependenciesPlugin from "eslint-plugin-node-dependencies"

export default [
{
plugins: { "node-dependencies": nodeDependenciesPlugin }
rules: {
// Override/add rules settings here, such as:
"node-dependencies/rule-name": "error"
}
}
];
```

```js
// .eslintrc.js
module.exports = {
Expand Down
35 changes: 32 additions & 3 deletions docs/user-guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,27 @@ npm install --save-dev eslint eslint-plugin-node-dependencies

<!--USAGE_SECTION_START-->

Add `node-dependencies` to the plugins section of your `.eslintrc` configuration file (you can omit the `eslint-plugin-` prefix)
Add `node-dependencies` to the plugins section of your `eslint.config.js` or `.eslintrc` configuration file (you can omit the `eslint-plugin-` prefix)
and either use one of the two configurations available (`recommended`) or configure the rules you want:

### The recommended configuration
### The recommended configuration (New Config)

The `plugin.configs["flat/recommended"]` config enables a subset of [the rules](../rules/index.md) that should be most useful to most users.
*See [lib/configs/rules/recommended.ts](https://github.com/ota-meshi/eslint-plugin-node-dependencies/blob/main/lib/configs/rules/recommended.ts) for more details.*

```js
// eslint.config.js
import * as nodeDependenciesPlugin from "eslint-plugin-node-dependencies"

export default [
...nodeDependenciesPlugin.configs["flat/recommended"],
];
```

### The recommended configuration (Legacy Config)

The `plugin:node-dependencies/recommended` config enables a subset of [the rules](../rules/index.md) that should be most useful to most users.
*See [lib/configs/recommended.ts](https://github.com/ota-meshi/eslint-plugin-node-dependencies/blob/main/lib/configs/recommended.ts) for more details.*
*See [lib/configs/rules/recommended.ts](https://github.com/ota-meshi/eslint-plugin-node-dependencies/blob/main/lib/configs/rules/recommended.ts) for more details.*

```js
// .eslintrc.js
Expand All @@ -43,6 +57,21 @@ module.exports = {

Override/add specific rules configurations. *See also: [http://eslint.org/docs/user-guide/configuring](http://eslint.org/docs/user-guide/configuring)*.

```js
// eslint.config.js
import * as nodeDependenciesPlugin from "eslint-plugin-node-dependencies"

export default [
{
plugins: { "node-dependencies": nodeDependenciesPlugin }
rules: {
// Override/add rules settings here, such as:
"node-dependencies/rule-name": "error"
}
}
];
```

```js
// .eslintrc.js
module.exports = {
Expand Down
21 changes: 21 additions & 0 deletions lib/configs/flat/recommended.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { ESLint, Linter } from "eslint";
import recommendedRules from "../rules/recommended";
import * as jsonParser from "jsonc-eslint-parser";
export const recommendedConfig = [
{
plugins: {
// eslint-disable-next-line @typescript-eslint/naming-convention -- ignore
get "node-dependencies"(): ESLint.Plugin {
// eslint-disable-next-line @typescript-eslint/no-require-imports -- ignore
return require("../../index");
},
},
},
{
files: ["**/package.json", "package.json"],
languageOptions: {
parser: jsonParser,
},
rules: recommendedRules.rules,
},
] satisfies Linter.FlatConfig[];
8 changes: 2 additions & 6 deletions lib/configs/recommended.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import recommendedRules from "./rules/recommended";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment -- ignore
// @ts-ignore -- Backwards compatibility
export = {
Expand All @@ -6,12 +7,7 @@ export = {
{
files: ["package.json"],
parser: require.resolve("jsonc-eslint-parser"),
rules: {
// eslint-plugin-node-dependencies rules
"node-dependencies/compat-engines": "error",
"node-dependencies/no-dupe-deps": "error",
"node-dependencies/valid-semver": "error",
},
rules: recommendedRules.rules,
},
],
};
10 changes: 10 additions & 0 deletions lib/configs/rules/recommended.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Linter } from "eslint";

export default {
rules: {
// eslint-plugin-node-dependencies rules
"node-dependencies/compat-engines": "error",
"node-dependencies/no-dupe-deps": "error",
"node-dependencies/valid-semver": "error",
} as Linter.RulesRecord,
};
2 changes: 2 additions & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import type { RuleModule } from "./types";
import { rules as ruleList } from "./utils/rules";
import recommended from "./configs/recommended";
import { recommendedConfig as flatRecommended } from "./configs/flat/recommended";
import * as meta from "./meta";

const configs = {
recommended,
"flat/recommended": flatRecommended,
};

const rules = ruleList.reduce(
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"lint": "eslint . --ext .js,.vue,.ts,.json,.yaml,.yml",
"eslint-fix": "eslint . --ext .js,.vue,.ts,.json,.yaml,.yml --fix",
"pretest": "npm run build",
"test:base": "mocha --require ts-node/register \"tests/**/*.ts\" --reporter dot --timeout 60000",
"test:base": "mocha --require ts-node/register/transpile-only \"tests/**/*.ts\" --reporter dot --timeout 60000",
"test": "npm run test:nyc",
"test:nyc": "nyc --reporter=lcov npm run test:base",
"test:debug": "mocha --require ts-node/register/transpile-only \"tests/**/*.ts\" --reporter dot --timeout 60000",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"engines": {
"node": ">=8"
},
"dependencies": {
"semver": "^7.3.5"
}
}
5 changes: 5 additions & 0 deletions tests/fixtures/integrations/eslint-plugin/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as nodeDependenciesPlugin from "../../../../dist/index.js"

export default [
...nodeDependenciesPlugin.configs["flat/recommended"],
];
73 changes: 53 additions & 20 deletions tests/lib/eslint-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,66 @@
import path from "path";
import assert from "assert";
import { getLegacyESLint } from "eslint-compat-utils/eslint";
import * as eslintModule from "eslint";
import plugin from "../../lib/index";
// eslint-disable-next-line @typescript-eslint/naming-convention -- ignore
const ESLint = getLegacyESLint();

// -----------------------------------------------------------------------------
// Tests
// -----------------------------------------------------------------------------

const TEST_CWD = path.join(__dirname, "../fixtures/integrations/eslint-plugin");
const TEST_CWD_FOR_FLAT_CONFIG = path.join(
__dirname,
"../fixtures/integrations/eslint-plugin",
);
const TEST_CWD_FOR_LEGACY_CONFIG = path.join(
__dirname,
"../fixtures/integrations/eslint-plugin-legacy-config",
);

describe("Integration with eslint-plugin-node-dependencies", () => {
if (!ESLint) {
return;
}
it("should lint without errors", async () => {
const engine = new ESLint({
cwd: TEST_CWD,
plugins: {
"eslint-plugin-node-dependencies": plugin as never,
},
describe("Integration with eslint-plugin-node-dependencies", async () => {
// eslint-disable-next-line @typescript-eslint/naming-convention -- ignore
const FlatESLint: typeof eslintModule.ESLint =
// @ts-expect-error -- new API
typeof eslintModule.loadESLint === "function"
? // @ts-expect-error -- new API
await eslintModule.loadESLint({ useFlatConfig: true })
: null;
// eslint-disable-next-line @typescript-eslint/naming-convention -- ignore
const ESLint: typeof eslintModule.ESLint =
// @ts-expect-error -- new API
typeof eslintModule.loadESLint === "function"
? // @ts-expect-error -- new API
await eslintModule.loadESLint({ useFlatConfig: false })
: getLegacyESLint();
if (FlatESLint) {
it("should lint without errors (with flat config)", async () => {
const eslint = new FlatESLint({
cwd: TEST_CWD_FOR_FLAT_CONFIG,
});
const results = await eslint.lintFiles(["package.json"]);

assert.strictEqual(results.length, 1);
assert.deepStrictEqual(
results[0].messages.map((m) => m.ruleId),
["node-dependencies/compat-engines"],
);
});
const results = await engine.lintFiles(["package.json"]);
}
if (ESLint) {
it("should lint without errors (with legacy config)", async () => {
const engine = new ESLint({
cwd: TEST_CWD_FOR_LEGACY_CONFIG,
plugins: {
"eslint-plugin-node-dependencies": plugin as never,
},
});
const results = await engine.lintFiles(["package.json"]);

assert.strictEqual(results.length, 1);
assert.deepStrictEqual(
results[0].messages.map((m) => m.ruleId),
["node-dependencies/compat-engines"],
);
});
assert.strictEqual(results.length, 1);
assert.deepStrictEqual(
results[0].messages.map((m) => m.ruleId),
["node-dependencies/compat-engines"],
);
});
}
});
39 changes: 14 additions & 25 deletions tools/update-rulesets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,23 @@ import fs from "fs";
// import eslint from "eslint"
import { rules } from "./lib/load-rules";

const content = `
// eslint-disable-next-line @typescript-eslint/ban-ts-comment -- ignore
// @ts-ignore -- Backwards compatibility
export = {
plugins: ["node-dependencies"],
overrides: [
{
files: ["package.json"],
parser: require.resolve("jsonc-eslint-parser"),
rules: {
// eslint-plugin-node-dependencies rules
${rules
.filter(
(rule) =>
rule.meta.docs.recommended && !rule.meta.deprecated,
)
.map((rule) => {
const conf = rule.meta.docs.default || "error";
return `"${rule.meta.docs.ruleId}": "${conf}"`;
})
.join(",\n")}
}
}
]
const content = `import type { Linter } from "eslint";
export default {
rules: {
// eslint-plugin-node-dependencies rules
${rules
.filter((rule) => rule.meta.docs.recommended && !rule.meta.deprecated)
.map((rule) => {
const conf = rule.meta.docs.default || "error";
return `"${rule.meta.docs.ruleId}": "${conf}"`;
})
.join(",\n")}
} as Linter.RulesRecord
}
`;

const filePath = path.resolve(__dirname, "../lib/configs/recommended.ts");
const filePath = path.resolve(__dirname, "../lib/configs/rules/recommended.ts");

// Update file.
fs.writeFileSync(filePath, content);
Expand Down

0 comments on commit 1ef872c

Please sign in to comment.