Skip to content

Commit

Permalink
BC-8147 - Upgrade to ESLint 9 (#3411)
Browse files Browse the repository at this point in the history
This PR upgrades ESLint 8 to ESLint 9.

* change eslintrc format to flat config
* remove .eslintignore, move it to the ignores object
* adjust custom plugin accordingly
* change to flat config in eslint webpack plugin
* upgrade to eslint9
* exclude eslint config from sonarcloud coverage
* move mock-store-module to test folder
* refactor SonarCloud configuration and github action

---------

Co-authored-by: SevenWaysDP <[email protected]>
  • Loading branch information
NFriedo and SevenWaysDP authored Oct 28, 2024
1 parent dda3247 commit e8dc494
Show file tree
Hide file tree
Showing 118 changed files with 1,788 additions and 1,543 deletions.
6 changes: 0 additions & 6 deletions .eslintignore

This file was deleted.

104 changes: 0 additions & 104 deletions .eslintrc.js

This file was deleted.

15 changes: 3 additions & 12 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,13 @@ jobs:
NODE_OPTIONS: "--unhandled-rejections=warn"
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
distribution: "temurin"
java-version: "17"
- name: SonarCloud upload coverage
uses: SonarSource/[email protected]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONARCLOUD_TOKEN }}
with:
args: >
-Dsonar.organization=schulcloud-verbund
-Dsonar.projectKey=hpi-schul-cloud_nuxt-client
-Dsonar.sources=.
-Dsonar.exclusions=src/serverApi/**/*.*,src/fileStorageApi/**/*.*,src/h5pEditorApi/**/*.*
-Dsonar.coverage.exclusions=tests/**/*.*,**/*.unit.ts,**/*.unit.js
-Dsonar.cpd.exclusions=tests/**/*.*,**/*.unit.ts,**/*.unit.js,**/locales/*.ts
-Dsonar.javascript.lcov.reportPaths=./coverage/lcov.info

lint:
runs-on: ubuntu-latest
Expand All @@ -56,4 +47,4 @@ jobs:
- name: npm ci
run: npm ci --prefer-offline --no-audit
- name: npm run lint
run: npm run lint
run: npm run lint
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ RUN apt update && apt install -y g++ libcairo2-dev libpango1.0-dev libjpeg-dev l
WORKDIR /app

COPY package.json package-lock.json ./
COPY lib/eslint-plugin-schulcloud ./lib/eslint-plugin-schulcloud
RUN npm ci

COPY babel.config.js .eslintrc.js LICENSE.md .prettierrc.js tsconfig.json tsconfig.build.json .eslintignore .prettierignore ./
COPY babel.config.js eslint.config.js LICENSE.md .prettierrc.js tsconfig.json tsconfig.build.json .prettierignore ./
COPY lib/eslint-plugin-schulcloud ./lib/eslint-plugin-schulcloud
COPY public ./public
COPY src ./src
COPY config/webpack ./config/webpack
Expand Down
1 change: 1 addition & 0 deletions config/webpack/webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ module.exports = {
extensions: [".js", ".jsx", ".vue", ".ts", ".tsx"],
failOnWarning: false,
failOnError: true,
configType: "flat",
}),
],

Expand Down
142 changes: 142 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
const js = require("@eslint/js");
const pluginVue = require("eslint-plugin-vue");
const vueTsEslintConfig = require("@vue/eslint-config-typescript");
const schulcloud = require("./lib/eslint-plugin-schulcloud");
const eslintPluginPrettierRecommended = require("eslint-plugin-prettier/recommended");
const globals = require("globals");

module.exports = [
...pluginVue.configs["flat/essential"],
js.configs.recommended,
...vueTsEslintConfig({
extends: ["recommended"],
supportedScriptLangs: {
ts: true,

// [!DISCOURAGED]
// Set to `true` to allow plain `<script>` or `<script setup>` blocks.
// This might result-in false positive or negatives in some rules for `.vue` files.
// Note you also need to configure `allowJs: true` and `checkJs: true`
// in corresponding `tsconfig.json` files.
js: true,
},
}),
eslintPluginPrettierRecommended,

{
ignores: [
".vscode/**",
"node_modules/**",
"**/dist/**",
"src/serverApi/**",
"src/fileStorageApi/**",
"src/h5pEditorApi/**",
],
},
{
languageOptions: {
ecmaVersion: "latest",
globals: {
...globals.node,
},
},
plugins: {
schulcloud,
},
rules: {
"@typescript-eslint/ban-ts-comment": "error",
"@typescript-eslint/no-empty-function": "error",
"@typescript-eslint/no-empty-object-type": [
"error",
{ allowInterfaces: "with-single-extends" },
],
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-inferrable-types": "error",
"@typescript-eslint/no-require-imports": "warn",
"@typescript-eslint/no-restricted-imports": [
"warn",
{
patterns: [
{
group: [
"@data-*/*",
"@feature-*/*",
"@page-*/*",
"@ui-*/*",
"@util-*/*",
],
message: "Do not deep import into a module",
},
{
group: ["@/modules/data/*", "*/../data/*", "../**/data/*"],
message:
"Data-Modules have to be imported using the pattern '@data-<name>'",
},
{
group: [
"@/modules/feature/*",
"*/../feature/*",
"../**/feature/*",
],
message:
"Feature-Modules have to be imported using the pattern '@feature-<name>'",
},
{
group: ["@/modules/page/*", "*/../page/*", "../**/page/*/*"],
message:
"Page-Modules have to be imported using the pattern '@page-<name>'",
},
{
group: ["@/modules/ui/*", "*/../ui/*", "../**/ui/*/*"],
message:
"Ui-Modules have to be imported using the pattern '@ui-<name>'",
},
{
group: ["@/modules/util/*", "*/../util/*", "../**/util/*/*"],
message:
"Util-Modules have to be imported using the pattern '@util-<name>'",
},
],
},
],
"@typescript-eslint/no-unused-vars": "warn",
"no-console": process.env.NODE_ENV === "production" ? "off" : "warn",
"no-debugger": process.env.NODE_ENV === "production" ? "off" : "warn",
"no-empty": "error",
"no-irregular-whitespace": "error",
"no-prototype-builtins": "error",
"no-undef": "warn",
"no-unused-vars": "off", // disable the base rule for @typescript-eslint/no-unused-vars
"no-useless-escape": "error",
"no-var": "error",
"prefer-const": "error",
"prettier/prettier": "error",
"schulcloud/material-icon-imports": "error",
"vue/html-self-closing": [
"error",
{
html: {
void: "always",
},
},
],
"vue/multi-word-component-names": "off", // TODO - make a final decision about this rule
"vue/no-mutating-props": "error",
"vue/no-setup-props-reactivity-loss": "error",
"vue/no-useless-template-attributes": "error",
"vue/no-v-html": "error",
"vue/no-v-text-v-html-on-component": "error",
},
},
{
files: ["**/*.unit.{j,t}s?(x)", "tests/**"],
languageOptions: {
globals: {
...globals.jest,
mount: "readonly",
shallowMount: "readonly",
fail: "readonly",
},
},
},
];
11 changes: 6 additions & 5 deletions lib/eslint-plugin-schulcloud/material-icon-imports.unit.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
"use strict";

const { RuleTester } = require("eslint");
const rule = require("./material-icon-imports.js");
const materialIconImportRule = require("./material-icon-imports.js");

const ruleTester = new RuleTester({
parserOptions: { ecmaVersion: 2020, sourceType: "module" },
});
global.structuredClone = (value) => {
return JSON.parse(JSON.stringify(value));
};
const ruleTester = new RuleTester();

ruleTester.run("material-icon-imports", rule, {
ruleTester.run("material-icon-imports", materialIconImportRule, {
valid: [
{
code: `import { mdiCheck } from "@icons/material";`,
Expand Down
Loading

0 comments on commit e8dc494

Please sign in to comment.