diff --git a/scm-ui/eslint-config/src/__resources__/AllowRootImport.tsx b/scm-ui/eslint-config/src/__resources__/AllowRootImport.tsx new file mode 100644 index 0000000000..c2a8396f93 --- /dev/null +++ b/scm-ui/eslint-config/src/__resources__/AllowRootImport.tsx @@ -0,0 +1,6 @@ +import React, { FC } from "react"; +import { Button } from "@scm-manager/ui-components"; + +const SpecialButton: FC = () => ; + +export default SpecialButton; diff --git a/scm-ui/eslint-config/src/__resources__/AvoidSourceImport.tsx b/scm-ui/eslint-config/src/__resources__/AvoidSourceImport.tsx new file mode 100644 index 0000000000..75be029f6a --- /dev/null +++ b/scm-ui/eslint-config/src/__resources__/AvoidSourceImport.tsx @@ -0,0 +1,6 @@ +import React, { FC } from "react"; +import Button from "@scm-manager/ui-components/src/buttons/Button"; + +const SpecialButton: FC = () => ; + +export default SpecialButton; diff --git a/scm-ui/eslint-config/src/index.js b/scm-ui/eslint-config/src/index.js index 625e5bfb55..ac998d81fb 100644 --- a/scm-ui/eslint-config/src/index.js +++ b/scm-ui/eslint-config/src/index.js @@ -37,6 +37,10 @@ const nodeConfiguration = { } }; +const restrictImportConfig = { + patterns: ["@scm-manager/*/*"] +}; + const typescriptConfiguration = { parser: "@typescript-eslint/parser", extends: ["react-app", "plugin:@typescript-eslint/recommended"], @@ -45,6 +49,7 @@ const typescriptConfiguration = { "@typescript-eslint/ban-ts-ignore": "warn", "no-console": "error", "jsx-a11y/href-no-hash": "off", + "no-restricted-imports": ["error", restrictImportConfig], ...rules } }; diff --git a/scm-ui/eslint-config/src/index.test.js b/scm-ui/eslint-config/src/index.test.js index 55af7ace6f..99acf09da9 100644 --- a/scm-ui/eslint-config/src/index.test.js +++ b/scm-ui/eslint-config/src/index.test.js @@ -25,27 +25,27 @@ const { ESLint } = require("eslint"); const path = require("path"); -describe("should lint files", () => { - const eslint = new ESLint(); - const resource = path.join(__dirname, "__resources__"); +const eslint = new ESLint(); +const resource = path.join(__dirname, "__resources__"); - const lint = async file => { - const results = await eslint.lintFiles([path.join(resource, file)]); +const lint = async file => { + const results = await eslint.lintFiles([path.join(resource, file)]); - const { messages } = results[0]; + const { messages } = results[0]; - const warnings = messages.filter(m => m.severity === 1).map(m => m.ruleId); - const errors = messages.filter(m => m.severity === 2).map(m => m.ruleId); - return { - errors, - warnings - }; + const warnings = messages.filter(m => m.severity === 1).map(m => m.ruleId); + const errors = messages.filter(m => m.severity === 2).map(m => m.ruleId); + return { + errors, + warnings }; +}; - const expectContains = (results, ...ids) => { - ids.forEach(id => expect(results).toContain(id)); - }; +const expectContains = (results, ...ids) => { + ids.forEach(id => expect(results).toContain(id)); +}; +describe("should lint different file types", () => { it("should lint tsx files", async () => { const { errors, warnings } = await lint("TypescriptWithJsx.tsx"); expectContains(errors, "no-console", "quotes", "semi"); @@ -64,3 +64,16 @@ describe("should lint files", () => { expectContains(warnings, "prettier/prettier"); }); }); + +describe("lint @scm-manager imports", () => { + it("should return an error for source imports", async () => { + const { errors } = await lint("AvoidSourceImport.tsx"); + expectContains(errors, "no-restricted-imports"); + }); + + it("should return no error for package imports", async () => { + const { errors, warnings } = await lint("AllowRootImport.tsx"); + expect(errors).toEqual([]); + expect(warnings).toEqual([]); + }); +});