From ecdacd474b8cc2e2b96157941cdc6c7880eab991 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 23 Mar 2014 18:33:18 -0700 Subject: [PATCH] Simplify the install and uninstall commands and improve tests. --- pre_commit/commands.py | 25 +++++++++++++++++++++++++ pre_commit/git.py | 19 ------------------- pre_commit/run.py | 15 ++++++++++----- pre_commit/runner.py | 4 ++++ tests/commands_test.py | 37 +++++++++++++++++++++++++++++++++++++ tests/git_test.py | 28 ---------------------------- tests/runner_test.py | 6 ++++++ 7 files changed, 82 insertions(+), 52 deletions(-) create mode 100644 pre_commit/commands.py create mode 100644 tests/commands_test.py diff --git a/pre_commit/commands.py b/pre_commit/commands.py new file mode 100644 index 00000000..1411340c --- /dev/null +++ b/pre_commit/commands.py @@ -0,0 +1,25 @@ + +import os +import pkg_resources +import stat + + +def install(runner): + """Install the pre-commit hooks.""" + pre_commit_file = pkg_resources.resource_filename('pre_commit', 'resources/pre-commit.sh') + with open(runner.pre_commit_path, 'w') as pre_commit_file_obj: + pre_commit_file_obj.write(open(pre_commit_file).read()) + + original_mode = os.stat(runner.pre_commit_path).st_mode + os.chmod( + runner.pre_commit_path, + original_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH, + ) + return 0 + + +def uninstall(runner): + """Uninstall the pre-commit hooks.""" + if os.path.exists(runner.pre_commit_path): + os.remove(runner.pre_commit_path) + return 0 diff --git a/pre_commit/git.py b/pre_commit/git.py index 3ed28da4..7a50ead2 100644 --- a/pre_commit/git.py +++ b/pre_commit/git.py @@ -1,9 +1,7 @@ import functools import os import os.path -import pkg_resources import re -import stat from plumbum import local from pre_commit.util import memoize_by_cwd @@ -24,23 +22,6 @@ def get_root(): return _get_root_new() -@memoize_by_cwd -def get_pre_commit_path(): - return os.path.join(get_root(), '.git/hooks/pre-commit') - - -def create_pre_commit(): - path = get_pre_commit_path() - pre_commit_file = pkg_resources.resource_filename('pre_commit', 'resources/pre-commit.sh') - local.path(path).write(local.path(pre_commit_file).read()) - original_mode = os.stat(path).st_mode - os.chmod(path, original_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) - - -def remove_pre_commit(): - local.path(get_pre_commit_path()).delete() - - def get_head_sha(git_repo_path): with local.cwd(git_repo_path): return local['git']['rev-parse', 'HEAD']().strip() diff --git a/pre_commit/run.py b/pre_commit/run.py index bd25b53d..39189e0f 100644 --- a/pre_commit/run.py +++ b/pre_commit/run.py @@ -4,6 +4,7 @@ import os.path import subprocess import sys +from pre_commit import commands from pre_commit import git from pre_commit.runner import Runner from pre_commit.util import entry @@ -126,13 +127,13 @@ def run(argv): runner = Runner.create() if args.command == 'install': - git.create_pre_commit() - print 'pre-commit installed at {0}'.format(git.get_pre_commit_path()) - return 0 + retval = commands.install(runner) + print 'pre-commit installed at {0}'.format(runner.pre_commit_path) + return retval elif args.command == 'uninstall': - git.remove_pre_commit() + retval = commands.uninstall(runner) print 'pre-commit uninstalled' - return 0 + return retval elif args.command == 'run': if args.hook: return run_single_hook(runner, args.hook, all_files=args.all_files) @@ -148,6 +149,10 @@ def run(argv): 'Command {0} not implemented.'.format(args.command) ) + raise AssertionError( + 'Command {0} failed to exit with a returncode'.format(args.command) + ) + if __name__ == '__main__': sys.exit(run()) diff --git a/pre_commit/runner.py b/pre_commit/runner.py index 7cb7dee2..0c17cd76 100644 --- a/pre_commit/runner.py +++ b/pre_commit/runner.py @@ -40,3 +40,7 @@ class Runner(object): """Returns a tuple of the configured repositories.""" config = load_config(self.config_file_path) return tuple(map(Repository, config)) + + @cached_property + def pre_commit_path(self): + return os.path.join(self.git_root, '.git/hooks/pre-commit') diff --git a/tests/commands_test.py b/tests/commands_test.py new file mode 100644 index 00000000..d99a5ab3 --- /dev/null +++ b/tests/commands_test.py @@ -0,0 +1,37 @@ + +import os +import os.path +import pkg_resources +import stat + +from pre_commit.commands import install +from pre_commit.commands import uninstall +from pre_commit.runner import Runner + + +def test_install_pre_commit(empty_git_dir): + runner = Runner(empty_git_dir) + ret = install(runner) + assert ret == 0 + assert os.path.exists(runner.pre_commit_path) + pre_commit_contents = open(runner.pre_commit_path).read() + pre_commit_sh = pkg_resources.resource_filename('pre_commit', 'resources/pre-commit.sh') + expected_contents = open(pre_commit_sh).read() + assert pre_commit_contents == expected_contents + stat_result = os.stat(runner.pre_commit_path) + assert stat_result.st_mode & (stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) + + +def test_uninstall_pre_commit_does_not_blow_up_when_not_there(empty_git_dir): + runner = Runner(empty_git_dir) + ret = uninstall(runner) + assert ret == 0 + + +def test_uninstall(empty_git_dir): + runner = Runner(empty_git_dir) + assert not os.path.exists(runner.pre_commit_path) + install(runner) + assert os.path.exists(runner.pre_commit_path) + uninstall(runner) + assert not os.path.exists(runner.pre_commit_path) diff --git a/tests/git_test.py b/tests/git_test.py index f625ac83..5ce2a7f0 100644 --- a/tests/git_test.py +++ b/tests/git_test.py @@ -1,7 +1,5 @@ -import os import pytest -import stat from plumbum import local from pre_commit import git @@ -17,32 +15,6 @@ def test_get_root(empty_git_dir): assert git.get_root() == empty_git_dir -def test_get_pre_commit_path(empty_git_dir): - assert git.get_pre_commit_path() == '{0}/.git/hooks/pre-commit'.format( - empty_git_dir, - ) - - -def test_create_pre_commit(empty_git_dir): - git.create_pre_commit() - assert len(open(git.get_pre_commit_path(), 'r').read()) > 0 - stat_result = os.stat(git.get_pre_commit_path()) - assert stat_result.st_mode & stat.S_IXUSR - assert stat_result.st_mode & stat.S_IXGRP - assert stat_result.st_mode & stat.S_IXOTH - - -def test_remove_pre_commit(empty_git_dir): - git.remove_pre_commit() - - assert not os.path.exists(git.get_pre_commit_path()) - - git.create_pre_commit() - git.remove_pre_commit() - - assert not os.path.exists(git.get_pre_commit_path()) - - @pytest.fixture def get_files_matching_func(): def get_filenames(): diff --git a/tests/runner_test.py b/tests/runner_test.py index 0ec6bbe5..167b7bb6 100644 --- a/tests/runner_test.py +++ b/tests/runner_test.py @@ -53,3 +53,9 @@ def test_repositories(consumer_repo): 'git@github.com:pre-commit/pre-commit-hooks', 'git@github.com:pre-commit/pre-commit', ] + + +def test_pre_commit_path(): + runner = Runner('foo/bar') + expected_path = os.path.join('foo/bar', '.git/hooks/pre-commit') + assert runner.pre_commit_path == expected_path