Bug 1203520 - We need a DevTools ESLint plugin containing our ruleset r=gps
This commit is contained in:
@@ -8,6 +8,9 @@ import argparse
|
||||
import logging
|
||||
import mozpack.path as mozpath
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import sys
|
||||
import which
|
||||
|
||||
from mozbuild.base import (
|
||||
@@ -20,17 +23,46 @@ from mach.decorators import (
|
||||
Command,
|
||||
)
|
||||
|
||||
|
||||
ESLINT_NOT_FOUND_MESSAGE = '''
|
||||
Could not find eslint! We looked at the --binary option, at the ESLINT
|
||||
environment variable, and then at your path. Install eslint and needed plugins
|
||||
with
|
||||
|
||||
npm install -g eslint eslint-plugin-react
|
||||
mach eslint --setup
|
||||
|
||||
and try again.
|
||||
'''.strip()
|
||||
|
||||
NODE_NOT_FOUND_MESSAGE = '''
|
||||
nodejs is either not installed or is installed to a non-standard path.
|
||||
Please install nodejs from https://nodejs.org and try again.
|
||||
|
||||
Valid installation paths:
|
||||
'''.strip()
|
||||
|
||||
NPM_NOT_FOUND_MESSAGE = '''
|
||||
Node Package Manager (npm) is either not installed or installed to a
|
||||
non-standard path. Please install npm from https://nodejs.org (it comes as an
|
||||
option in the node installation) and try again.
|
||||
|
||||
Valid installation paths:
|
||||
'''.strip()
|
||||
|
||||
ESLINT_PROMPT = '''
|
||||
Would you like to use eslint
|
||||
'''.strip()
|
||||
|
||||
ESLINT_PLUGIN_MOZILLA_PROMPT = '''
|
||||
eslint-plugin-mozilla is an eslint plugin containing rules that help enforce
|
||||
JavaScript coding standards in the Mozilla project. Would you like to use this
|
||||
plugin
|
||||
'''.strip()
|
||||
|
||||
ESLINT_PLUGIN_REACT_PROMPT = '''
|
||||
eslint-plugin-react is an eslint plugin containing rules that help React
|
||||
developers follow strict guidelines. Would you like to install it
|
||||
'''.strip()
|
||||
|
||||
|
||||
@CommandProvider
|
||||
class MachCommands(MachCommandBase):
|
||||
@@ -132,7 +164,10 @@ class MachCommands(MachCommandBase):
|
||||
|
||||
return 0 if return_code == 0 else 1
|
||||
|
||||
@Command('eslint', category='devenv')
|
||||
@Command('eslint', category='devenv',
|
||||
description='Run eslint or help configure eslint for optimal development.')
|
||||
@CommandArgument('-s', '--setup', default=False, action='store_true',
|
||||
help='configure eslint for optimal development.')
|
||||
@CommandArgument('path', nargs='?', default='.',
|
||||
help='Path to files to lint, like "browser/components/loop" '
|
||||
'or "mobile/android". '
|
||||
@@ -142,9 +177,12 @@ class MachCommands(MachCommandBase):
|
||||
@CommandArgument('-b', '--binary', default=None,
|
||||
help='Path to eslint binary.')
|
||||
@CommandArgument('args', nargs=argparse.REMAINDER) # Passed through to eslint.
|
||||
def eslint(self, path, ext=None, binary=None, args=[]):
|
||||
def eslint(self, setup, path, ext=None, binary=None, args=[]):
|
||||
'''Run eslint.'''
|
||||
|
||||
if setup:
|
||||
return self.eslint_setup()
|
||||
|
||||
if not binary:
|
||||
binary = os.environ.get('ESLINT', None)
|
||||
if not binary:
|
||||
@@ -182,3 +220,100 @@ class MachCommands(MachCommandBase):
|
||||
pass_thru=True, # Allow user to run eslint interactively.
|
||||
ensure_exit_code=False, # Don't throw on non-zero exit code.
|
||||
)
|
||||
def eslint_setup(self, update_only=False):
|
||||
"""Ensure eslint is optimally configured.
|
||||
|
||||
This command will inspect your eslint configuration and
|
||||
guide you through an interactive wizard helping you configure
|
||||
eslint for optimal use on Mozilla projects.
|
||||
"""
|
||||
sys.path.append(os.path.dirname(__file__))
|
||||
|
||||
# At the very least we need node installed.
|
||||
nodePath = self.getNodeOrNpmPath("node")
|
||||
if not nodePath:
|
||||
return 1
|
||||
|
||||
npmPath = self.getNodeOrNpmPath("npm")
|
||||
if not npmPath:
|
||||
return 1
|
||||
|
||||
# Install eslint.
|
||||
print("Installing eslint...")
|
||||
with open(os.devnull, "w") as fnull:
|
||||
subprocess.call([npmPath, "install", "eslint", "-g"],
|
||||
stdout=fnull, stderr=fnull)
|
||||
|
||||
# Install eslint-plugin-mozilla.
|
||||
print("")
|
||||
print("Installing eslint-plugin-mozilla...")
|
||||
with open(os.devnull, "w") as fnull:
|
||||
subprocess.call([npmPath, "link"],
|
||||
cwd="testing/eslint-plugin-mozilla",
|
||||
stdout=fnull, stderr=fnull)
|
||||
|
||||
# Install eslint-plugin-react.
|
||||
print("")
|
||||
print("Installing eslint-plugin-react...")
|
||||
with open(os.devnull, "w") as fnull:
|
||||
subprocess.call([npmPath, "install", "-g", "eslint-plugin-react"],
|
||||
stdout=fnull, stderr=fnull)
|
||||
|
||||
def getPossibleNodePathsWin(self):
|
||||
"""
|
||||
Return possible nodejs paths on Windows.
|
||||
"""
|
||||
if platform.system() != "Windows":
|
||||
return []
|
||||
|
||||
return {
|
||||
"%s\\nodejs" % os.environ.get("SystemDrive"),
|
||||
os.path.join(os.environ.get("ProgramFiles"), "nodejs"),
|
||||
os.path.join(os.environ.get("PROGRAMW6432"), "nodejs"),
|
||||
os.path.join(os.environ.get("PROGRAMFILES"), "nodejs")
|
||||
}
|
||||
|
||||
def getNodeOrNpmPath(self, filename):
|
||||
"""
|
||||
Return the nodejs or npm path.
|
||||
"""
|
||||
try:
|
||||
appPath = which.which(filename)
|
||||
return appPath
|
||||
except which.WhichError:
|
||||
pass
|
||||
|
||||
if platform.system() == "Windows":
|
||||
try:
|
||||
for ext in ["", ".cmd", ".exe"]:
|
||||
nodeOrNpmPath = which.which(filename + ext,
|
||||
path=self.getPossibleNodePathsWin())
|
||||
if self.is_valid(nodeOrNpmPath):
|
||||
return nodeOrNpmPath
|
||||
except which.WhichError:
|
||||
pass
|
||||
|
||||
if filename == "node":
|
||||
print(NODE_NOT_FOUND_MESSAGE)
|
||||
elif filename == "npm":
|
||||
print(NPM_NOT_FOUND_MESSAGE)
|
||||
|
||||
if platform.system() == "Windows":
|
||||
appPaths = self.getPossibleNodePathsWin()
|
||||
|
||||
for p in appPaths:
|
||||
print(" - " + p)
|
||||
elif platform.system() == "Darwin":
|
||||
print(" - /usr/local/bin/node")
|
||||
elif platform.system() == "Linux":
|
||||
print(" - /usr/bin/nodejs")
|
||||
|
||||
return None
|
||||
|
||||
def is_valid(self, path):
|
||||
try:
|
||||
with open(os.devnull, "w") as fnull:
|
||||
subprocess.check_call([path, "--version"], stdout=fnull)
|
||||
return True
|
||||
except subprocess.CalledProcessError:
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user