From b9c08ee9b3b950c316824f2675449bbbd06ab019 Mon Sep 17 00:00:00 2001 From: Dave Townsend Date: Fri, 11 Dec 2015 09:11:49 -0500 Subject: [PATCH] Bug 1230300: Add a hg extension that rejects changesets that fail to pass eslint. r=gps This grabs the list of changed and added files that match the set we expect to be able to lint and runs them through eslint displaying simple messages on error. --- tools/mercurial/eslintvalidate.py | 45 +++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 tools/mercurial/eslintvalidate.py diff --git a/tools/mercurial/eslintvalidate.py b/tools/mercurial/eslintvalidate.py new file mode 100644 index 00000000000..e792741e93f --- /dev/null +++ b/tools/mercurial/eslintvalidate.py @@ -0,0 +1,45 @@ +# 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 +import re +import json +from subprocess import check_output, CalledProcessError + +lintable = re.compile(r'.+\.(?:js|jsm|jsx|xml)$') +ignored = "File ignored because of your .eslintignore file. Use --no-ignore to override." + +def is_lintable(filename): + return lintable.match(filename) + +def display(ui, output): + results = json.loads(output) + for file in results: + path = os.path.relpath(file["filePath"]) + for message in file["messages"]: + if message["message"] == ignored: + continue + + ui.warn("%s:%d:%d %s\n" % (path, message["line"], message["column"], message["message"])) + +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 + + try: + output = check_output(["eslint", "--format", "json"] + files) + display(ui, output) + except CalledProcessError as ex: + display(ui, ex.output) + ui.warn("ESLint found problems in your changes, please correct them.\n") + +def reposetup(ui, repo): + ui.setconfig('hooks', 'commit.eslint', eslinthook)