diff options
author | Joris Roovers <joris.roovers@gmail.com> | 2022-09-19 11:39:00 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-19 11:39:00 +0200 |
commit | 07170186ea5327e7e9b0ccd6e80ce74172f71b40 (patch) | |
tree | a8dac0fcda8e5f7c80de339b3364f746f15ce114 /qa | |
parent | af27803f5a29741ffce0d6326773c44dc755cd44 (diff) |
GitCommit object now contains diff stats information (#334)
GitCommit now contains a new changed_files_stats attribute which
is a dictionary mapping changed file paths to a corresponding
GitChangedFileStats object which contains the number of additions and
deletions in that file.
Diffstat (limited to 'qa')
-rw-r--r-- | qa/base.py | 33 | ||||
-rw-r--r-- | qa/expected/test_commits/test_lint_staged_msg_filename_1 | 4 | ||||
-rw-r--r-- | qa/expected/test_commits/test_lint_staged_stdin_1 | 4 | ||||
-rw-r--r-- | qa/expected/test_config/test_config_from_env_1 | 4 | ||||
-rw-r--r-- | qa/expected/test_config/test_config_from_env_2 | 3 | ||||
-rw-r--r-- | qa/expected/test_config/test_config_from_file_debug_1 | 4 | ||||
-rw-r--r-- | qa/expected/test_gitlint/test_commit_binary_file_1 | 92 | ||||
-rw-r--r-- | qa/test_commits.py | 20 | ||||
-rw-r--r-- | qa/test_config.py | 12 | ||||
-rw-r--r-- | qa/test_gitlint.py | 34 |
10 files changed, 193 insertions, 17 deletions
@@ -75,11 +75,23 @@ class BaseTestCase(TestCase): return tmp_git_repo @staticmethod - def create_file(parent_dir): + def create_file(parent_dir, content=None): """Creates a file inside a passed directory. Returns filename.""" test_filename = "test-fïle-" + str(uuid4()) - # pylint: disable=consider-using-with - open(os.path.join(parent_dir, test_filename), "a", encoding=DEFAULT_ENCODING).close() + full_path = os.path.join(parent_dir, test_filename) + + if content: + if isinstance(content, bytes): + open_kwargs = {"mode": "wb"} + else: + open_kwargs = {"mode": "w", "encoding": DEFAULT_ENCODING} + + with open(full_path, **open_kwargs) as f: # pylint: disable=unspecified-encoding + f.write(content) + else: + # pylint: disable=consider-using-with + open(full_path, "a", encoding=DEFAULT_ENCODING).close() + return test_filename @staticmethod @@ -95,7 +107,9 @@ class BaseTestCase(TestCase): tmp_config = self.create_tmpfile(contents) return self.create_environment({"GIT_CONFIG": tmp_config}) - def create_simple_commit(self, message, out=None, ok_code=None, env=None, git_repo=None, tty_in=False): + def create_simple_commit( + self, message, *, file_contents=None, out=None, ok_code=None, env=None, git_repo=None, tty_in=False + ): """Creates a simple commit with an empty test file. :param message: Commit message for the commit.""" @@ -108,7 +122,7 @@ class BaseTestCase(TestCase): environment = self.create_environment(env) # Create file and add to git - test_filename = self.create_file(git_repo) + test_filename = self.create_file(git_repo, file_contents) git("add", test_filename, _cwd=git_repo) # https://amoffat.github.io/sh/#interactive-callbacks if not ok_code: @@ -132,8 +146,15 @@ class BaseTestCase(TestCase): # Not using a context manager to avoid unnecessary indentation in test code tmpfile, tmpfilepath = tempfile.mkstemp() self.tmpfiles.append(tmpfilepath) - with open(tmpfile, "w", encoding=DEFAULT_ENCODING) as f: + + if isinstance(content, bytes): + open_kwargs = {"mode": "wb"} + else: + open_kwargs = {"mode": "w", "encoding": DEFAULT_ENCODING} + + with open(tmpfile, **open_kwargs) as f: # pylint: disable=unspecified-encoding f.write(content) + return tmpfilepath @staticmethod diff --git a/qa/expected/test_commits/test_lint_staged_msg_filename_1 b/qa/expected/test_commits/test_lint_staged_msg_filename_1 index 882a82c..dd565b3 100644 --- a/qa/expected/test_commits/test_lint_staged_msg_filename_1 +++ b/qa/expected/test_commits/test_lint_staged_msg_filename_1 @@ -68,10 +68,10 @@ DEBUG: gitlint.cli Using --msg-filename. DEBUG: gitlint.git ('config', '--get', 'core.commentchar') DEBUG: gitlint.cli Linting 1 commit(s) DEBUG: gitlint.lint Linting commit [SHA UNKNOWN] +DEBUG: gitlint.git ('diff', '--staged', '--numstat', '-r') DEBUG: gitlint.git ('config', '--get', 'user.name') DEBUG: gitlint.git ('config', '--get', 'user.email') DEBUG: gitlint.git ('rev-parse', '--abbrev-ref', 'HEAD') -DEBUG: gitlint.git ('diff', '--staged', '--name-only', '-r') DEBUG: gitlint.lint Commit Object --- Commit Message ---- WIP: from fïle test. @@ -85,6 +85,8 @@ is-squash-commit: False is-revert-commit: False Branches: ['main'] Changed Files: {changed_files} +Changed Files Stats: + {changed_files_stats} ----------------------- 1: T3 Title has trailing punctuation (.): "WIP: from fïle test." 1: T5 Title contains the word 'WIP' (case-insensitive): "WIP: from fïle test." diff --git a/qa/expected/test_commits/test_lint_staged_stdin_1 b/qa/expected/test_commits/test_lint_staged_stdin_1 index 9d6153a..f999e39 100644 --- a/qa/expected/test_commits/test_lint_staged_stdin_1 +++ b/qa/expected/test_commits/test_lint_staged_stdin_1 @@ -70,10 +70,10 @@ DEBUG: gitlint.cli Stdin detected and not ignored. Using as input. DEBUG: gitlint.git ('config', '--get', 'core.commentchar') DEBUG: gitlint.cli Linting 1 commit(s) DEBUG: gitlint.lint Linting commit [SHA UNKNOWN] +DEBUG: gitlint.git ('diff', '--staged', '--numstat', '-r') DEBUG: gitlint.git ('config', '--get', 'user.name') DEBUG: gitlint.git ('config', '--get', 'user.email') DEBUG: gitlint.git ('rev-parse', '--abbrev-ref', 'HEAD') -DEBUG: gitlint.git ('diff', '--staged', '--name-only', '-r') DEBUG: gitlint.lint Commit Object --- Commit Message ---- WIP: Pïpe test. @@ -87,6 +87,8 @@ is-squash-commit: False is-revert-commit: False Branches: ['main'] Changed Files: {changed_files} +Changed Files Stats: + {changed_files_stats} ----------------------- 1: T3 Title has trailing punctuation (.): "WIP: Pïpe test." 1: T5 Title contains the word 'WIP' (case-insensitive): "WIP: Pïpe test." diff --git a/qa/expected/test_config/test_config_from_env_1 b/qa/expected/test_config/test_config_from_env_1 index bbbdcc2..c828067 100644 --- a/qa/expected/test_config/test_config_from_env_1 +++ b/qa/expected/test_config/test_config_from_env_1 @@ -72,8 +72,8 @@ DEBUG: gitlint.cli Linting 1 commit(s) DEBUG: gitlint.git ('log', '{commit_sha}', '-1', '--pretty=%aN%x00%aE%x00%ai%x00%P%n%B') DEBUG: gitlint.git ('config', '--get', 'core.commentchar') DEBUG: gitlint.lint Linting commit {commit_sha} +DEBUG: gitlint.git ('diff-tree', '--no-commit-id', '--numstat', '-r', '--root', '{commit_sha}') DEBUG: gitlint.git ('branch', '--contains', '{commit_sha}') -DEBUG: gitlint.git ('diff-tree', '--no-commit-id', '--name-only', '-r', '--root', '{commit_sha}') DEBUG: gitlint.lint Commit Object --- Commit Message ---- WIP: Thïs is a title thåt is a bit longer. @@ -90,6 +90,8 @@ is-squash-commit: False is-revert-commit: False Branches: ['main'] Changed Files: {changed_files} +Changed Files Stats: + {changed_files_stats} ----------------------- 1: CC1 Body does not contain a 'Signed-off-by' line 1: CT1 Title does not start with one of fix, feat, chore, docs, style, refactor, perf, test, revert, ci, build diff --git a/qa/expected/test_config/test_config_from_env_2 b/qa/expected/test_config/test_config_from_env_2 index 6049f32..a923f22 100644 --- a/qa/expected/test_config/test_config_from_env_2 +++ b/qa/expected/test_config/test_config_from_env_2 @@ -68,10 +68,10 @@ DEBUG: gitlint.cli Using --msg-filename. DEBUG: gitlint.git ('config', '--get', 'core.commentchar') DEBUG: gitlint.cli Linting 1 commit(s) DEBUG: gitlint.lint Linting commit [SHA UNKNOWN] +DEBUG: gitlint.git ('diff', '--staged', '--numstat', '-r') DEBUG: gitlint.git ('config', '--get', 'user.name') DEBUG: gitlint.git ('config', '--get', 'user.email') DEBUG: gitlint.git ('rev-parse', '--abbrev-ref', 'HEAD') -DEBUG: gitlint.git ('diff', '--staged', '--name-only', '-r') DEBUG: gitlint.lint Commit Object --- Commit Message ---- WIP: msg-fïlename test. @@ -85,5 +85,6 @@ is-squash-commit: False is-revert-commit: False Branches: ['main'] Changed Files: [] +Changed Files Stats: {{}} ----------------------- DEBUG: gitlint.cli Exit Code = 3 diff --git a/qa/expected/test_config/test_config_from_file_debug_1 b/qa/expected/test_config/test_config_from_file_debug_1 index f136348..80d26e8 100644 --- a/qa/expected/test_config/test_config_from_file_debug_1 +++ b/qa/expected/test_config/test_config_from_file_debug_1 @@ -69,8 +69,8 @@ DEBUG: gitlint.cli Linting 1 commit(s) DEBUG: gitlint.git ('log', '{commit_sha}', '-1', '--pretty=%aN%x00%aE%x00%ai%x00%P%n%B') DEBUG: gitlint.git ('config', '--get', 'core.commentchar') DEBUG: gitlint.lint Linting commit {commit_sha} +DEBUG: gitlint.git ('diff-tree', '--no-commit-id', '--numstat', '-r', '--root', '{commit_sha}') DEBUG: gitlint.git ('branch', '--contains', '{commit_sha}') -DEBUG: gitlint.git ('diff-tree', '--no-commit-id', '--name-only', '-r', '--root', '{commit_sha}') DEBUG: gitlint.lint Commit Object --- Commit Message ---- WIP: Thïs is a title thåt is a bit longer. @@ -87,6 +87,8 @@ is-squash-commit: False is-revert-commit: False Branches: ['main'] Changed Files: {changed_files} +Changed Files Stats: + {changed_files_stats} ----------------------- 1: T1 Title exceeds max length (42>20) 1: T5 Title contains the word 'WIP' (case-insensitive) diff --git a/qa/expected/test_gitlint/test_commit_binary_file_1 b/qa/expected/test_gitlint/test_commit_binary_file_1 new file mode 100644 index 0000000..8e87051 --- /dev/null +++ b/qa/expected/test_gitlint/test_commit_binary_file_1 @@ -0,0 +1,92 @@ +DEBUG: gitlint.cli To report issues, please visit https://github.com/jorisroovers/gitlint/issues +DEBUG: gitlint.cli Platform: {platform} +DEBUG: gitlint.cli Python version: {python_version} +DEBUG: gitlint.git ('--version',) +DEBUG: gitlint.cli Git version: {git_version} +DEBUG: gitlint.cli Gitlint version: {gitlint_version} +DEBUG: gitlint.cli GITLINT_USE_SH_LIB: {GITLINT_USE_SH_LIB} +DEBUG: gitlint.cli DEFAULT_ENCODING: {DEFAULT_ENCODING} +DEBUG: gitlint.cli Configuration +config-path: None +[GENERAL] +extra-path: None +contrib: [] +ignore: +ignore-merge-commits: True +ignore-fixup-commits: True +ignore-fixup-amend-commits: True +ignore-squash-commits: True +ignore-revert-commits: True +ignore-stdin: False +staged: False +fail-without-commits: False +verbosity: 3 +debug: True +target: {target} +[RULES] + I1: ignore-by-title + ignore=all + regex=None + I2: ignore-by-body + ignore=all + regex=None + I3: ignore-body-lines + regex=None + I4: ignore-by-author-name + ignore=all + regex=None + T1: title-max-length + line-length=72 + T2: title-trailing-whitespace + T6: title-leading-whitespace + T3: title-trailing-punctuation + T4: title-hard-tab + T5: title-must-not-contain-word + words=WIP + T7: title-match-regex + regex=None + T8: title-min-length + min-length=5 + B1: body-max-line-length + line-length=80 + B5: body-min-length + min-length=20 + B6: body-is-missing + ignore-merge-commits=True + B2: body-trailing-whitespace + B3: body-hard-tab + B4: body-first-line-empty + B7: body-changed-file-mention + files= + B8: body-match-regex + regex=None + M1: author-valid-email + regex=[^@ ]+@[^@ ]+\.[^@ ]+ + +DEBUG: gitlint.cli No --msg-filename flag, no or empty data passed to stdin. Using the local repo. +DEBUG: gitlint.git ('log', '-1', '--pretty=%H') +DEBUG: gitlint.cli Linting 1 commit(s) +DEBUG: gitlint.git ('log', '{commit_sha}', '-1', '--pretty=%aN%x00%aE%x00%ai%x00%P%n%B') +DEBUG: gitlint.git ('config', '--get', 'core.commentchar') +DEBUG: gitlint.lint Linting commit {commit_sha} +DEBUG: gitlint.git ('diff-tree', '--no-commit-id', '--numstat', '-r', '--root', '{commit_sha}') +DEBUG: gitlint.git ('branch', '--contains', '{commit_sha}') +DEBUG: gitlint.lint Commit Object +--- Commit Message ---- +Sïmple commit + +--- Meta info --------- +Author: gitlint-test-user <gitlint@test.com> +Date: {commit_date} +is-merge-commit: False +is-fixup-commit: False +is-fixup-amend-commit: False +is-squash-commit: False +is-revert-commit: False +Branches: ['main'] +Changed Files: {changed_files} +Changed Files Stats: + {changed_files_stats} +----------------------- +3: B6 Body message is missing +DEBUG: gitlint.cli Exit Code = 1 diff --git a/qa/test_commits.py b/qa/test_commits.py index 8581504..d40c211 100644 --- a/qa/test_commits.py +++ b/qa/test_commits.py @@ -155,7 +155,15 @@ class CommitsTests(BaseTestCase): # Determine variable parts of expected output expected_kwargs = self.get_debug_vars_last_commit() - expected_kwargs.update({"changed_files": sorted([filename1, filename2])}) + filenames = sorted([filename1, filename2]) + expected_kwargs.update( + { + "changed_files": filenames, + "changed_files_stats": ( + f"{filenames[0]}: 0 additions, 0 deletions\n {filenames[1]}: 0 additions, 0 deletions" + ), + } + ) # It's not really possible to determine the "Date: ..." line that is part of the debug output as this date # is not taken from git but instead generated by gitlint itself. As a workaround, we extract the date from the @@ -199,7 +207,15 @@ class CommitsTests(BaseTestCase): # Determine variable parts of expected output expected_kwargs = self.get_debug_vars_last_commit() - expected_kwargs.update({"changed_files": sorted([filename1, filename2])}) + filenames = sorted([filename1, filename2]) + expected_kwargs.update( + { + "changed_files": filenames, + "changed_files_stats": ( + f"{filenames[0]}: 0 additions, 0 deletions\n {filenames[1]}: 0 additions, 0 deletions" + ), + } + ) # It's not really possible to determine the "Date: ..." line that is part of the debug output as this date # is not taken from git but instead generated by gitlint itself. As a workaround, we extract the date from the diff --git a/qa/test_config.py b/qa/test_config.py index c9ea4e7..1225f6a 100644 --- a/qa/test_config.py +++ b/qa/test_config.py @@ -73,7 +73,13 @@ class ConfigTests(BaseTestCase): output = gitlint("--config", config_path, "--debug", _cwd=target_repo, _tty_in=True, _ok_code=[5]) expected_kwargs = self.get_debug_vars_last_commit(git_repo=target_repo) - expected_kwargs.update({"config_path": config_path, "changed_files": [filename]}) + expected_kwargs.update( + { + "config_path": config_path, + "changed_files": [filename], + "changed_files_stats": f"{filename}: 0 additions, 0 deletions", + } + ) self.assertEqualStdout( output, self.get_expected("test_config/test_config_from_file_debug_1", expected_kwargs) ) @@ -103,7 +109,9 @@ class ConfigTests(BaseTestCase): ) output = gitlint(_env=env, _cwd=self.tmp_git_repo, _tty_in=True, _ok_code=[5]) expected_kwargs = self.get_debug_vars_last_commit(git_repo=target_repo) - expected_kwargs.update({"changed_files": [filename]}) + expected_kwargs.update( + {"changed_files": [filename], "changed_files_stats": f"{filename}: 0 additions, 0 deletions"} + ) self.assertEqualStdout(output, self.get_expected("test_config/test_config_from_env_1", expected_kwargs)) diff --git a/qa/test_gitlint.py b/qa/test_gitlint.py index bad58a1..6af19c8 100644 --- a/qa/test_gitlint.py +++ b/qa/test_gitlint.py @@ -191,7 +191,12 @@ class IntegrationTests(BaseTestCase): # necessary but seems good for consistency. env = self.create_tmp_git_config("[user]\n email = test-emåil@foo.com\n") output = gitlint( - "--staged", "--msg-filename", tmp_commit_msg_file, _ok_code=[self.GIT_CONTEXT_ERROR_CODE], _env=env + "--staged", + "--msg-filename", + tmp_commit_msg_file, + _ok_code=[self.GIT_CONTEXT_ERROR_CODE], + _env=env, + _cwd=self.tmp_git_repo, ) expected = "Missing git configuration: please set user.name\n" self.assertEqualStdout(output, expected) @@ -201,7 +206,12 @@ class IntegrationTests(BaseTestCase): tmp_commit_msg_file = self.create_tmpfile("WIP: msg-fïlename NO email test.") env = self.create_tmp_git_config("[user]\n name = test åuthor\n") output = gitlint( - "--staged", "--msg-filename", tmp_commit_msg_file, _ok_code=[self.GIT_CONTEXT_ERROR_CODE], _env=env + "--staged", + "--msg-filename", + tmp_commit_msg_file, + _ok_code=[self.GIT_CONTEXT_ERROR_CODE], + _env=env, + _cwd=self.tmp_git_repo, ) expected = "Missing git configuration: please set user.email\n" self.assertEqualStdout(output, expected) @@ -227,3 +237,23 @@ class IntegrationTests(BaseTestCase): echo("WIP: Pïpe test."), "--staged", _cwd=empty_git_repo, _tty_in=False, _err_to_out=True, _ok_code=[3] ) self.assertEqualStdout(output, expected) + + def test_commit_binary_file(self): + """When committing a binary file, git shows somewhat different output in diff commands, + this test ensures gitlint deals with that correctly""" + binary_filename = self.create_simple_commit("Sïmple commit", file_contents=bytes([0x48, 0x00, 0x49, 0x00])) + output = gitlint( + "--debug", + _ok_code=1, + _cwd=self.tmp_git_repo, + ) + + expected_kwargs = self.get_debug_vars_last_commit() + expected_kwargs.update( + { + "changed_files": [binary_filename], + "changed_files_stats": (f"{binary_filename}: None additions, None deletions"), + } + ) + expected = self.get_expected("test_gitlint/test_commit_binary_file_1", expected_kwargs) + self.assertEqualStdout(output, expected) |