Bug 1429223 - [lint] Obsolete the eslintvalidate hooks by printing error message with upgrade path, r=standard8
authorAndrew Halberstadt <ahalberstadt@mozilla.com>
Tue, 09 Jan 2018 20:03:58 -0500
changeset 452917 912ba3bc72115962148d9b7b110c60ce3f2d697f
parent 452916 574c3361e20ce1b48f1ae99cab40a9d77c5eb2ca
child 452918 aea20cd2ae6a873be9db89573b086a93353432eb
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersstandard8
bugs1429223
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1429223 - [lint] Obsolete the eslintvalidate hooks by printing error message with upgrade path, r=standard8 This replaces the eslintvalidate hooks with an error message prompting the user to upgrade to tools/lint/hooks.py. The reasons for deprecating eslintvalidate are twofold: 1) It only runs eslint, so developers might miss errors from other linters. 2) It isn't as well maintained, and I've started to see reports of problems in the wild. It doesn't make sense to maintain two sets of hooks that do the same thing. MozReview-Commit-ID: CseeVIof2om
tools/git/eslintvalidate.py
tools/lint/eslint.yml
tools/lint/eslint/hook_helper.py
tools/mercurial/eslintvalidate.py
--- a/tools/git/eslintvalidate.py
+++ b/tools/git/eslintvalidate.py
@@ -1,35 +1,30 @@
 #!/usr/bin/python
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-import os
 import sys
-sys.path.append(os.path.join(os.path.dirname(__file__), "..", "lint", "eslint"))
-from hook_helper import is_lintable, runESLint
+
+OBSOLETE = """
+ERROR: the eslintvalidate hook is obsolete. This commit went
+through, but ESlint didn't run. You can lint your changes
+after the fact by running:
+
+    $ mach lint --outgoing
+
+Please remove this hook and upgrade by following these
+instructions:
+https://firefox-source-docs.mozilla.org/tools/lint/usage.html#using-a-vcs-hook
+""".lstrip()
 
 
 def output(message):
     print >> sys.stderr, message
 
 
 def eslint():
-    f = os.popen('git diff --cached --name-only --diff-filter=ACM')
-
-    files = [file for file in f.read().splitlines() if is_lintable(file)]
-
-    if len(files) == 0:
-        return True
-
-    print "Running ESLint..."
-
-    return runESLint(output, files)
+    output(OBSOLETE)
+    return False
 
 
 if __name__ == '__main__':
-    if not eslint():
-        output("Note: ESLint failed, but the commit will still happen. "
-               "Please fix before pushing.")
-
-    # We output successfully as that seems to be a better model. See
-    # https://bugzilla.mozilla.org/show_bug.cgi?id=1230300#c4 for more
-    # information.
+    eslint()
--- a/tools/lint/eslint.yml
+++ b/tools/lint/eslint.yml
@@ -1,11 +1,9 @@
 ---
 eslint:
     description: JavaScript linter
     # ESLint infra handles its own path filtering, so just include cwd
     include: ['.']
     exclude: []
-    # Make sure these are defined on the same line until the hack
-    # in hook_helper.py is fixed.
     extensions: ['js', 'jsm', 'jsx', 'xml', 'html', 'xhtml']
     type: external
     payload: eslint:lint
deleted file mode 100644
--- a/tools/lint/eslint/hook_helper.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-# This file provides helper functions for the repository hooks for git/hg.
-
-import json
-import os
-import re
-from subprocess import check_output, CalledProcessError
-
-import setup_helper
-
-ignored = 'File ignored because of a matching ignore pattern. Use "--no-ignore" to override.'
-
-here = os.path.abspath(os.path.dirname(__file__))
-config_path = os.path.join(here, '..', 'eslint.yml')
-
-EXTENSIONS_RE = None
-
-
-def get_extensions():
-    # This is a hacky way to avoid both re-defining extensions and
-    # depending on PyYaml in hg's python path. This will go away
-    # once the vcs hooks are using mozlint directly (bug 1361972)
-    with open(config_path) as fh:
-        line = [l for l in fh.readlines() if 'extensions' in l][0]
-
-    extensions = json.loads(line.split(':', 1)[1].replace('\'', '"'))
-    return [e.lstrip('.') for e in extensions]
-
-
-def is_lintable(filename):
-    """Determine if a file is lintable based on the file extension.
-
-    Keyword arguments:
-    filename -- the file to check.
-    """
-    global EXTENSIONS_RE
-    if not EXTENSIONS_RE:
-        EXTENSIONS_RE = re.compile(r'.+\.(?:%s)$' % '|'.join(get_extensions()))
-    return EXTENSIONS_RE.match(filename)
-
-
-def display(print_func, output_json):
-    """Formats an ESLint result into a human readable message.
-
-    Keyword arguments:
-    print_func -- A function to call to print the output.
-    output_json -- the json ESLint results to format.
-    """
-    results = json.loads(output_json)
-    for file in results:
-        path = os.path.relpath(file["filePath"])
-        for message in file["messages"]:
-            if message["message"] == ignored:
-                continue
-
-            if "line" in message:
-                print_func("%s:%d:%d %s\n" % (path, message["line"], message["column"],
-                           message["message"]))
-            else:
-                print_func("%s: %s\n" % (path, message["message"]))
-
-
-def runESLint(print_func, files):
-    """Runs ESLint on the files that are passed.
-
-    Keyword arguments:
-    print_func -- A function to call to print the output.
-    files -- A list of files to be checked.
-    """
-    try:
-        basepath = setup_helper.get_project_root()
-
-        if not basepath:
-            return False
-
-        if not setup_helper.check_node_executables_valid():
-            return False
-
-        setup_helper.eslint_maybe_setup()
-
-        dir = os.path.join(basepath, "node_modules", ".bin")
-
-        eslint_path = os.path.join(dir, "eslint")
-        if os.path.exists(os.path.join(dir, "eslint.cmd")):
-            eslint_path = os.path.join(dir, "eslint.cmd")
-        output = check_output([eslint_path,
-                               "--format", "json", "--plugin", "html"] + files,
-                              cwd=basepath)
-        display(print_func, output)
-        return True
-    except CalledProcessError as ex:
-        display(print_func, ex.output)
-        return False
--- a/tools/mercurial/eslintvalidate.py
+++ b/tools/mercurial/eslintvalidate.py
@@ -1,27 +1,23 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-import os
-import sys
-sys.path.append(os.path.join(os.path.dirname(__file__), "..", "lint", "eslint"))
-from hook_helper import is_lintable, runESLint
+OBSOLETE = """
+ERROR: the eslintvalidate hook is obsolete. This commit went
+through, but ESlint didn't run. You can lint your changes
+after the fact by running:
+
+    $ mach lint --outgoing
+
+Please remove this hook and upgrade by following these
+instructions:
+https://firefox-source-docs.mozilla.org/tools/lint/usage.html#using-a-vcs-hook
+""".lstrip()
 
 
 def eslinthook(ui, repo, node=None, **opts):
-    ctx = repo[node]
-    if len(ctx.parents()) > 1:
-        return 0
-
-    deleted = repo.status(ctx.p1().node(), ctx.node()).deleted
-    files = [f for f in ctx.files() if f not in deleted and is_lintable(f)]
-
-    if len(files) == 0:
-        return
-
-    if not runESLint(ui.warn, files):
-        ui.warn("Note: ESLint failed, but the commit will still happen. "
-                "Please fix before pushing.\n")
+    ui.warn(OBSOLETE)
+    return False
 
 
 def reposetup(ui, repo):
     ui.setconfig('hooks', 'commit.eslint', eslinthook)