diff --git a/CHANGELOG.md b/CHANGELOG.md index c8361895b..5c14fd348 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange ### Added - [`no-named-default`, `no-default-export`, `prefer-default-export`, `no-named-export`, `export`, `named`, `namespace`, `no-unused-modules`]: support arbitrary module namespace names ([#2358], thanks [@sosukesuzuki]) - [`no-dynamic-require`]: support dynamic import with espree ([#2371], thanks [@sosukesuzuki]) +- [`no-relative-packages`]: add fixer ([#2381], thanks [@forivall]) ### Fixed - [`default`]: `typescript-eslint-parser`: avoid a crash on exporting as namespace (thanks [@ljharb]) @@ -969,6 +970,7 @@ for info on changes for earlier releases. [`memo-parser`]: ./memo-parser/README.md +[#2381]: https://github.com/import-js/eslint-plugin-import/pull/2381 [#2378]: https://github.com/import-js/eslint-plugin-import/pull/2378 [#2371]: https://github.com/import-js/eslint-plugin-import/pull/2371 [#2367]: https://github.com/import-js/eslint-plugin-import/pull/2367 diff --git a/docs/rules/no-relative-packages.md b/docs/rules/no-relative-packages.md index d5a068493..a989c12a2 100644 --- a/docs/rules/no-relative-packages.md +++ b/docs/rules/no-relative-packages.md @@ -5,6 +5,7 @@ Use this rule to prevent importing packages through relative paths. It's useful in Yarn/Lerna workspaces, were it's possible to import a sibling package using `../package` relative path, while direct `package` is the correct one. ++(fixable) The `--fix` option on the [command line] automatically fixes problems reported by this rule. ### Examples diff --git a/src/rules/no-relative-packages.js b/src/rules/no-relative-packages.js index 17406e80e..7bf1ce5ce 100644 --- a/src/rules/no-relative-packages.js +++ b/src/rules/no-relative-packages.js @@ -6,6 +6,11 @@ import moduleVisitor, { makeOptionsSchema } from 'eslint-module-utils/moduleVisi import importType from '../core/importType'; import docsUrl from '../docsUrl'; +/** @param {string} filePath */ +function toPosixPath(filePath) { + return filePath.replace(/\\/g, '/'); +} + function findNamedPackage(filePath) { const found = readPkgUp({ cwd: filePath }); if (found.pkg && !found.pkg.name) { @@ -42,6 +47,8 @@ function checkImportForRelativePackage(context, importPath, node) { context.report({ node, message: `Relative import from another package is not allowed. Use \`${properImport}\` instead of \`${importPath}\``, + fix: fixer => fixer.replaceText(node, JSON.stringify(toPosixPath(properImport))) + , }); } } @@ -52,6 +59,7 @@ module.exports = { docs: { url: docsUrl('no-relative-packages'), }, + fixable: 'code', schema: [makeOptionsSchema()], }, diff --git a/tests/src/rules/no-relative-packages.js b/tests/src/rules/no-relative-packages.js index 1a706387c..2d27bcc91 100644 --- a/tests/src/rules/no-relative-packages.js +++ b/tests/src/rules/no-relative-packages.js @@ -47,6 +47,7 @@ ruleTester.run('no-relative-packages', rule, { line: 1, column: 17, } ], + output: 'import foo from "package-named"', }), test({ code: 'import foo from "../package-named"', @@ -56,6 +57,7 @@ ruleTester.run('no-relative-packages', rule, { line: 1, column: 17, } ], + output: 'import foo from "package-named"', }), test({ code: 'import foo from "../package-scoped"', @@ -65,6 +67,7 @@ ruleTester.run('no-relative-packages', rule, { line: 1, column: 17, } ], + output: `import foo from "@scope/package-named"`, }), test({ code: 'import bar from "../bar"', @@ -74,6 +77,7 @@ ruleTester.run('no-relative-packages', rule, { line: 1, column: 17, } ], + output: `import bar from "eslint-plugin-import/tests/files/bar"`, }), ], });