Bug 1361972 - Add a pre-push and pre-commit mozlint hooks draft
authorAndrew Halberstadt <ahalberstadt@mozilla.com>
Fri, 30 Jun 2017 18:29:42 -0700
changeset 604824 d1ca75e77a10e62bf21c8789db363c2f290d3f5a
parent 604823 e429ad5080a7bf8fa592fd7506b9dcc6b3ca798e
child 636299 1235bcb2a7ba0cca47f5c18b79f82c2cac3464da
push id67196
push userahalberstadt@mozilla.com
push dateThu, 06 Jul 2017 13:45:23 +0000
bugs1361972
milestone56.0a1
Bug 1361972 - Add a pre-push and pre-commit mozlint hooks This adds pre-push and pre-commit hooks for both hg and git. All four possibilities are implemented in the same file. To enable a pre-push hg hook, add the following to hgrc: [hooks] pre-push.lint = python:/path/to/gecko/tools/lint/hooks.py:hg To enable a pre-commit hg hook, add the following to hgrc: [hooks] pretxncommit.lint = python:/path/to/gecko/tools/lint/hooks.py:hg To enable a pre-push git hook, run the following command: $ ln -s /path/to/gecko/tools/lint/hooks.py .git/hooks/pre-push To enable a pre-commit git hook, run the following command: $ ln -s /path/to/gecko/tools/lint/hooks.py .git/hooks/pre-commit MozReview-Commit-ID: DUxCKN2fiag
tools/lint/docs/usage.rst
tools/lint/hooks.py
--- a/tools/lint/docs/usage.rst
+++ b/tools/lint/docs/usage.rst
@@ -1,11 +1,14 @@
 Running Linters Locally
 =======================
 
+Using the Command Line
+----------------------
+
 You can run all the various linters in the tree using the ``mach lint`` command. Simply pass in the
 directory or file you wish to lint (defaults to current working directory):
 
 .. parsed-literal::
 
     ./mach lint path/to/files
 
 Multiple paths are allowed:
@@ -22,15 +25,53 @@ To restrict which linters are invoked ma
 
 .. parsed-literal::
 
     ./mach lint -l eslint path/to/files
 
 Finally, ``mozlint`` can lint the files touched by outgoing revisions or the working directory using
 the ``-o/--outgoing`` and ``-w/--workdir`` arguments respectively. These work both with mercurial and
 git. In the case of ``--outgoing``, the default remote repository the changes would be pushed to is
-used as the comparison. If desired, a remote can be specified manually:
+used as the comparison. If desired, a remote can be specified manually. In git, you may only want to
+lint staged commits from the working directory, this can be accomplished with ``--workdir=staged``.
+Examples:
 
 .. parsed-literal::
 
     ./mach lint --workdir
+    ./mach lint --workdir=staged
     ./mach lint --outgoing
     ./mach lint --outgoing origin/master
+    ./mach lint -wo
+
+
+Using a VCS Hook
+----------------
+
+There are also both pre-commit and pre-push version control hooks that work in
+either hg or git. To enable a pre-push hg hook, add the following to hgrc:
+
+.. parsed-literal::
+
+    [hooks]
+    pre-push.lint = python:/path/to/gecko/tools/lint/hooks.py:hg
+
+
+To enable a pre-commit hg hook, add the following to hgrc:
+
+.. parsed-literal::
+
+    [hooks]
+    pretxncommit.lint = python:/path/to/gecko/tools/lint/hooks.py:hg
+
+
+To enable a pre-push git hook, run the following command:
+
+.. parsed-literal::
+
+    $ ln -s /path/to/gecko/tools/lint/hooks.py .git/hooks/pre-push
+
+
+To enable a pre-commit git hook, run the following command:
+
+.. parsed-literal::
+
+    $ ln -s /path/to/gecko/tools/lint/hooks.py .git/hooks/pre-commit
new file mode 100644
--- /dev/null
+++ b/tools/lint/hooks.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+import subprocess
+import sys
+
+here = os.path.dirname(os.path.realpath(__file__))
+topsrcdir = os.path.join(here, os.pardir, os.pardir)
+
+
+def run_mozlint(hooktype, args):
+    cmd = [os.path.join(topsrcdir, 'mach'), 'lint']
+
+    if 'commit' in hooktype:
+        # don't prevent commits, just display the lint results
+        subprocess.call(cmd + ['--workdir=staged'])
+        return False
+    elif 'push' in hooktype:
+        return subprocess.call(cmd + ['--outgoing'] + args)
+
+    print("warning: '{}' is not a valid mozlint hooktype".format(hooktype))
+    return False
+
+
+def hg(ui, repo, **kwargs):
+    hooktype = kwargs['hooktype']
+    return run_mozlint(hooktype, kwargs.get('pats', []))
+
+
+def git(args=sys.argv[1:]):
+    hooktype = os.path.basename(__file__)
+    return run_mozlint(hooktype, args[:1])
+
+
+if __name__ == '__main__':
+    sys.exit(git())