From 045c0842901d7a1ad49ad18169f075aeffbbe74b Mon Sep 17 00:00:00 2001 From: Tamas Szabo Date: Sat, 25 Jul 2020 15:47:04 +0300 Subject: [PATCH] Adds lazy option to git hook. Fixes #1214 --- README.md | 7 ++++++- isort/hooks.py | 8 +++++++- tests/test_hooks.py | 22 +++++++++++++++++++--- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4b7e55825..0ce08a04d 100644 --- a/README.md +++ b/README.md @@ -526,13 +526,18 @@ include the following in `.git/hooks/pre-commit`: import sys from isort.hooks import git_hook -sys.exit(git_hook(strict=True, modify=True)) +sys.exit(git_hook(strict=True, modify=True, lazy=True)) ``` If you just want to display warnings, but allow the commit to happen anyway, call `git_hook` without the strict parameter. If you want to display warnings, but not also fix the code, call `git_hook` without the modify parameter. +The `lazy` argument is to support users who are "lazy" to add files +individually to the index and tend to use `git commit -a` instead. +Set it to `True` to ensure all tracked files are properly isorted, +leave it out or set it to `False` to check only files added to your +index. Setuptools integration ---------------------- diff --git a/isort/hooks.py b/isort/hooks.py index 892bd312c..3198a1d09 100644 --- a/isort/hooks.py +++ b/isort/hooks.py @@ -33,7 +33,7 @@ def get_lines(command: List[str]) -> List[str]: return [line.strip() for line in stdout.splitlines()] -def git_hook(strict: bool = False, modify: bool = False) -> int: +def git_hook(strict: bool = False, modify: bool = False, lazy: bool = False) -> int: """ Git pre-commit hook to check staged files for isort errors @@ -43,12 +43,18 @@ def git_hook(strict: bool = False, modify: bool = False) -> int: :param bool modify - if True, fix the sources if they are not sorted properly. If False, only report result without modifying anything. + :param bool lazy - if True, also check/fix unstaged files. + This is useful if you frequently use ``git commit -a`` for example. + If False, ony check/fix the staged files for isort errors. :return number of errors if in strict mode, 0 otherwise. """ # Get list of files modified and staged diff_cmd = ["git", "diff-index", "--cached", "--name-only", "--diff-filter=ACMRTUXB", "HEAD"] + if lazy: + diff_cmd.remove("--cached") + files_modified = get_lines(diff_cmd) if not files_modified: return 0 diff --git a/tests/test_hooks.py b/tests/test_hooks.py index c84d6d5c9..677b0d209 100644 --- a/tests/test_hooks.py +++ b/tests/test_hooks.py @@ -11,9 +11,25 @@ def test_git_hook(src_dir): # Ensure correct subprocess command is called with patch("subprocess.run", MagicMock()) as run_mock: hooks.git_hook() - assert run_mock.called_with( - ["git", "diff-index", "--cached", "--name-only", "--diff-filter=ACMRTUXB HEAD"] - ) + assert run_mock.called_once() + assert run_mock.call_args[0][0] == [ + "git", + "diff-index", + "--cached", + "--name-only", + "--diff-filter=ACMRTUXB", + "HEAD", + ] + + hooks.git_hook(lazy=True) + assert run_mock.called_once() + assert run_mock.call_args[0][0] == [ + "git", + "diff-index", + "--name-only", + "--diff-filter=ACMRTUXB", + "HEAD", + ] # Test with incorrectly sorted file returned from git with patch(