Skip to content

Commit

Permalink
Experimental support for git commit-msg hook
Browse files Browse the repository at this point in the history
Users can now install a git commit-msg hook using the --install-hook
commandline flag. This is still experimental and missing some important
features (uninstall, appending to existing hook, restoring incorrect
commit message).
  • Loading branch information
jroovers-cisco committed Sep 11, 2015
1 parent 5b25f4d commit 3ab56fc
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 2 deletions.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ Usage: gitlint [OPTIONS]
Git lint tool, checks your git commit messages for styling issues

Options:
--install-hook [experimental] Install gitlint as a git commit-msg hook
-C, --config PATH Config file location (default: .gitlint).
-c TEXT Config flags in format <rule>.<option>=<value> (e.g.: -c
T1.line-length=80). Flag can be used multiple times to
Expand Down Expand Up @@ -138,6 +139,26 @@ B2 | body-trailing-whitespace | Body cannot have trailing whitespace (spac
B3 | body-hard-tab | Body cannot contain hard tab characters (\t)
B4 | body-first-line-empty | First line of the body (second line of commit message) must be empty
## Experimental: git commit-msg hook ##
You can also install gitlint as a git ```commit-msg``` hook so that gitlint checks your commit messages automatically
after each commit.
```bash
gitlint --install-hook
```

Note that this is still an experimental feature missing with some important gaps:
- When your commit message fails to pass gitlint validation, your commit is aborted (intended) and the commit message
you just entered will be lost (unintended). To make this a bit less inconvenient, the gitlint ```commit-msg``` hook
will print the commit message you just entered to the commandline so that you can copy-paste and reuse it (this only
happens if your commit message contained any violations).
- You currently cannot uninstall the ```commit-msg``` hook using gitlint. You will need to manually remove the hook from
```.git/hooks/commit-msg``` in your local git repository.
- Gitlint cannot work together with an existing hook. If you already have a ```.git/hooks/commit-msg``` file in your
local repository, gitlint will refuse to install the ```commit-msg``` hook.



## Development ##

To run tests:
Expand Down
7 changes: 6 additions & 1 deletion gitlint/cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import gitlint
from gitlint.lint import GitLinter
from gitlint.config import LintConfig, LintConfigError
from gitlint.hooks import GitHookInstaller
import os
import click
import sys
Expand Down Expand Up @@ -35,6 +36,7 @@ def get_lint_config(config_path=None):


@click.command()
@click.option('--install-hook', is_flag=True, help="[experimental] Install gitlint as a git commit-msg hook")
@click.option('-C', '--config', type=click.Path(exists=True),
help="Config file location (default: {0}).".format(DEFAULT_CONFIG_FILE))
@click.option('-c', multiple=True,
Expand All @@ -45,9 +47,12 @@ def get_lint_config(config_path=None):
help="Verbosity, more v's for more verbose output (e.g.: -v, -vv, -vvv). Default: -vvv", )
@click.option('-s', '--silent', help="Silent mode (no output). Takes precedence over -v, -vv, -vvv.", is_flag=True)
@click.version_option(version=gitlint.__version__)
def cli(config, c, ignore, verbose, silent):
def cli(install_hook, config, c, ignore, verbose, silent):
""" Git lint tool, checks your git commit messages for styling issues """

if install_hook:
GitHookInstaller.install_commit_msg_hook()

try:
# Config precedence:
# First, load default config or config from configfile
Expand Down
31 changes: 31 additions & 0 deletions gitlint/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import shutil
import stat
import sys
import os

COMMIT_MSG_HOOK_SRC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "hooks/commit-msg")
COMMIT_MSG_HOOK_DST_PATH = os.path.abspath(".git/hooks/commit-msg")


class GitHookInstaller(object):
@staticmethod
def install_commit_msg_hook():
# assert that current directory is a git repository
if not os.path.isdir(".git/hooks"):
sys.stderr.write("The current directory is not a git repository\n")
exit(1)
if os.path.exists(COMMIT_MSG_HOOK_DST_PATH):
sys.stderr.write(
"There is already a commit-msg hook file present in {}. \n".format(COMMIT_MSG_HOOK_DST_PATH) +
"gitlint currently does not support appending to an existing commit-msg file.\n")
exit(1)

# copy hook file
shutil.copy(COMMIT_MSG_HOOK_SRC_PATH, COMMIT_MSG_HOOK_DST_PATH)
# make hook executable
st = os.stat(COMMIT_MSG_HOOK_DST_PATH)
os.chmod(COMMIT_MSG_HOOK_DST_PATH, st.st_mode | stat.S_IEXEC)

# declare victory :-)
sys.stdout.write("Successfully installed gitlint commit-msg hook in {0}\n".format(COMMIT_MSG_HOOK_DST_PATH))
exit(0)
18 changes: 18 additions & 0 deletions gitlint/hooks/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/sh
### gitlint commit-msg hook start ###

cat "$1" | gitlint
gitlint_exit_code=$?

if [ $gitlint_exit_code -gt 0 ]; then
echo "----------------------"
echo "Your commit message: "
echo "----------------------"
cat "$1" | grep -v '^#'
else
echo "gitlint: OK"
fi

exit $gitlint_exit_code

### gitlint commit-msg hook end ###
5 changes: 4 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def get_version(package):
description="Linter for git repositories. Under active development.",
long_description=long_description,
classifiers=[
"Development Status :: 3 - Alpha",
"Development Status :: 4 - Beta",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Environment :: Console",
Expand All @@ -41,6 +41,9 @@ def get_version(package):
author='Joris Roovers',
url='https://github.com/jorisroovers/gitlint',
license='MIT',
package_data={
'gitlint': ['hooks/*']
},
packages=find_packages(exclude=["examples"]),
entry_points={
"console_scripts": [
Expand Down

0 comments on commit 3ab56fc

Please sign in to comment.