# 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|html)$') ignored = 'File ignored because of a matching ignore pattern. 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 if "line" in message: ui.warn("%s:%d:%d %s\n" % (path, message["line"], message["column"], message["message"])) else: ui.warn("%s: %s\n" % (path, 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: basepath = get_project_root() if not basepath: return dir = os.path.join(basepath, "tools", "lint", "eslint", "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(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) def get_project_root(): file_found = False folder = os.getcwd() while (folder): if os.path.exists(os.path.join(folder, 'mach')): file_found = True break else: folder = os.path.dirname(folder) if file_found: return os.path.abspath(folder) return None