Skip to content

Commit

Permalink
Update to eslint 9 (#40555)
Browse files Browse the repository at this point in the history
Eslint 9 brings a new config format, which means this PR also rewrites
all the eslint configs. I took the opportunity to clean them up
(although a good bit of that wound up in earlier PRs), and added code to
fetch the textdomain from composer.json and whether the project uses
React from package.json so we don't need to have so many boilerplate
configs that just set a textdomain or enable React rules.
  • Loading branch information
anomiex authored Dec 11, 2024
1 parent 4481373 commit 9e3ae2f
Show file tree
Hide file tree
Showing 298 changed files with 1,917 additions and 1,656 deletions.
1 change: 0 additions & 1 deletion .eslintignore

This file was deleted.

6 changes: 2 additions & 4 deletions .eslintignore.root
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
# Named ".eslintignore.root" rather than ".eslintignore" because there's no way to stop eslint from reading this after processing ignorePatterns in .eslintrc.js. Sigh.
# Our standard eslint config reads .gitignore and .eslintignore to determine what to ignore.
# This file is named ".eslintignore.root" rather than ".eslintignore" because eslint, despite not using it, still complains if it exists.

# Stuff not to lint in general.
*.min.js
**/changelog/

# Storybook files
**/@(storybook|stories)/**/*.js

# Ignored by default, but we should check it
!.github/
!.prettierrc.js
Expand Down
11 changes: 0 additions & 11 deletions .eslintrc.js

This file was deleted.

9 changes: 5 additions & 4 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
.gitkeep production-exclude

# We don't need these files in any production mirror.
.eslintrc.js production-exclude
jsconfig.json production-exclude
tsconfig.json production-exclude
**/.phan/** production-exclude
eslint.config.mjs production-exclude
.eslintignore production-exclude
jsconfig.json production-exclude
tsconfig.json production-exclude
**/.phan/** production-exclude
**/.w.org-assets/** production-exclude
9 changes: 0 additions & 9 deletions .github/.eslintrc.js

This file was deleted.

11 changes: 11 additions & 0 deletions .github/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import makeBaseConfig from 'jetpack-js-tools/eslintrc/base.mjs';

export default [
...makeBaseConfig( import.meta.url, { envs: [ 'node' ] } ),
{
rules: {
'no-console': 'off',
'n/no-process-exit': 'off',
},
},
];
51 changes: 13 additions & 38 deletions .github/files/lint-project-structure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -222,14 +222,6 @@ for PROJECT in projects/*/*; do
fi
fi

# - If a project uses react, it should include the react linting rules too.
if [[ -e "$PROJECT/package.json" ]] && jq -e '.dependencies.react // .devDependencies.react' "$PROJECT/package.json" >/dev/null && ! git grep eslintrc/react "$PROJECT"/.eslintrc.* &>/dev/null; then
EXIT=1
TMP=$( git ls-files "$PROJECT"/.eslintrc.* | head -n 1 ) || true
[[ -n "$TMP" ]] && TMP=" file=$TMP"
echo "::error${TMP}::Project $SLUG appears to use React but does not extend jetpack-js-tools/eslintrc/react in its eslint config. Please add that."
fi

# - composer.json must exist.
if [[ ! -e "$PROJECT/composer.json" ]]; then
EXIT=1
Expand Down Expand Up @@ -520,54 +512,35 @@ done

# - Text domains in phpcs config should match composer.json.
debug "Checking package textdomain usage in phpcs config"
for FILE in $(git -c core.quotepath=off ls-files 'projects/packages/**/.phpcs.dir.xml'); do
for FILE in $(git -c core.quotepath=off ls-files 'projects/*/**/.phpcs.dir.xml'); do
DOM="$(php -r '$doc = new DOMDocument(); $doc->load( $argv[1] ); $xpath = new DOMXPath( $doc ); echo $xpath->evaluate( "string(//rule[@ref=\"WordPress.WP.I18n\"]/properties/property[@name=\"text_domain\"]/element/@value)" );' "$FILE")"
[[ -z "$DOM" ]] && continue
DIR="$FILE"
while ! [[ "$DIR" =~ ^projects/[^/]*/[^/]*$ ]]; do
DIR="${DIR%/*}"
done
SLUG="${DIR#projects/}"
DOM2="$(jq -r '.extra.textdomain // ""' "$DIR/composer.json")"
if [[ "$SLUG" == plugins/* ]]; then
WHAT='`.extra.wp-plugin-slug` or `.extra.beta-plugin-slug`'
DOM2="$(jq -r '.extra["wp-plugin-slug"] // .extra["beta-plugin-slug"] // ""' "$DIR/composer.json")"
else
WHAT='`.extra.textdomain`'
DOM2="$(jq -r '.extra.textdomain // ""' "$DIR/composer.json")"
fi
if [[ "$DOM" != "$DOM2" ]]; then
EXIT=1
LINE=$(grep --line-number --max-count=1 'name="text_domain"' "$FILE" || true)
if [[ -n "$LINE" ]]; then
LINE=",line=${LINE%%:*}"
fi
if [[ -z "$DOM2" ]]; then
echo "::error file=$FILE$LINE::PHPCS config sets textdomain \"$DOM\", but $SLUG's composer.json does not set \`.extra.textdomain\`."
echo "::error file=$FILE$LINE::PHPCS config sets textdomain \"$DOM\", but $SLUG's composer.json does not set $WHAT."
else
echo "::error file=$FILE$LINE::PHPCS config sets textdomain \"$DOM\", but $SLUG's composer.json sets domain \"$DOM2\"."
fi
fi
done

# - Text domains in eslint config should match composer.json.
debug "Checking package textdomain usage in eslint config"
for FILE in $(git -c core.quotepath=off ls-files 'projects/packages/**/.eslintrc.js' 'projects/packages/**/.eslintrc.cjs'); do
DOM="$(node -e 'const x = require( `./${ process.argv[1] }` ); console.log( x.rules?.["@wordpress/i18n-text-domain"]?.[1]?.allowedTextDomain ?? "" );' "$FILE")"
[[ -z "$DOM" ]] && continue
DIR="$FILE"
while ! [[ "$DIR" =~ ^projects/[^/]*/[^/]*$ ]]; do
DIR="${DIR%/*}"
done
SLUG="${DIR#projects/}"
DOM2="$(jq -r '.extra.textdomain // ""' "$DIR/composer.json")"
if [[ "$DOM" != "$DOM2" ]]; then
EXIT=1
LINE=$(grep --line-number --max-count=1 'allowedTextDomain' "$FILE" || true)
if [[ -n "$LINE" ]]; then
LINE=",line=${LINE%%:*}"
fi
if [[ -z "$DOM2" ]]; then
echo "::error file=$FILE$LINE::Eslint config sets textdomain \"$DOM\", but $SLUG's composer.json does not set \`.extra.textdomain\`."
else
echo "::error file=$FILE$LINE::Eslint config sets textdomain \"$DOM\", but $SLUG's composer.json sets domain \"$DOM2\"."
fi
fi
done

# - Text domains in block.json should match composer.json.
debug "Checking textdomain usage in block.json"
for FILE in $(git -c core.quotepath=off ls-files 'projects/packages/**/block.json' 'projects/plugins/**/block.json'); do
Expand All @@ -580,8 +553,10 @@ for FILE in $(git -c core.quotepath=off ls-files 'projects/packages/**/block.jso
done
SLUG="${DIR#projects/}"
if [[ "$SLUG" == plugins/* ]]; then
DOM2="$(jq -r '.extra["wp-plugin-slug"] // .extra["wp-theme-slug"] // ""' "$DIR/composer.json")"
WHAT='`.extra.wp-plugin-slug` or `.extra.beta-plugin-slug`'
DOM2="$(jq -r '.extra["wp-plugin-slug"] // .extra["beta-plugin-slug"] // ""' "$DIR/composer.json")"
else
WHAT='`.extra.textdomain`'
DOM2="$(jq -r '.extra.textdomain // ""' "$DIR/composer.json")"
fi
if [[ "$DOM" != "$DOM2" ]]; then
Expand All @@ -591,7 +566,7 @@ for FILE in $(git -c core.quotepath=off ls-files 'projects/packages/**/block.jso
LINE=",line=${LINE%%:*}"
fi
if [[ -z "$DOM2" ]]; then
echo "::error file=$FILE$LINE::block.json sets textdomain \"$DOM\", but $SLUG's composer.json does not set \`.extra.textdomain\`."
echo "::error file=$FILE$LINE::block.json sets textdomain \"$DOM\", but $SLUG's composer.json does not set $WHAT."
else
echo "::error file=$FILE$LINE::block.json sets textdomain \"$DOM\", but $SLUG's composer.json sets domain \"$DOM2\"."
fi
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/linting.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ jobs:
- 'pnpm-lock.yaml'
- '.eslintignore'
- '.eslintignore.root'
- '.eslintrc.*'
- 'eslint.config.*'
- '**/.eslintignore'
- '**/.eslintrc.*'
- '**/eslint.config.*'
# If the excludelist changed, run to ensure newly non-excluded files pass.
- 'tools/eslint-excludelist.json'
misc_excludelist:
Expand Down
5 changes: 5 additions & 0 deletions .pnpmfile.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ function fixDeps( pkg ) {
pkg.peerDependencies[ dep ] = ver.replace( /^\^?/, '>=' );
}
}

// Doesn't really need these at all with eslint 9 and our config.
pkg.peerDependenciesMeta ??= {};
pkg.peerDependenciesMeta[ '@typescript-eslint/eslint-plugin' ] = { optional: true };
pkg.peerDependenciesMeta[ '@typescript-eslint/parser' ] = { optional: true };
}

// Unnecessarily explicit deps. I don't think we really even need @wordpress/babel-preset-default at all.
Expand Down
2 changes: 1 addition & 1 deletion docs/development-environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ To execute them in your local environment, you can use the following commands.
We strongly recommend that you install tools to review your code in your IDE. It will make it easier for you to notice any missing documentation or coding standards you should respect. Most IDEs display warnings and notices inside the editor, making it even easier.

- Jetpack's custom Code Sniffer ruleset is located at `./projects/packages/codesniffer/Jetpack/ruleset.xml`. Depending on your IDE, you can use this path or you may need to use `.phpcs.xml.dist` in the monorepo root.
- For JavaScript, we recommend installing ESLint. Most IDEs come with an ESLint plugin that you can use. Jetpack includes a `.eslintrc.js` file that defines our coding standards.
- For JavaScript, we recommend installing ESLint. Most IDEs come with an ESLint plugin that you can use. Jetpack includes a `eslint.config.mjs` file that defines our coding standards.

## Linting

Expand Down
12 changes: 1 addition & 11 deletions docs/monorepo.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,17 +195,7 @@ The following environment variables are available for all tests:

We use eslint and phpcs to lint JavaScript and PHP code. Projects should comply with the [coding standards](development-environment.md#coding-standards) enforced by these tools.

* Projects may include `.eslintrc.js` to adjust eslint configuration as necessary, but try to keep to the spirit of it.

Note we're using something of a hack to get eslint to read ignore rules from `.gitignore` and per-directory `.eslintignore` files.
Any eslintrc that does `root: true` or an `extends` that extends from an eslintrc that includes the hack will have to do like
```js
const loadIgnorePatterns = require( 'jetpack-js-tools/load-eslint-ignore.js' );
module.exports = {
// Whatever stuff, including `root: true` or `extends`.
ignorePatterns: loadIgnorePatterns( __dirname ),
};
```
* Projects may include `eslint.config.mjs` to adjust eslint configuration as necessary, but try to keep to the spirit of it. Configurations should generally start with `...makeBaseConfig( import.meta.url )` (imported from `jetpack-js-tools/eslintrc/base.mjs`) with any appropriate options, and override from there.
* We're using a fork of phpcs and a custom filter that adds support for per-directory configuration (`.phpcs.dir.xml`) and use of `.gitignore` and `.phpcsignore` files. Again, try to keep to the spirit of things.

### Static Analysis
Expand Down
4 changes: 4 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import autoProjects from 'jetpack-js-tools/eslintrc/auto-projects.mjs';
import makeBaseConfig from 'jetpack-js-tools/eslintrc/base.mjs';

export default [ ...makeBaseConfig( import.meta.url ), ...autoProjects ];
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"cli-setup": "pnpm install && jetpack cli link",
"cli-unlink": "jetpack cli unlink",
"lint": "pnpm run lint-file .",
"lint-changed": "eslint-changed --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.svelte --git",
"lint-file": "eslint --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.svelte",
"lint-changed": "eslint-changed --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.svelte --eslint-options flags='[\"unstable_config_lookup_from_file\"]' --git",
"lint-file": "eslint --flag unstable_config_lookup_from_file",
"lint-required": "ESLINT_IGNORE_REQUIRED=1 pnpm run lint --max-warnings=0",
"php:autofix": "composer phpcs:fix",
"php:compatibility": "composer phpcs:compatibility",
Expand All @@ -28,7 +28,7 @@
"version-packages": "bash ./tools/version-packages.sh"
},
"devDependencies": {
"eslint": "8.57.1",
"eslint": "9.16.0",
"husky": "8.0.3",
"jetpack-cli": "workspace:*",
"jetpack-js-tools": "workspace:*"
Expand Down
Loading

0 comments on commit 9e3ae2f

Please sign in to comment.