@oxlint/migrate 1.41.0 → 1.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -10
- package/dist/bin/oxlint-migrate.mjs +135 -23
- package/dist/src/index.d.mts +2670 -6
- package/dist/src/index.mjs +1 -1
- package/dist/{src-BNblTDrB.mjs → src-BMWXAQvA.mjs} +187 -146
- package/package.json +11 -9
package/README.md
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/@oxlint/migrate)
|
|
5
5
|
[](https://www.npmjs.com/package/@oxlint/migrate)
|
|
6
6
|
|
|
7
|
-
Generates a `.oxlintrc.json` from an existing
|
|
7
|
+
Generates a `.oxlintrc.json` from an existing ESLint flat config.
|
|
8
|
+
|
|
9
|
+
See [the Migration Guide in the Oxlint docs](https://oxc.rs/docs/guide/usage/linter/migrate-from-eslint.html) for more information on migrating from ESLint to Oxlint.
|
|
8
10
|
|
|
9
11
|
## Usage
|
|
10
12
|
|
|
@@ -12,32 +14,33 @@ Generates a `.oxlintrc.json` from an existing eslint flat config.
|
|
|
12
14
|
npx @oxlint/migrate <optional-eslint-flat-config-path>
|
|
13
15
|
```
|
|
14
16
|
|
|
15
|
-
When no config file provided, the script searches for the default
|
|
17
|
+
When no config file is provided, the script searches for the default ESLint config filenames in the current directory.
|
|
16
18
|
|
|
17
19
|
### Options
|
|
18
20
|
|
|
19
21
|
| Options | Description |
|
|
20
22
|
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
21
|
-
| `--merge` | \* merge
|
|
22
|
-
| `--type-aware` | Include type aware rules, which are supported with `oxlint --type-aware`
|
|
23
|
+
| `--merge` | \* merge ESLint configuration with an existing .oxlintrc.json configuration |
|
|
24
|
+
| `--type-aware` | Include type aware rules, which are supported with `oxlint --type-aware` and [oxlint-tsgolint](https://github.com/oxc-project/tsgolint) |
|
|
23
25
|
| `--with-nursery` | Include oxlint rules which are currently under development |
|
|
24
26
|
| `--js-plugins` | \*\* Include ESLint plugins via `jsPlugins` key. |
|
|
25
|
-
| `--
|
|
26
|
-
| `--
|
|
27
|
+
| `--details` | List rules that could not be migrated to oxlint |
|
|
28
|
+
| `--output-file <file>` | The oxlint configuration file where ESLint v9 rules will be written to, default: `.oxlintrc.json` |
|
|
29
|
+
| `--replace-eslint-comments` | Search in the project files for ESLint comments and replaces them with oxlint. Some ESLint comments are not supported and will be reported. |
|
|
27
30
|
|
|
28
31
|
\* WARNING: When some `categories` are enabled, this tools will enable more rules with the combination of `plugins`.
|
|
29
|
-
Else we need to disable each rule `plugin/categories` combination, which is not covered by your
|
|
32
|
+
Else we need to disable each rule `plugin/categories` combination, which is not covered by your ESLint configuration.
|
|
30
33
|
This behavior can change in the future.
|
|
31
34
|
|
|
32
|
-
\*\* WARNING: Tries to guess the plugin name. Should work with most
|
|
35
|
+
\*\* WARNING: Tries to guess the plugin name. Should work fine with most plugin names, but is not perfect.
|
|
33
36
|
Not every ESLint API is integrated with `oxlint`.
|
|
34
|
-
Tested ESLint Plugins with `oxlint` can be found in this [Oxc Discussion](https://github.com/oxc-project/oxc/discussions/14862).
|
|
37
|
+
Tested ESLint Plugins with `oxlint` can be found in this [Oxc Discussion](https://github.com/oxc-project/oxc/discussions/14862). See the caveats section for more details.
|
|
35
38
|
|
|
36
39
|
### User Flow
|
|
37
40
|
|
|
38
41
|
- Upgrade `oxlint` and `@oxlint/migrate` to the same version.
|
|
39
42
|
- Execute `npx @oxlint/migrate`
|
|
40
|
-
- (Optional): Disable supported rules via [eslint-plugin-oxlint](https://github.com/oxc-project/eslint-plugin-oxlint)
|
|
43
|
+
- (Optional): Disable supported rules via [eslint-plugin-oxlint](https://github.com/oxc-project/eslint-plugin-oxlint), if you have any rules you need that aren't in Oxlint yet.
|
|
41
44
|
|
|
42
45
|
### TypeScript ESLint Configuration Files
|
|
43
46
|
|
|
@@ -66,3 +69,64 @@ pnpm vitest
|
|
|
66
69
|
```shell
|
|
67
70
|
pnpm manual-test
|
|
68
71
|
```
|
|
72
|
+
|
|
73
|
+
## Caveats
|
|
74
|
+
|
|
75
|
+
The migration tool has been tested to work quite well for simple ESLint flat config files. It has also been tested to work correctly for the large majority of complex flat config files. However, there may be some edge cases where the migration is not perfect, or the behavior of Oxlint itself differs from ESLint.
|
|
76
|
+
|
|
77
|
+
Here are some known caveats to be aware of:
|
|
78
|
+
|
|
79
|
+
**`settings` field not migrated**
|
|
80
|
+
|
|
81
|
+
The `settings` field (e.g. for setting the React version) is not migrated to the oxlint config yet. You may need to copy it over manually if you have any settings specified.
|
|
82
|
+
|
|
83
|
+
Not all `settings` options are supported by oxlint, and so rule behavior in certain edge-cases may differ. See [the Settings docs](https://oxc.rs/docs/guide/usage/linter/config-file-reference.html#settings) for more info.
|
|
84
|
+
|
|
85
|
+
**Local ESLint Plugins imported via path are not migrated**
|
|
86
|
+
|
|
87
|
+
The `--js-plugins` flag cannot migrate ESLint plugins from file paths in the same repo currently (e.g. if you have `../eslint-plugin-myplugin` in your `eslint.config.mjs`). You will need to copy them over into the `jsPlugins` manually. See [the JS Plugins docs]() for more info.
|
|
88
|
+
|
|
89
|
+
**`globals` field with large number of values**
|
|
90
|
+
|
|
91
|
+
If you end up with a very large list of values for the `globals` field, it's likely because your version of the `globals` npm package is older (or newer!) than the one used in `@oxlint/migrate`.
|
|
92
|
+
|
|
93
|
+
You can generally fix this by updating the `globals` package to the latest version so we can recognize the relevant globals and handle it as a simple `env` field.
|
|
94
|
+
|
|
95
|
+
For example, this is a good `.oxlintrc.json` and means the globals used by your ESLint config were recognized:
|
|
96
|
+
|
|
97
|
+
```jsonc
|
|
98
|
+
{
|
|
99
|
+
"env": {
|
|
100
|
+
"browser": true,
|
|
101
|
+
},
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
And this is bad:
|
|
106
|
+
|
|
107
|
+
```jsonc
|
|
108
|
+
{
|
|
109
|
+
"globals": {
|
|
110
|
+
"window": "readonly",
|
|
111
|
+
"document": "readonly",
|
|
112
|
+
"navigator": "readonly",
|
|
113
|
+
// ...and a few hundred more
|
|
114
|
+
},
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Oxlint can potentially lint more files by default**
|
|
119
|
+
|
|
120
|
+
If you extend certain ESLint configs (e.g. the airbnb config), they can disable many - or even all - rules for specific files or file types. And this is not always obvious to the end-user.
|
|
121
|
+
|
|
122
|
+
Depending on how this is implemented by the given config, these behaviors may not migrate to your Oxlint config. If you see certain files that you do not want to run Oxlint on which the migrator did not handle, you can add the relevant patterns to the `ignorePatterns` field in `.oxlintrc.json`.
|
|
123
|
+
|
|
124
|
+
**Not all ESLint plugins will work with JS Plugins**
|
|
125
|
+
|
|
126
|
+
The JS Plugins API supports almost all ESLint v9+ plugins for linting JS/TS/JSX/TSX files, but there are still some minor holes in support. See the [JS Plugins documentation](https://oxc.rs/docs/guide/usage/linter/js-plugins.html) for specifics.
|
|
127
|
+
|
|
128
|
+
For example, if you currently use `eslint-plugin-prettier`, it will not work as a JS Plugin, as we do not support custom parsers for JS Plugins. To replace the functionality of `eslint-plugin-prettier`, you can use `prettier --check` in CI and/or your git pre-commit hooks to ensure code formatting is enforced.
|
|
129
|
+
|
|
130
|
+
You could also consider [replacing Prettier with Oxfmt](https://oxc.rs/docs/guide/usage/formatter/migrate-from-prettier.html).
|
|
131
|
+
|
|
132
|
+
Note that `eslint-config-prettier` is different from the prettier plugin, and _will_ be migrated fine, as it's just a config to disable formatting-related ESLint rules, not an actual plugin.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { a as rules_exports, i as nurseryRules, n as preFixForJsPlugins, r as isOffValue, t as src_default } from "../src-BMWXAQvA.mjs";
|
|
3
3
|
import { program } from "commander";
|
|
4
4
|
import { existsSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
@@ -17,9 +17,9 @@ const FLAT_CONFIG_FILENAMES = [
|
|
|
17
17
|
"eslint.config.mts",
|
|
18
18
|
"eslint.config.cts"
|
|
19
19
|
];
|
|
20
|
-
const getAutodetectedEslintConfigName = (cwd
|
|
20
|
+
const getAutodetectedEslintConfigName = (cwd) => {
|
|
21
21
|
for (const filename of FLAT_CONFIG_FILENAMES) {
|
|
22
|
-
const filePath = path.join(cwd
|
|
22
|
+
const filePath = path.join(cwd, filename);
|
|
23
23
|
if (existsSync(filePath)) return filePath;
|
|
24
24
|
}
|
|
25
25
|
};
|
|
@@ -40,7 +40,7 @@ const loadESLintConfig = async (filePath) => {
|
|
|
40
40
|
|
|
41
41
|
//#endregion
|
|
42
42
|
//#region package.json
|
|
43
|
-
var version = "1.
|
|
43
|
+
var version = "1.43.0";
|
|
44
44
|
|
|
45
45
|
//#endregion
|
|
46
46
|
//#region src/walker/comments/replaceRuleDirectiveComment.ts
|
|
@@ -211,8 +211,8 @@ function partialAstroSourceTextLoader(sourceText) {
|
|
|
211
211
|
pos = frontmatterEndDelimiter + 3;
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
|
-
results.push(...extractScriptBlocks(sourceText, pos, Number.MAX_SAFE_INTEGER, false).map((sourceText
|
|
215
|
-
return Object.assign(sourceText
|
|
214
|
+
results.push(...extractScriptBlocks(sourceText, pos, Number.MAX_SAFE_INTEGER, false).map((sourceText) => {
|
|
215
|
+
return Object.assign(sourceText, {
|
|
216
216
|
lang: `ts`,
|
|
217
217
|
sourceType: `module`
|
|
218
218
|
});
|
|
@@ -227,7 +227,7 @@ const getComments = (absoluteFilePath, partialSourceText, options) => {
|
|
|
227
227
|
lang: partialSourceText.lang,
|
|
228
228
|
sourceType: partialSourceText.sourceType
|
|
229
229
|
});
|
|
230
|
-
if (parserResult.errors.length > 0) options.reporter?.
|
|
230
|
+
if (parserResult.errors.length > 0) options.reporter?.addWarning(`${absoluteFilePath}: failed to parse`);
|
|
231
231
|
return parserResult.comments;
|
|
232
232
|
};
|
|
233
233
|
function replaceCommentsInSourceText(absoluteFilePath, partialSourceText, options) {
|
|
@@ -241,7 +241,7 @@ function replaceCommentsInSourceText(absoluteFilePath, partialSourceText, option
|
|
|
241
241
|
}
|
|
242
242
|
} catch (error) {
|
|
243
243
|
if (error instanceof Error) {
|
|
244
|
-
options.reporter?.
|
|
244
|
+
options.reporter?.addWarning(`${absoluteFilePath}, char offset ${comment.start + partialSourceText.offset}: ${error.message}`);
|
|
245
245
|
continue;
|
|
246
246
|
}
|
|
247
247
|
throw error;
|
|
@@ -258,13 +258,13 @@ function replaceCommentsInFile(absoluteFilePath, fileContent, options) {
|
|
|
258
258
|
|
|
259
259
|
//#endregion
|
|
260
260
|
//#region src/walker/index.ts
|
|
261
|
-
const walkAndReplaceProjectFiles = (projectFiles, readFileSync
|
|
261
|
+
const walkAndReplaceProjectFiles = (projectFiles, readFileSync, writeFile, options) => {
|
|
262
262
|
return Promise.all(projectFiles.map((file) => {
|
|
263
|
-
const sourceText = readFileSync
|
|
263
|
+
const sourceText = readFileSync(file);
|
|
264
264
|
if (!sourceText) return Promise.resolve();
|
|
265
265
|
const newSourceText = replaceCommentsInFile(file, sourceText, options);
|
|
266
266
|
if (newSourceText === sourceText) return Promise.resolve();
|
|
267
|
-
return writeFile
|
|
267
|
+
return writeFile(file, newSourceText);
|
|
268
268
|
}));
|
|
269
269
|
};
|
|
270
270
|
|
|
@@ -281,20 +281,18 @@ const getAllProjectFiles = () => {
|
|
|
281
281
|
//#endregion
|
|
282
282
|
//#region src/reporter.ts
|
|
283
283
|
var DefaultReporter = class {
|
|
284
|
-
|
|
284
|
+
warnings = /* @__PURE__ */ new Set();
|
|
285
285
|
skippedRules = new Map([
|
|
286
286
|
["nursery", /* @__PURE__ */ new Set()],
|
|
287
287
|
["type-aware", /* @__PURE__ */ new Set()],
|
|
288
|
-
["unsupported", /* @__PURE__ */ new Set()]
|
|
288
|
+
["unsupported", /* @__PURE__ */ new Set()],
|
|
289
|
+
["js-plugins", /* @__PURE__ */ new Set()]
|
|
289
290
|
]);
|
|
290
|
-
|
|
291
|
-
this.
|
|
291
|
+
addWarning(message) {
|
|
292
|
+
this.warnings.add(message);
|
|
292
293
|
}
|
|
293
|
-
|
|
294
|
-
this.
|
|
295
|
-
}
|
|
296
|
-
getReports() {
|
|
297
|
-
return Array.from(this.reports);
|
|
294
|
+
getWarnings() {
|
|
295
|
+
return Array.from(this.warnings);
|
|
298
296
|
}
|
|
299
297
|
markSkipped(rule, category) {
|
|
300
298
|
this.skippedRules.get(category)?.add(rule);
|
|
@@ -306,6 +304,7 @@ var DefaultReporter = class {
|
|
|
306
304
|
const result = {
|
|
307
305
|
nursery: [],
|
|
308
306
|
"type-aware": [],
|
|
307
|
+
"js-plugins": [],
|
|
309
308
|
unsupported: []
|
|
310
309
|
};
|
|
311
310
|
for (const [category, rules] of this.skippedRules) result[category] = Array.from(rules);
|
|
@@ -313,6 +312,92 @@ var DefaultReporter = class {
|
|
|
313
312
|
}
|
|
314
313
|
};
|
|
315
314
|
|
|
315
|
+
//#endregion
|
|
316
|
+
//#region bin/output-formatter.ts
|
|
317
|
+
const CATEGORY_METADATA = {
|
|
318
|
+
nursery: {
|
|
319
|
+
label: "Nursery",
|
|
320
|
+
description: "Experimental:"
|
|
321
|
+
},
|
|
322
|
+
"type-aware": {
|
|
323
|
+
label: "Type-aware",
|
|
324
|
+
description: "Requires TS info:"
|
|
325
|
+
},
|
|
326
|
+
"js-plugins": {
|
|
327
|
+
label: "JS Plugins",
|
|
328
|
+
description: "Requires JS plugins:"
|
|
329
|
+
},
|
|
330
|
+
unsupported: { label: "Unsupported" }
|
|
331
|
+
};
|
|
332
|
+
const MAX_LABEL_LENGTH = Math.max(...Object.values(CATEGORY_METADATA).map((meta) => meta.label.length));
|
|
333
|
+
/**
|
|
334
|
+
* Formats a category summary as either inline (with example) or vertical list
|
|
335
|
+
*/
|
|
336
|
+
function formatCategorySummary(count, category, rules, showAll) {
|
|
337
|
+
const meta = CATEGORY_METADATA[category];
|
|
338
|
+
if (!showAll) {
|
|
339
|
+
const maxRules = 3;
|
|
340
|
+
const exampleList = rules.slice(0, maxRules).join(", ");
|
|
341
|
+
const suffix = count > maxRules ? ", and more" : "";
|
|
342
|
+
const prefix = meta.description ? `${meta.description} ` : "";
|
|
343
|
+
return ` - ${String(count).padStart(3)} ${meta.label.padEnd(MAX_LABEL_LENGTH)} (${prefix}${exampleList}${suffix})\n`;
|
|
344
|
+
}
|
|
345
|
+
let output = ` - ${count} ${meta.label}\n`;
|
|
346
|
+
for (const rule of rules) output += ` - ${rule}\n`;
|
|
347
|
+
return output;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Detects which CLI flags are missing and could enable more rules
|
|
351
|
+
*/
|
|
352
|
+
function detectMissingFlags(byCategory, cliOptions) {
|
|
353
|
+
const missingFlags = [];
|
|
354
|
+
if (byCategory.nursery.length > 0 && !cliOptions.withNursery) missingFlags.push("--with-nursery");
|
|
355
|
+
if (byCategory["type-aware"].length > 0 && !cliOptions.typeAware) missingFlags.push("--type-aware");
|
|
356
|
+
if (byCategory["js-plugins"].length > 0 && !cliOptions.jsPlugins) missingFlags.push("--js-plugins");
|
|
357
|
+
return missingFlags;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Formats the complete migration output message
|
|
361
|
+
*/
|
|
362
|
+
function formatMigrationOutput(data) {
|
|
363
|
+
let output = "";
|
|
364
|
+
const showAll = data.cliOptions.details || false;
|
|
365
|
+
if (data.enabledRulesCount === 0) output += `\n⚠️ ${data.outputFileName} created with no rules enabled.\n`;
|
|
366
|
+
else output += `\n✨ ${data.outputFileName} created with ${data.enabledRulesCount} rules.\n`;
|
|
367
|
+
const byCategory = data.skippedRulesByCategory;
|
|
368
|
+
const nurseryCount = byCategory.nursery.length;
|
|
369
|
+
const typeAwareCount = byCategory["type-aware"].length;
|
|
370
|
+
const unsupportedCount = byCategory.unsupported.length;
|
|
371
|
+
const jsPluginsCount = byCategory["js-plugins"].length;
|
|
372
|
+
const totalSkipped = nurseryCount + typeAwareCount + unsupportedCount + jsPluginsCount;
|
|
373
|
+
if (totalSkipped > 0) {
|
|
374
|
+
output += `\n Skipped ${totalSkipped} rules:\n`;
|
|
375
|
+
if (nurseryCount > 0) output += formatCategorySummary(nurseryCount, "nursery", byCategory.nursery, showAll);
|
|
376
|
+
if (typeAwareCount > 0) output += formatCategorySummary(typeAwareCount, "type-aware", byCategory["type-aware"], showAll);
|
|
377
|
+
if (jsPluginsCount > 0) output += formatCategorySummary(jsPluginsCount, "js-plugins", byCategory["js-plugins"], showAll);
|
|
378
|
+
if (unsupportedCount > 0) output += formatCategorySummary(unsupportedCount, "unsupported", byCategory.unsupported, showAll);
|
|
379
|
+
if (!showAll) {
|
|
380
|
+
const maxExamples = 3;
|
|
381
|
+
if (nurseryCount > maxExamples || typeAwareCount > maxExamples || unsupportedCount > maxExamples || jsPluginsCount > maxExamples) output += `\n Tip: Use --details to see the full list.\n`;
|
|
382
|
+
}
|
|
383
|
+
const missingFlags = detectMissingFlags(byCategory, data.cliOptions);
|
|
384
|
+
if (missingFlags.length > 0) {
|
|
385
|
+
const eslintConfigArg = data.eslintConfigPath ? ` ${path.basename(data.eslintConfigPath)}` : "";
|
|
386
|
+
output += `\n👉 Re-run with flags to include more:\n`;
|
|
387
|
+
output += ` npx @oxlint/migrate${eslintConfigArg} ${missingFlags.join(" ")}\n`;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
if (data.enabledRulesCount > 0) {
|
|
391
|
+
output += `\n🚀 Next:\n`;
|
|
392
|
+
output += ` npx oxlint .\n`;
|
|
393
|
+
}
|
|
394
|
+
return output;
|
|
395
|
+
}
|
|
396
|
+
function displayMigrationResult(outputMessage, warnings) {
|
|
397
|
+
console.log(outputMessage);
|
|
398
|
+
for (const warning of warnings) console.warn(warning);
|
|
399
|
+
}
|
|
400
|
+
|
|
316
401
|
//#endregion
|
|
317
402
|
//#region bin/oxlint-migrate.ts
|
|
318
403
|
const cwd = process.cwd();
|
|
@@ -323,7 +408,22 @@ const getFileContent = (absoluteFilePath) => {
|
|
|
323
408
|
return;
|
|
324
409
|
}
|
|
325
410
|
};
|
|
326
|
-
|
|
411
|
+
/**
|
|
412
|
+
* Count enabled rules (excluding "off" rules) from both rules and overrides
|
|
413
|
+
*/
|
|
414
|
+
const countEnabledRules = (config) => {
|
|
415
|
+
const enabledRules = /* @__PURE__ */ new Set();
|
|
416
|
+
if (config.rules) {
|
|
417
|
+
for (const [ruleName, ruleValue] of Object.entries(config.rules)) if (!isOffValue(ruleValue)) enabledRules.add(ruleName);
|
|
418
|
+
}
|
|
419
|
+
if (config.overrides && Array.isArray(config.overrides)) {
|
|
420
|
+
for (const override of config.overrides) if (override.rules) {
|
|
421
|
+
for (const [ruleName, ruleValue] of Object.entries(override.rules)) if (!isOffValue(ruleValue)) enabledRules.add(ruleName);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return enabledRules.size;
|
|
425
|
+
};
|
|
426
|
+
program.name("oxlint-migrate").version(version).argument("[eslint-config]", "The path to the eslint v9 config file").option("--output-file <file>", "The oxlint configuration file where to eslint v9 rules will be written to", ".oxlintrc.json").option("--merge", "Merge eslint configuration with an existing .oxlintrc.json configuration", false).option("--with-nursery", "Include oxlint rules which are currently under development", false).option("--replace-eslint-comments", "Search in the project files for eslint comments and replaces them with oxlint. Some eslint comments are not supported and will be reported.").option("--type-aware", "Includes supported type-aware rules. Needs the same flag in `oxlint` to enable it.").option("--js-plugins", "Tries to convert unsupported oxlint plugins with `jsPlugins`.").option("--details", "List rules that could not be migrated to oxlint.", false).action(async (filePath) => {
|
|
327
427
|
const cliOptions = program.opts();
|
|
328
428
|
const oxlintFilePath = path.join(cwd, cliOptions.outputFile);
|
|
329
429
|
const reporter = new DefaultReporter();
|
|
@@ -335,7 +435,7 @@ program.name("oxlint-migrate").version(version).argument("[eslint-config]", "The
|
|
|
335
435
|
jsPlugins: !!cliOptions.jsPlugins
|
|
336
436
|
};
|
|
337
437
|
if (cliOptions.replaceEslintComments) {
|
|
338
|
-
await walkAndReplaceProjectFiles(await getAllProjectFiles(), (filePath
|
|
438
|
+
await walkAndReplaceProjectFiles(await getAllProjectFiles(), (filePath) => getFileContent(filePath), (filePath, content) => writeFile(filePath, content, "utf-8"), options);
|
|
339
439
|
return;
|
|
340
440
|
}
|
|
341
441
|
if (filePath === void 0) filePath = getAutodetectedEslintConfigName(cwd);
|
|
@@ -352,7 +452,19 @@ program.name("oxlint-migrate").version(version).argument("[eslint-config]", "The
|
|
|
352
452
|
const oxlintConfig = "default" in eslintConfigs ? await src_default(eslintConfigs.default, config, options) : await src_default(eslintConfigs, config, options);
|
|
353
453
|
if (existsSync(oxlintFilePath)) renameSync(oxlintFilePath, `${oxlintFilePath}.bak`);
|
|
354
454
|
writeFileSync(oxlintFilePath, JSON.stringify(oxlintConfig, null, 2));
|
|
355
|
-
|
|
455
|
+
const enabledRulesCount = countEnabledRules(oxlintConfig);
|
|
456
|
+
displayMigrationResult(formatMigrationOutput({
|
|
457
|
+
outputFileName: cliOptions.outputFile,
|
|
458
|
+
enabledRulesCount,
|
|
459
|
+
skippedRulesByCategory: reporter.getSkippedRulesByCategory(),
|
|
460
|
+
cliOptions: {
|
|
461
|
+
withNursery: !!cliOptions.withNursery,
|
|
462
|
+
typeAware: !!cliOptions.typeAware,
|
|
463
|
+
details: !!cliOptions.details,
|
|
464
|
+
jsPlugins: !!cliOptions.jsPlugins
|
|
465
|
+
},
|
|
466
|
+
eslintConfigPath: filePath
|
|
467
|
+
}), reporter.getWarnings());
|
|
356
468
|
});
|
|
357
469
|
program.parse();
|
|
358
470
|
|