Skip to content

Commit 7f416f4

Browse files
authored
fix: Package-specific migration bugs (#107)
1 parent 9250f28 commit 7f416f4

File tree

6 files changed

+108
-2
lines changed

6 files changed

+108
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* @fileoverview A list of shareable configs that need the compat utility.
3+
* @author Nicholas C. Zakas
4+
*/
5+
6+
export default ["eslint-config-react-app"];

packages/migrate-config/src/migrate-config.js

+31-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import * as recast from "recast";
1111
import { Legacy } from "@eslint/eslintrc";
1212
import camelCase from "camelcase";
1313
import pluginsNeedingCompat from "./compat-plugins.js";
14+
import configsNeedingCompat from "./compat-configs.js";
1415
import { convertIgnorePatternToMinimatch } from "@eslint/compat";
1516

1617
//-----------------------------------------------------------------------------
@@ -147,6 +148,23 @@ function pluginNeedsCompat(pluginName) {
147148
);
148149
}
149150

151+
/**
152+
* Determines if a shareable config needs the compat utility.
153+
* @param {string} configName The name of the config.
154+
* @returns {boolean} `true` if the config needs the compat utility.
155+
*/
156+
function configNeedsCompat(configName) {
157+
const configNameToTest = configName.includes("/")
158+
? configName.slice(0, configName.indexOf("/"))
159+
: configName;
160+
161+
const fullConfigName = naming.normalizePackageName(
162+
configNameToTest,
163+
"eslint-config",
164+
);
165+
return configsNeedingCompat.includes(fullConfigName);
166+
}
167+
150168
/**
151169
* Gets the name of the variable to use for the plugin. If the plugin name
152170
* contains slashes or an @ symbol, it will be normalized to a camelcase name.
@@ -165,6 +183,9 @@ function getPluginVariableName(pluginName) {
165183
name = name.slice(1);
166184
}
167185

186+
// replace slash with uppercase of following letter
187+
name = name.replace(/\/(.)/gu, (_, letter) => letter.toUpperCase());
188+
168189
return camelCase(name);
169190
}
170191

@@ -682,11 +703,19 @@ function migrateConfigObject(migration, config) {
682703

683704
// Check if any of the extends are plugins that need the compat utility
684705
const needsCompat = extendsArray.some(extend => {
685-
if (!extend.startsWith("plugin:")) {
706+
if (
707+
extend.startsWith("eslint:") ||
708+
extend.startsWith(".") ||
709+
extend.startsWith("/")
710+
) {
686711
return false;
687712
}
688713

689-
return pluginNeedsCompat(extend.slice(7));
714+
if (extend.startsWith("plugin:")) {
715+
return pluginNeedsCompat(extend.slice(7));
716+
}
717+
718+
return configNeedsCompat(extend);
690719
});
691720

692721
if (needsCompat) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"extends": [
3+
"react-app",
4+
"prettier",
5+
"plugin:jsx-a11y/recommended",
6+
"plugin:@tanstack/eslint-plugin-query/recommended"
7+
],
8+
"plugins": [
9+
"jsx-a11y",
10+
"@tanstack/query"
11+
]
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const {
2+
fixupConfigRules,
3+
fixupPluginRules,
4+
} = require("@eslint/compat");
5+
6+
const jsxA11Y = require("eslint-plugin-jsx-a11y");
7+
const tanstackQuery = require("@tanstack/eslint-plugin-query");
8+
const js = require("@eslint/js");
9+
10+
const {
11+
FlatCompat,
12+
} = require("@eslint/eslintrc");
13+
14+
const compat = new FlatCompat({
15+
baseDirectory: __dirname,
16+
recommendedConfig: js.configs.recommended,
17+
allConfig: js.configs.all
18+
});
19+
20+
module.exports = [...fixupConfigRules(compat.extends(
21+
"react-app",
22+
"prettier",
23+
"plugin:jsx-a11y/recommended",
24+
"plugin:@tanstack/eslint-plugin-query/recommended",
25+
)), {
26+
plugins: {
27+
"jsx-a11y": fixupPluginRules(jsxA11Y),
28+
"@tanstack/query": fixupPluginRules(tanstackQuery),
29+
},
30+
}];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { fixupConfigRules, fixupPluginRules } from "@eslint/compat";
2+
import jsxA11Y from "eslint-plugin-jsx-a11y";
3+
import tanstackQuery from "@tanstack/eslint-plugin-query";
4+
import path from "node:path";
5+
import { fileURLToPath } from "node:url";
6+
import js from "@eslint/js";
7+
import { FlatCompat } from "@eslint/eslintrc";
8+
9+
const __filename = fileURLToPath(import.meta.url);
10+
const __dirname = path.dirname(__filename);
11+
const compat = new FlatCompat({
12+
baseDirectory: __dirname,
13+
recommendedConfig: js.configs.recommended,
14+
allConfig: js.configs.all
15+
});
16+
17+
export default [...fixupConfigRules(compat.extends(
18+
"react-app",
19+
"prettier",
20+
"plugin:jsx-a11y/recommended",
21+
"plugin:@tanstack/eslint-plugin-query/recommended",
22+
)), {
23+
plugins: {
24+
"jsx-a11y": fixupPluginRules(jsxA11Y),
25+
"@tanstack/query": fixupPluginRules(tanstackQuery),
26+
},
27+
}];

packages/migrate-config/tests/migrate-config-cli.test.js

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const filePaths = [
2626
"gitignore-simple/.eslintrc.json",
2727
"gitignore-complex/.eslintrc.json",
2828
"import-duplicate/.eslintrc.cjs",
29+
"slash-package/.eslintrc.json",
2930
].map(file => `tests/fixtures/${file}`);
3031

3132
//-----------------------------------------------------------------------------
@@ -83,6 +84,7 @@ describe("@eslint/migrate-config", async () => {
8384
// run the migration for mjs
8485
execSync(
8586
`node src/migrate-config-cli.js ${filePath} ${gitignoreFlag}`,
87+
{ stdio: "inherit" },
8688
);
8789

8890
// run the migration for cjs

0 commit comments

Comments
 (0)