Bug 1305023 - Move ESLint's package.json and node_modules to the top level to improve editor integration. r?gps
Editors generally look for configurations at the top level of a project. For ESLint, they also look for the specific binary in node_modules before defaulting to the system binary. Whilst you can override the location, generally it doesn't work well when switching between projects.
The custom in-tree libraries make setup of a system ESLint more difficult as well.
Therefore to make it simple for developers to pick up the ESLint integrations with Editors, by moving the package.json and associated node_modules to the top-level directory.
MozReview-Commit-ID: 1pQpd7hTQ61
--- a/.gitignore
+++ b/.gitignore
@@ -95,18 +95,18 @@ embedding/ios/GeckoEmbed/GeckoEmbed.xcod
# Ignore mozharness execution files
testing/mozharness/.tox/
testing/mozharness/build/
testing/mozharness/logs/
testing/mozharness/.coverage
testing/mozharness/nosetests.xml
-# Ignore node_modules
-tools/lint/eslint/node_modules/
+# Ignore ESLint node_modules
+node_modules/
# Ignore talos virtualenv and tp5n files.
# The tp5n set is supposed to be decompressed at
# testing/talos/talos/page_load_test/tp5n in order to run tests like tps
# locally. Similarly, running talos requires a Python package virtual
# environment. Both the virtual environment and tp5n files end up littering
# the status command, so we ignore them.
testing/talos/.Python
--- a/.hgignore
+++ b/.hgignore
@@ -107,18 +107,18 @@ GPATH
^testing/mozharness/build/
^testing/mozharness/logs/
^testing/mozharness/.coverage
^testing/mozharness/nosetests.xml
# Ignore tox generated dir
.tox/
-# Ignore node_modules
-^tools/lint/eslint/node_modules/
+# Ignore ESLint node_modules
+^node_modules/
# Ignore talos virtualenv and tp5n files.
# The tp5n set is supposed to be decompressed at
# testing/talos/talos/tests/tp5n in order to run tests like tps
# locally. Similarly, running talos requires a Python package virtual
# environment. Both the virtual environment and tp5n files end up littering
# the status command, so we ignore them.
^testing/talos/.Python
rename from tools/lint/eslint/npm-shrinkwrap.json
rename to npm-shrinkwrap.json
rename from tools/lint/eslint/package.json
rename to package.json
--- a/tools/lint/eslint/package.json
+++ b/package.json
@@ -1,11 +1,11 @@
{
- "name": "mach-eslint",
- "description": "ESLint and external plugins for use with mach",
+ "name": "Mozilla ESLint Setup",
+ "description": "This package file is for setup of ESLint only for editor integration.",
"repository": {},
"license": "MPL-2.0",
"dependencies": {
"eslint": "3.18.0",
"eslint-plugin-html": "1.5.2",
"eslint-plugin-react": "4.2.3",
"escope": "^3.6.0",
"espree": "^3.4.0",
--- a/taskcluster/ci/source-test/mozlint.yml
+++ b/taskcluster/ci/source-test/mozlint.yml
@@ -8,22 +8,22 @@ mozlint-eslint:
worker-type: aws-provisioner-v1/gecko-t-linux-xlarge
worker:
implementation: docker-worker
docker-image: {in-tree: "lint"}
max-run-time: 1800
run:
using: run-task
command: >
- cd /home/worker/checkouts/gecko/tools/lint/eslint &&
- /build/tooltool.py fetch -m manifest.tt &&
+ cd /home/worker/checkouts/gecko/ &&
+ /build/tooltool.py fetch -m tools/lint/eslint/manifest.tt &&
tar xvfz eslint.tar.gz &&
rm eslint.tar.gz &&
- ln -s ../eslint-plugin-mozilla node_modules &&
- cd ../../.. &&
+ ln -s ../tools/lint/eslint/eslint-plugin-mozilla node_modules &&
+ ln -s ../tools/lint/eslint/eslint-plugin-spidermonkey-js node_modules &&
./mach lint -l eslint -f treeherder --quiet
run-on-projects:
- integration
- release
when:
files-changed:
# Files that are likely audited.
- '**/*.js'
@@ -32,16 +32,17 @@ mozlint-eslint:
- '**/*.html'
- '**/*.xhtml'
- '**/*.xml'
# Run when eslint policies change.
- '**/.eslintignore'
- '**/*eslintrc*'
# The plugin implementing custom checks.
- 'tools/lint/eslint/eslint-plugin-mozilla/**'
+ - 'tools/lint/eslint/eslint-plugin-spidermonkey-js/**'
# Other misc lint related files.
- 'python/mozlint/**'
- 'tools/lint/**'
mozlint-flake8:
description: flake8 run over the gecko codebase
platform: lint/opt
treeherder:
--- a/tools/lint/eslint.lint
+++ b/tools/lint/eslint.lint
@@ -67,17 +67,17 @@ def eslint_setup():
"""
orig_cwd = os.getcwd()
sys.path.append(os.path.dirname(__file__))
module_path = get_eslint_module_path()
# npm sometimes fails to respect cwd when it is run using check_call so
# we manually switch folders here instead.
- os.chdir(module_path)
+ os.chdir(get_project_root())
npm_path = get_node_or_npm_path("npm")
if not npm_path:
return 1
# Install ESLint and external plugins
cmd = [npm_path, "install"]
print("Installing eslint for mach using \"%s\"..." % (" ".join(cmd)))
@@ -120,17 +120,17 @@ def call_process(name, cmd, cwd=None):
return False
return True
def expected_eslint_modules():
# Read the expected version of ESLint and external modules
- expected_modules_path = os.path.join(get_eslint_module_path(), "package.json")
+ expected_modules_path = os.path.join(get_project_root(), "package.json")
with open(expected_modules_path, "r") as f:
expected_modules = json.load(f)["dependencies"]
# Also read the in-tree ESLint plugin mozilla version
mozilla_json_path = os.path.join(get_eslint_module_path(),
"eslint-plugin-mozilla", "package.json")
with open(mozilla_json_path, "r") as f:
expected_modules["eslint-plugin-mozilla"] = json.load(f)["version"]
@@ -141,17 +141,17 @@ def expected_eslint_modules():
with open(mozilla_json_path, "r") as f:
expected_modules["eslint-plugin-spidermonkey-js"] = json.load(f)["version"]
return expected_modules
def eslint_module_has_issues():
has_issues = False
- node_modules_path = os.path.join(get_eslint_module_path(), "node_modules")
+ node_modules_path = os.path.join(get_project_root(), "node_modules")
for name, version_range in expected_eslint_modules().iteritems():
path = os.path.join(node_modules_path, name, "package.json")
if not os.path.exists(path):
print("%s v%s needs to be installed locally." % (name, version_range))
has_issues = True
continue
@@ -272,17 +272,17 @@ def get_eslint_module_path():
return os.path.join(get_project_root(), "tools", "lint", "eslint")
def lint(paths, binary=None, fix=None, setup=None, **lintargs):
"""Run eslint."""
global project_root
project_root = lintargs['root']
- module_path = get_eslint_module_path()
+ module_path = get_project_root()
# eslint requires at least node 6.9.1
node_path = get_node_or_npm_path("node", LooseVersion("6.9.1"))
if not node_path:
return 1
if setup:
return eslint_setup()
--- a/tools/lint/eslint/update
+++ b/tools/lint/eslint/update
@@ -29,16 +29,18 @@ case "$choice" in
echo ""
echo "Invalid input."
continue
;;
esac
echo ""
echo "Removing node_modules and npm_shrinkwrap.json..."
+# Move to the top-level directory.
+cd ../../../
rm -rf node_modules/
rm npm-shrinkwrap.json
echo "Installing eslint and external plugins..."
# ESLint and all _external_ plugins are listed in this directory's package.json,
# so a regular `npm install` will install them at the specified versions.
# The in-tree eslint-plugin-mozilla is kept out of this tooltool archive on
# purpose so that it can be changed by any developer without requiring tooltool
@@ -46,25 +48,27 @@ echo "Installing eslint and external plu
npm install
echo "Creating npm shrinkwrap..."
npm shrinkwrap
echo "Creating eslint.tar.gz..."
tar cvfz eslint.tar.gz node_modules
+cd $DIR
+
echo "Downloading tooltool..."
wget https://raw.githubusercontent.com/mozilla/build-tooltool/master/tooltool.py
chmod +x tooltool.py
echo "Adding eslint.tar.gz to tooltool..."
rm manifest.tt
-./tooltool.py add --visibility public eslint.tar.gz
+./tooltool.py add --visibility public ../../../eslint.tar.gz
echo "Uploading eslint.tar.gz to tooltool..."
./tooltool.py upload --authentication-file=~/.tooltool-token --message "node_modules folder update for tools/lint/eslint"
echo "Cleaning up..."
-rm eslint.tar.gz
+rm ../../../eslint.tar.gz
rm tooltool.py
echo ""
echo "Update complete, please commit and check in your changes."