Bug 1825507 - Separate out prettier and ESLint to run as different processes. r=linter-reviewers,devtools-reviewers,ahal
This is enough to allow ESLint and Prettier to be run as different processes within the same lint command. It does not fix all the failures with those two separate - that will be handled in follow-up bugs. Differential Revision: https://phabricator.services.mozilla.com/D174133
This commit is contained in:
@@ -2,6 +2,12 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
let prettierRules = { "prettier/prettier": "error" };
|
||||
|
||||
if (process.env.MOZ_SEPARATE_PRETTIER) {
|
||||
prettierRules = { "prettier/prettier": "off" };
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
// When adding items to this file please check for effects on sub-directories.
|
||||
parserOptions: {
|
||||
@@ -25,7 +31,6 @@ module.exports = {
|
||||
"eslint:recommended",
|
||||
"plugin:jsx-a11y/recommended", // require("eslint-plugin-jsx-a11y")
|
||||
"plugin:mozilla/recommended", // require("eslint-plugin-mozilla") require("eslint-plugin-fetch-options") require("eslint-plugin-html") require("eslint-plugin-no-unsanitized")
|
||||
"plugin:prettier/recommended", // require("eslint-plugin-prettier")
|
||||
"prettier", // require("eslint-config-prettier")
|
||||
],
|
||||
overrides: [
|
||||
@@ -113,6 +118,8 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
rules: {
|
||||
...prettierRules,
|
||||
|
||||
"fetch-options/no-fetch-credentials": "error",
|
||||
|
||||
"react/jsx-boolean-value": ["error", "always"],
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
let prettierRules = { "prettier/prettier": "error" };
|
||||
|
||||
if (process.env.MOZ_SEPARATE_PRETTIER) {
|
||||
prettierRules = { "prettier/prettier": "off" };
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
plugins: ["react", "mozilla", "@babel", "prettier", "import", "file-header"],
|
||||
globals: {
|
||||
@@ -47,6 +53,8 @@ module.exports = {
|
||||
jest: true,
|
||||
},
|
||||
rules: {
|
||||
...prettierRules,
|
||||
|
||||
// These are the rules that have been configured so far to match the
|
||||
// devtools coding style.
|
||||
|
||||
@@ -358,9 +366,6 @@ module.exports = {
|
||||
// entirely
|
||||
"operator-assignment": 0,
|
||||
|
||||
// Rules from the prettier plugin
|
||||
"prettier/prettier": "error",
|
||||
|
||||
"file-header/file-header": [
|
||||
"error",
|
||||
[
|
||||
|
||||
@@ -32,6 +32,14 @@ mach eslint --setup
|
||||
and try again.
|
||||
""".strip()
|
||||
|
||||
PRETTIER_ERROR_MESSAGE = """
|
||||
An error occurred running prettier. Please check the following error messages:
|
||||
|
||||
{}
|
||||
""".strip()
|
||||
|
||||
PRETTIER_FORMATTING_MESSAGE = "This file needs formatting with prettier."
|
||||
|
||||
|
||||
def setup(root, **lintargs):
|
||||
setup_helper.set_project_root(root)
|
||||
@@ -70,6 +78,7 @@ def lint(paths, config, binary=None, fix=None, rules=[], setup=None, **lintargs)
|
||||
for rule in rules:
|
||||
extra_args.extend(["--rule", rule])
|
||||
|
||||
# First run ESLint
|
||||
cmd_args = (
|
||||
[
|
||||
binary,
|
||||
@@ -86,13 +95,56 @@ def lint(paths, config, binary=None, fix=None, rules=[], setup=None, **lintargs)
|
||||
+ exclude_args
|
||||
+ paths
|
||||
)
|
||||
log.debug("Command: {}".format(" ".join(cmd_args)))
|
||||
|
||||
if fix:
|
||||
# eslint requires that --fix be set before the --ext argument.
|
||||
cmd_args.insert(2, "--fix")
|
||||
|
||||
return run(cmd_args, config)
|
||||
log.debug("ESLint command: {}".format(" ".join(cmd_args)))
|
||||
|
||||
result = run(cmd_args, config)
|
||||
if result == 1:
|
||||
return result
|
||||
|
||||
# Then run Prettier
|
||||
if "MOZ_SEPARATE_PRETTIER" in os.environ:
|
||||
patterns = []
|
||||
for p in paths:
|
||||
filename, file_extension = os.path.splitext(p)
|
||||
if file_extension:
|
||||
patterns.append(p)
|
||||
else:
|
||||
patterns.append(
|
||||
p + "/**/*.+({})".format("|".join(config["extensions"]))
|
||||
)
|
||||
|
||||
cmd_args = (
|
||||
[
|
||||
binary,
|
||||
os.path.join(
|
||||
module_path, "node_modules", "prettier", "bin-prettier.js"
|
||||
),
|
||||
"--list-different",
|
||||
]
|
||||
+ extra_args
|
||||
# Prettier does not support exclude arguments.
|
||||
# + exclude_args
|
||||
# Prettier only supports this from 2.3 and above (bug 1826062).
|
||||
# + "--no-error-on-unmatched-pattern",
|
||||
+ patterns
|
||||
)
|
||||
log.debug("Prettier command: {}".format(" ".join(cmd_args)))
|
||||
|
||||
if fix:
|
||||
cmd_args.append("--write")
|
||||
|
||||
prettier_result = run_prettier(cmd_args, config, fix)
|
||||
if prettier_result == 1:
|
||||
return prettier_result
|
||||
|
||||
result["results"].extend(prettier_result["results"])
|
||||
result["fixed"] = result["fixed"] + prettier_result["fixed"]
|
||||
return result
|
||||
|
||||
|
||||
def run(cmd_args, config):
|
||||
@@ -156,3 +208,77 @@ def run(cmd_args, config):
|
||||
results.append(result.from_config(config, **err))
|
||||
|
||||
return {"results": results, "fixed": fixed}
|
||||
|
||||
|
||||
def run_prettier(cmd_args, config, fix):
|
||||
|
||||
shell = False
|
||||
if (
|
||||
os.environ.get("MSYSTEM") in ("MINGW32", "MINGW64")
|
||||
or "MOZILLABUILD" in os.environ
|
||||
):
|
||||
# The eslint binary needs to be run from a shell with msys
|
||||
shell = True
|
||||
encoding = "utf-8"
|
||||
|
||||
orig = signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||
proc = subprocess.Popen(
|
||||
cmd_args, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
signal.signal(signal.SIGINT, orig)
|
||||
|
||||
try:
|
||||
output, errors = proc.communicate()
|
||||
except KeyboardInterrupt:
|
||||
proc.kill()
|
||||
return {"results": [], "fixed": 0}
|
||||
|
||||
if errors:
|
||||
errors = errors.decode(encoding, "replace")
|
||||
# --no-error-on-unmatched-pattern was only added in Prettier 2.3,
|
||||
# when we upgrade to the latest version (bug 1826062), we can pass in
|
||||
# that argument and remove this check.
|
||||
if "No matching files." in errors:
|
||||
return {"results": [], "fixed": 0}
|
||||
print(PRETTIER_ERROR_MESSAGE.format(errors))
|
||||
|
||||
if proc.returncode >= 2:
|
||||
return 1
|
||||
|
||||
if not output:
|
||||
return {"results": [], "fixed": 0} # no output means success
|
||||
|
||||
output = output.decode(encoding, "replace").splitlines()
|
||||
|
||||
results = []
|
||||
fixed = 0
|
||||
|
||||
if fix:
|
||||
# When Prettier is running in fix mode, it outputs the list of files
|
||||
# that have been fixed, so sum them up here.
|
||||
# If it can't fix files, it will throw an error, which will be handled
|
||||
# above.
|
||||
fixed = len(output)
|
||||
else:
|
||||
# When in "check" mode, Prettier will output the list of files that
|
||||
# need changing, so we'll wrap them in our result structure here.
|
||||
for file in output:
|
||||
if not file:
|
||||
continue
|
||||
|
||||
results.append(
|
||||
result.from_config(
|
||||
config,
|
||||
**{
|
||||
"name": "eslint",
|
||||
"path": file,
|
||||
"message": PRETTIER_FORMATTING_MESSAGE,
|
||||
"level": "error",
|
||||
"rule": "prettier",
|
||||
"lineno": 0,
|
||||
"column": 0,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
return {"results": results, "fixed": fixed}
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
let prettierRules = { "prettier/prettier": "error" };
|
||||
|
||||
if (process.env.MOZ_SEPARATE_PRETTIER) {
|
||||
prettierRules = { "prettier/prettier": "off" };
|
||||
}
|
||||
|
||||
/**
|
||||
* The configuration is based on eslint:recommended config. The details for all
|
||||
* the ESLint rules, and which ones are in the recommended configuration can
|
||||
@@ -19,7 +25,9 @@ module.exports = {
|
||||
"mozilla/specific": true,
|
||||
},
|
||||
|
||||
extends: ["eslint:recommended", "plugin:prettier/recommended"],
|
||||
// The prettier configuration here comes from eslint-config-prettier and
|
||||
// turns off all of ESLint's rules related to formatting.
|
||||
extends: ["eslint:recommended", "prettier"],
|
||||
|
||||
overrides: [
|
||||
{
|
||||
@@ -111,11 +119,16 @@ module.exports = {
|
||||
},
|
||||
|
||||
// When adding items to this file please check for effects on sub-directories.
|
||||
plugins: ["html", "fetch-options", "no-unsanitized"],
|
||||
plugins: ["html", "fetch-options", "prettier", "no-unsanitized"],
|
||||
|
||||
// When adding items to this file please check for effects on all of toolkit
|
||||
// and browser
|
||||
rules: {
|
||||
...prettierRules,
|
||||
|
||||
// This may conflict with prettier, so we turn it off.
|
||||
"arrow-body-style": "off",
|
||||
|
||||
// Warn about cyclomatic complexity in functions.
|
||||
// XXX Get this down to 20?
|
||||
complexity: ["error", 34],
|
||||
@@ -331,6 +344,9 @@ module.exports = {
|
||||
// Require object-literal shorthand with ES6 method syntax
|
||||
"object-shorthand": ["error", "always", { avoidQuotes: true }],
|
||||
|
||||
// This may conflict with prettier, so turn it off.
|
||||
"prefer-arrow-callback": "off",
|
||||
|
||||
// This generates too many false positives that are not easy to work around,
|
||||
// and false positives seem to be inherent in the rule.
|
||||
"require-atomic-updates": "off",
|
||||
|
||||
Reference in New Issue
Block a user