Actually run things and make pretty output.

This commit is contained in:
Anthony Sottile 2014-03-14 12:09:39 -07:00
parent f123e64c25
commit 5daed50f75
3 changed files with 113 additions and 22 deletions

View file

@ -5,7 +5,7 @@
hooks: hooks:
- -
id: pyflakes id: pyflakes
files: '*.py' files: '\.py$'
- -
repo: git@github.com:pre-commit/jshint repo: git@github.com:pre-commit/jshint
@ -13,7 +13,7 @@
hooks: hooks:
- -
id: jshint id: jshint
files: '*.js' files: '\.js$'
- -
repo: git@github.com:pre-commit/scss-lint repo: git@github.com:pre-commit/scss-lint
@ -21,4 +21,4 @@
hooks: hooks:
- -
id: scss-lint id: scss-lint
files: '*.scss' files: '\.scss$'

View file

@ -1,4 +1,5 @@
import os import os
import re
import pkg_resources import pkg_resources
from plumbum import local from plumbum import local
@ -27,4 +28,31 @@ def remove_pre_commit():
def get_head_sha(git_repo_path): def get_head_sha(git_repo_path):
with local.cwd(git_repo_path): with local.cwd(git_repo_path):
return (local['git']['rev-parse', 'HEAD'])().strip() return local['git']['rev-parse', 'HEAD']().strip()
@memoize_by_cwd
def get_staged_files():
return local['git']['diff', '--staged', '--name-only']().splitlines()
@memoize_by_cwd
def get_staged_files_matching(expr):
regex = re.compile(expr)
return set(
filename for filename in get_staged_files() if regex.search(filename)
)
@memoize_by_cwd
def get_all_files():
return local['git']['ls-files']().splitlines()
# Smell: this is duplicated above
@memoize_by_cwd
def get_all_files_matching(expr):
regex = re.compile(expr)
return set(
filename for filename in get_all_files() if regex.search(filename)
)

View file

@ -1,10 +1,19 @@
import argparse import argparse
import os.path import os.path
import subprocess
from pre_commit import git from pre_commit import git
from pre_commit.clientlib.validate_config import validate_config from pre_commit.clientlib.validate_config import validate_config
from pre_commit.repository import Repository from pre_commit.repository import Repository
RED = '\033[41m'
GREEN = '\033[42m'
NORMAL = '\033[0m'
COLS = int(subprocess.Popen(['tput', 'cols'], stdout=subprocess.PIPE).communicate()[0])
def install(): def install():
"""Install the pre-commit hook.""" """Install the pre-commit hook."""
git.create_pre_commit() git.create_pre_commit()
@ -15,27 +24,76 @@ def uninstall():
git.remove_pre_commit() git.remove_pre_commit()
def run_hooks(arguments): def _run_single_hook(repository, hook_id, run_all_the_things=False):
"""Actually run the hooks.""" repository.install()
raise NotImplementedError
if run_all_the_things:
get_filenames = git.get_all_files_matching
else:
get_filenames = git.get_staged_files_matching
hook = repository.hooks[hook_id]
retcode, stdout, stderr = repository.run_hook(
hook_id,
map(os.path.abspath, get_filenames(hook['files'])),
)
if retcode != repository.hooks[hook_id].get('expected_return_value', 0):
output = '\n'.join([stdout, stderr]).strip()
retcode = 1
color = RED
pass_fail = 'Failed'
else:
output = ''
retcode = 0
color = GREEN
pass_fail = 'Passed'
print '{0}{1}{2}{3}{4}'.format(
hook['name'],
'.' * (COLS - len(hook['name']) - len(pass_fail) - 6),
color,
pass_fail,
NORMAL,
)
if output:
print
print output
print
return retcode
def run_hooks(run_all_the_things=False):
"""Actually run the hooks."""
retval = 0
def run_single_hook(hook_id):
configs = validate_config([]) configs = validate_config([])
for config in configs:
repo = Repository(config)
for hook_id in repo.hooks:
retval |= _run_single_hook(
repo,
hook_id,
run_all_the_things=run_all_the_things,
)
return retval
def run_single_hook(hook_id, configs=None, run_all_the_things=False):
configs = configs or validate_config([])
for config in configs: for config in configs:
repo = Repository(config) repo = Repository(config)
if hook_id in repo.hooks: if hook_id in repo.hooks:
repo.install() return _run_single_hook(
repo,
retcode, stdout, stderr = repo.run_hook(hook_id, map(os.path.abspath, ['pre_commit/constants.py'])) hook_id,
run_all_the_things=run_all_the_things,
if retcode != repo.hooks[hook_id].get('expected_return_value', 0): )
for out in (stdout, stderr):
out = out.rstrip()
if len(out) > 0:
print out
return 1
else:
return 0
else: else:
print "No hook with id {0}".format(hook_id) print "No hook with id {0}".format(hook_id)
return 1 return 1
@ -60,6 +118,11 @@ def run(argv):
help='Run a hook' help='Run a hook'
) )
parser.add_argument(
'--run-fucking-everything', action='store_true', default=False,
help='Run on all the files in the repo',
)
args = parser.parse_args(argv) args = parser.parse_args(argv)
if args.install: if args.install:
@ -67,6 +130,6 @@ def run(argv):
elif args.uninstall: elif args.uninstall:
return uninstall() return uninstall()
elif args.run: elif args.run:
return run_single_hook(args.run) return run_single_hook(args.run, run_all_the_things=args.run_fucking_everything)
else: else:
return run_hooks(args) return run_hooks(run_all_the_things=args.run_fucking_everything)