diff --git a/.circleci/config.yml b/.circleci/config.yml index 6a3153a526..b37e488d24 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -54,6 +54,8 @@ jobs: - wagtail - run: npm run lint:js - run: npm run lint:css + # TODO Remove || true and enforce a successful exit code. + - run: npm run lint:format || true - run: npm run test:unit:coverage -- --runInBand - run: bash <(curl -s https://codecov.io/bash) -F frontend diff --git a/.editorconfig b/.editorconfig index 7c804220c2..1b06b5e1fe 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,17 +4,18 @@ root = true end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true - -[*.{css,js,json,py,yml,rst,md}] indent_style = space +[Makefile] +indent_style = tab + [*.{js,py}] charset = utf-8 -[*.{css,py,scss,rst,md}] +[*.{py,html,rst,md}] indent_size = 4 -[*.{js,json,yml,rst}] +[*.{js,ts,tsx,json,yml,yaml,css,scss}] indent_size = 2 [*.md] diff --git a/.eslintignore b/.eslintignore index 5bd3074d0a..68f29c5323 100644 --- a/.eslintignore +++ b/.eslintignore @@ -15,4 +15,3 @@ wagtail/users/static wagtail/contrib/*/static wagtail/admin/templates/wagtailadmin/edit_handlers/inline_panel.js wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/includes/searchpromotions_formset.js -wagtail/users/templates/wagtailusers/groups/includes/page_permissions_formset.js diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000000..6a2b8357f8 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,8 @@ +# git-blame ignored revisions +# To configure, run +# git config blame.ignoreRevsFile .git-blame-ignore-revs +# Requires Git > 2.23 +# See https://git-scm.com/docs/git-blame#Documentation/git-blame.txt---ignore-revs-fileltfilegt + +# Initial Prettier reformatting +# TODO diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bdd79d9a1f..6b6c94a297 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,3 +1,5 @@ +default_language_version: + node: system repos: - repo: https://github.com/timothycrosley/isort # isort config is in setup.cfg @@ -11,3 +13,8 @@ repos: hooks: - id: flake8 language_version: python3 + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v2.5.1 + hooks: + - id: prettier + types_or: [css, scss, javascript, ts, tsx, json, yaml] diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..4e5cb78eea --- /dev/null +++ b/.prettierignore @@ -0,0 +1,15 @@ +# Irrelevant files ignored for performance reasons. +node_modules +*.min.js +**/lib/ +public/ +coverage/ +**/vendor/ +static +_build +# File types which Prettier supports but we don’t want auto-formatting. +*.md +# Files which contain incompatible syntax. +*.html +wagtail/admin/templates/wagtailadmin/edit_handlers/inline_panel.js +wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/includes/searchpromotions_formset.js diff --git a/Makefile b/Makefile index 55c7a42c2c..0f92b6559a 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,7 @@ lint: jinjalint --parse-only wagtail | grep -v 'welcome_page.html:6:70' | tee /dev/tty | wc -l | grep -q '0' npm run lint:css --silent npm run lint:js --silent + npm run lint:format --silent doc8 docs test: diff --git a/docs/contributing/css_guidelines.rst b/docs/contributing/css_guidelines.rst index b31a5c4e58..124a3d1443 100644 --- a/docs/contributing/css_guidelines.rst +++ b/docs/contributing/css_guidelines.rst @@ -6,7 +6,8 @@ Our CSS is written in `Sass `_, using the SCSS syntax. Linting and formatting SCSS ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Wagtail uses the `stylelint `_ linter. +Wagtail uses `stylelint `_ for linting, +and `Prettier `_ for formatting. You'll need Node.js and npm on your development machine. Ensure project dependencies are installed by running ``npm install --no-save`` @@ -26,7 +27,13 @@ below, plus a little more. Formatting code --------------- -If you want to autofix errors, you can run that command directly with: +For Prettier auto-formatting, run: + +.. code-block:: console + + $ npm run format + +If you want to autofix linting errors: .. code-block:: console diff --git a/docs/contributing/javascript_guidelines.rst b/docs/contributing/javascript_guidelines.rst index b83457d79c..ae30f1a524 100644 --- a/docs/contributing/javascript_guidelines.rst +++ b/docs/contributing/javascript_guidelines.rst @@ -3,8 +3,7 @@ JavaScript coding guidelines Write JavaScript according to the `Airbnb Styleguide `_, with some exceptions: -- Use soft-tabs with a two space indent. Spaces are the only way to - guarantee code renders the same in any person's environment. +- Use `Prettier `_ for all formatting considerations. - We accept ``snake_case`` in object properties, such as ``ajaxResponse.page_title``, however camelCase or UPPER_CASE should be used everywhere else. @@ -13,9 +12,9 @@ Write JavaScript according to the `Airbnb Styleguide `_ linter to help check your code meets the -styleguide. You'll need node.js and npm on your development machine. -Ensure project dependencies are installed by running ``npm install --no-save`` +Wagtail uses `ESLint `_ and `Prettier `_. +You'll need Node and npm on your development machine. +Ensure project dependencies are installed by running ``npm install --no-save``. Linting code ------------ @@ -34,6 +33,14 @@ excluded from the linter. Formatting code --------------- +For Prettier auto-formatting, run: + +.. code-block:: console + + $ npm run format + +If you want to autofix linting errors: + .. code-block:: console $ npm run lint:js -- --fix diff --git a/package-lock.json b/package-lock.json index cd6383f5e9..a6eaf0d3ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,6 +59,7 @@ "mini-css-extract-plugin": "^2.4.5", "postcss": "^8.4.5", "postcss-loader": "^6.2.1", + "prettier": "^2.5.1", "react-axe": "^3.5.4", "react-test-renderer": "^16.14.0", "redux-mock-store": "^1.3.0", @@ -6690,6 +6691,18 @@ "url": "https://opencollective.com/core-js" } }, + "node_modules/@storybook/csf-tools/node_modules/prettier": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", + "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/@storybook/manager-webpack4": { "version": "6.4.17", "resolved": "https://registry.npmjs.org/@storybook/manager-webpack4/-/manager-webpack4-6.4.17.tgz", @@ -23358,9 +23371,9 @@ } }, "node_modules/prettier": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", - "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -34202,6 +34215,12 @@ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.20.3.tgz", "integrity": "sha512-vVl8j8ph6tRS3B8qir40H7yw7voy17xL0piAjlbBUsH7WIfzoedL/ZOr1OV9FyZQLWXsayOJyV4tnRyXR85/ag==", "dev": true + }, + "prettier": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", + "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==", + "dev": true } } }, @@ -47168,9 +47187,9 @@ "dev": true }, "prettier": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", - "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", "dev": true }, "pretty-error": { diff --git a/package.json b/package.json index d7cbd6653e..21efde8d37 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "mini-css-extract-plugin": "^2.4.5", "postcss": "^8.4.5", "postcss-loader": "^6.2.1", + "prettier": "^2.5.1", "react-axe": "^3.5.4", "react-test-renderer": "^16.14.0", "redux-mock-store": "^1.3.0", @@ -116,9 +117,11 @@ "start": "webpack --config ./client/webpack.config.js --mode development --progress --watch", "build": "webpack --config ./client/webpack.config.js --mode production", "fix:js": "eslint --ext .js,.ts,.tsx --fix ./", + "format": "prettier --write '**/?(.)*.{css,scss,js,ts,tsx,json,yaml,yml}'", "lint:js": "eslint --ext .js,.ts,.tsx --report-unused-disable-directives --max-warnings 16 ./client", "lint:css": "stylelint **/*.scss", - "lint": "npm run lint:js && npm run lint:css", + "lint:format": "prettier --check '**/?(.)*.{css,scss,js,ts,tsx,json,yaml,yml}'", + "lint": "npm run lint:js && npm run lint:css && npm run lint:format", "test": "npm run test:unit", "test:unit": "jest", "test:unit:watch": "jest --watch", diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 0000000000..1b349d1990 --- /dev/null +++ b/prettier.config.js @@ -0,0 +1,18 @@ +/** + * See https://prettier.io/docs/en/options.html. + */ +module.exports = { + arrowParens: 'always', + bracketSameLine: false, + bracketSpacing: true, + embeddedLanguageFormatting: 'auto', + endOfLine: 'lf', + htmlWhitespaceSensitivity: 'css', + jsxSingleQuote: false, + printWidth: 80, + proseWrap: 'preserve', + quoteProps: 'consistent', + semi: true, + singleQuote: true, + trailingComma: 'all', +};