1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
import os
from unittest.mock import patch, call
from gitlint.shell import ErrorReturnCode, CommandNotFound
from gitlint.tests.base import BaseTestCase
from gitlint.git import GitContext, GitContextError, GitNotInstalledError, git_commentchar, git_hooks_dir
class GitTests(BaseTestCase):
# Expected special_args passed to 'sh'
expected_sh_special_args = {"_tty_out": False, "_cwd": "fåke/path"}
@patch("gitlint.git.sh")
def test_get_latest_commit_command_not_found(self, sh):
sh.git.side_effect = CommandNotFound("git")
expected_msg = (
"'git' command not found. You need to install git to use gitlint on a local repository. "
+ "See https://git-scm.com/book/en/v2/Getting-Started-Installing-Git on how to install git."
)
with self.assertRaisesMessage(GitNotInstalledError, expected_msg):
GitContext.from_local_repository("fåke/path")
# assert that commit message was read using git command
sh.git.assert_called_once_with("log", "-1", "--pretty=%H", **self.expected_sh_special_args)
@patch("gitlint.git.sh")
def test_get_latest_commit_git_error(self, sh):
# Current directory not a git repo
err = b"fatal: Not a git repository (or any of the parent directories): .git"
sh.git.side_effect = ErrorReturnCode("git log -1 --pretty=%H", b"", err)
with self.assertRaisesMessage(GitContextError, "fåke/path is not a git repository."):
GitContext.from_local_repository("fåke/path")
# assert that commit message was read using git command
sh.git.assert_called_once_with("log", "-1", "--pretty=%H", **self.expected_sh_special_args)
sh.git.reset_mock()
err = b"fatal: Random git error"
sh.git.side_effect = ErrorReturnCode("git log -1 --pretty=%H", b"", err)
expected_msg = f"An error occurred while executing 'git log -1 --pretty=%H': {err}"
with self.assertRaisesMessage(GitContextError, expected_msg):
GitContext.from_local_repository("fåke/path")
# assert that commit message was read using git command
sh.git.assert_called_once_with("log", "-1", "--pretty=%H", **self.expected_sh_special_args)
@patch("gitlint.git.sh")
def test_git_no_commits_error(self, sh):
# No commits: returned by 'git log'
err = b"fatal: your current branch 'main' does not have any commits yet"
sh.git.side_effect = ErrorReturnCode("git log -1 --pretty=%H", b"", err)
expected_msg = "Current branch has no commits. Gitlint requires at least one commit to function."
with self.assertRaisesMessage(GitContextError, expected_msg):
GitContext.from_local_repository("fåke/path")
# assert that commit message was read using git command
sh.git.assert_called_once_with("log", "-1", "--pretty=%H", **self.expected_sh_special_args)
@patch("gitlint.git.sh")
def test_git_no_commits_get_branch(self, sh):
"""Check that we can still read the current branch name when there's no commits. This is useful when
when trying to lint the first commit using the --staged flag.
"""
# Unknown reference 'HEAD' commits: returned by 'git rev-parse'
err = (
b"HEAD"
b"fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree."
b"Use '--' to separate paths from revisions, like this:"
b"'git <command> [<revision>...] -- [<file>...]'"
)
sh.git.side_effect = [
"#\n", # git config --get core.commentchar
ErrorReturnCode("rev-parse --abbrev-ref HEAD", b"", err),
"test-branch", # git branch --show-current
]
context = GitContext.from_commit_msg("test")
self.assertEqual(context.current_branch, "test-branch")
# assert that we try using `git rev-parse` first, and if that fails (as will be the case with the first commit),
# we fallback to `git branch --show-current` to determine the current branch name.
expected_calls = [
call("config", "--get", "core.commentchar", _tty_out=False, _cwd=None, _ok_code=[0, 1]),
call("rev-parse", "--abbrev-ref", "HEAD", _tty_out=False, _cwd=None),
call("branch", "--show-current", _tty_out=False, _cwd=None),
]
self.assertEqual(sh.git.mock_calls, expected_calls)
@patch("gitlint.git._git")
def test_git_commentchar(self, git):
git.return_value.exit_code = 1
self.assertEqual(git_commentchar(), "#")
git.return_value.exit_code = 0
git.return_value = "ä"
self.assertEqual(git_commentchar(), "ä")
git.return_value = ";\n"
self.assertEqual(git_commentchar(os.path.join("/föo", "bar")), ";")
git.assert_called_with("config", "--get", "core.commentchar", _ok_code=[0, 1], _cwd=os.path.join("/föo", "bar"))
@patch("gitlint.git._git")
def test_git_hooks_dir(self, git):
hooks_dir = os.path.join("föo", ".git", "hooks")
git.return_value = hooks_dir + "\n"
self.assertEqual(git_hooks_dir("/blä"), os.path.abspath(os.path.join("/blä", hooks_dir)))
git.assert_called_once_with("rev-parse", "--git-path", "hooks", _cwd="/blä")
|