Bug 1361972 - Add a pre-push and pre-commit mozlint hooks r=standard8
authorAndrew Halberstadt <ahalberstadt@mozilla.com>
Fri, 30 Jun 2017 18:29:42 -0700
changeset 367638 ea6fb7712a573762c57e1cef4cd03424d732d81c
parent 367637 55b72ade8f20b29785db4c7fd208d39f0a3c09e7
child 367639 f3fc2ea88f607ce82ed46e329d44350bfb9c8ce2
push id46040
push userahalberstadt@mozilla.com
push dateThu, 06 Jul 2017 15:19:45 +0000
treeherderautoland@ea6fb7712a57 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersstandard8
bugs1361972
milestone56.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 1361972 - Add a pre-push and pre-commit mozlint hooks r=standard8 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())