From 300f5026c4461b154645fe6ea19aa223b03de111 Mon Sep 17 00:00:00 2001 From: Evgenii Alekseev Date: Thu, 22 Aug 2024 18:17:56 +0300 Subject: [PATCH] feat: add ability to suppress git hints It can be done by setting options in command. The commit author/email is also now using this logic --- .pylintrc | 3 + src/ahriman/application/handlers/patch.py | 1 + src/ahriman/application/handlers/update.py | 2 +- src/ahriman/core/build_tools/sources.py | 59 +++++--- .../ahriman/core/build_tools/test_sources.py | 132 ++++++++++-------- 5 files changed, 117 insertions(+), 80 deletions(-) diff --git a/.pylintrc b/.pylintrc index b19c2614..fcdbf483 100644 --- a/.pylintrc +++ b/.pylintrc @@ -82,6 +82,7 @@ limit-inference-results=100 # List of plugins (as comma separated values of python module names) to load, # usually to register additional checkers. load-plugins=pylint.extensions.docparams, + pylint.extensions.bad_builtin, definition_order, import_order, @@ -131,6 +132,8 @@ attr-naming-style=snake_case # style. #attr-rgx= +bad-functions=print, + # Bad variable names which should always be refused, separated by a comma. bad-names=foo, bar, diff --git a/src/ahriman/application/handlers/patch.py b/src/ahriman/application/handlers/patch.py index ef58e068..2a80b416 100644 --- a/src/ahriman/application/handlers/patch.py +++ b/src/ahriman/application/handlers/patch.py @@ -98,6 +98,7 @@ class Patch(Handler): PkgbuildPatch: created patch for the PKGBUILD function """ if patch_path is None: + # pylint: disable=bad-builtin print("Post new function or variable value below. Press Ctrl-D to finish:", file=sys.stderr) patch = "".join(list(sys.stdin)) else: diff --git a/src/ahriman/application/handlers/update.py b/src/ahriman/application/handlers/update.py index 490aeeee..fbd48b77 100644 --- a/src/ahriman/application/handlers/update.py +++ b/src/ahriman/application/handlers/update.py @@ -77,5 +77,5 @@ class Update(Handler): Callable[[str], None]: in case if dry_run is set it will return print, logger otherwise """ def inner(line: str) -> None: - return print(line) if dry_run else application.logger.info(line) + return print(line) if dry_run else application.logger.info(line) # pylint: disable=bad-builtin return inner diff --git a/src/ahriman/core/build_tools/sources.py b/src/ahriman/core/build_tools/sources.py index d32d90c0..234a84d6 100644 --- a/src/ahriman/core/build_tools/sources.py +++ b/src/ahriman/core/build_tools/sources.py @@ -19,6 +19,7 @@ # import shutil +from collections.abc import Generator from pathlib import Path from ahriman.core.exceptions import CalledProcessError @@ -38,10 +39,14 @@ class Sources(LazyLogging): DEFAULT_BRANCH(str): (class attribute) default branch to process git repositories. Must be used only for local stored repositories, use RemoteSource descriptor instead for real packages DEFAULT_COMMIT_AUTHOR(tuple[str, str]): (class attribute) default commit author to be used if none set + GITCONFIG(dict[str, str]): (class attribute) git config options to suppress annoying hints """ DEFAULT_BRANCH = "master" # default fallback branch DEFAULT_COMMIT_AUTHOR = ("ahriman", "ahriman@localhost") + GITCONFIG = { + "init.defaultBranch": DEFAULT_BRANCH, + } @staticmethod def changes(source_dir: Path, last_commit_sha: str | None) -> str | None: @@ -106,15 +111,15 @@ class Sources(LazyLogging): instance.fetch_until(sources_dir, branch=branch) elif remote.git_url is not None: instance.logger.info("clone remote %s to %s using branch %s", remote.git_url, sources_dir, branch) - check_output("git", "clone", "--quiet", "--depth", "1", "--branch", branch, "--single-branch", + check_output(*instance.git(), "clone", "--quiet", "--depth", "1", "--branch", branch, "--single-branch", remote.git_url, str(sources_dir), cwd=sources_dir.parent, logger=instance.logger) else: # it will cause an exception later instance.logger.error("%s is not initialized, but no remote provided", sources_dir) # and now force reset to our branch - check_output("git", "checkout", "--force", branch, cwd=sources_dir, logger=instance.logger) - check_output("git", "reset", "--quiet", "--hard", f"origin/{branch}", + check_output(*instance.git(), "checkout", "--force", branch, cwd=sources_dir, logger=instance.logger) + check_output(*instance.git(), "reset", "--quiet", "--hard", f"origin/{branch}", cwd=sources_dir, logger=instance.logger) # move content if required @@ -136,7 +141,7 @@ class Sources(LazyLogging): bool: True in case if there is any remote and false otherwise """ instance = Sources() - remotes = check_output("git", "remote", cwd=sources_dir, logger=instance.logger) + remotes = check_output(*instance.git(), "remote", cwd=sources_dir, logger=instance.logger) return bool(remotes) @staticmethod @@ -150,7 +155,7 @@ class Sources(LazyLogging): instance = Sources() if not (sources_dir / ".git").is_dir(): # skip initializing in case if it was already - check_output("git", "init", "--quiet", "--initial-branch", instance.DEFAULT_BRANCH, + check_output(*instance.git(), "init", "--quiet", "--initial-branch", instance.DEFAULT_BRANCH, cwd=sources_dir, logger=instance.logger) # extract local files... @@ -220,7 +225,7 @@ class Sources(LazyLogging): return # no changes to push, just skip action git_url, branch = remote.git_source() - check_output("git", "push", "--quiet", git_url, branch, cwd=sources_dir, logger=instance.logger) + check_output(*instance.git(), "push", "--quiet", git_url, branch, cwd=sources_dir, logger=instance.logger) def add(self, sources_dir: Path, *pattern: str, intent_to_add: bool = False) -> None: """ @@ -241,7 +246,7 @@ class Sources(LazyLogging): self.logger.info("found matching files %s", found_files) # add them to index args = ["--intent-to-add"] if intent_to_add else [] - check_output("git", "add", *args, *[str(fn.relative_to(sources_dir)) for fn in found_files], + check_output(*self.git(), "add", *args, *[str(fn.relative_to(sources_dir)) for fn in found_files], cwd=sources_dir, logger=self.logger) def commit(self, sources_dir: Path, message: str | None = None, @@ -264,15 +269,16 @@ class Sources(LazyLogging): if message is None: message = f"Autogenerated commit at {utcnow()}" args = ["--message", message] - environment: dict[str, str] = {} if commit_author is None: commit_author = self.DEFAULT_COMMIT_AUTHOR user, email = commit_author - environment["GIT_AUTHOR_NAME"] = environment["GIT_COMMITTER_NAME"] = user - environment["GIT_AUTHOR_EMAIL"] = environment["GIT_COMMITTER_EMAIL"] = email + gitconfig = { + "user.email": email, + "user.name": user, + } - check_output("git", "commit", "--quiet", *args, cwd=sources_dir, logger=self.logger, environment=environment) + check_output(*self.git(gitconfig), "commit", "--quiet", *args, cwd=sources_dir, logger=self.logger) return True @@ -290,7 +296,7 @@ class Sources(LazyLogging): args = [] if sha is not None: args.append(sha) - return check_output("git", "diff", *args, cwd=sources_dir, logger=self.logger) + return check_output(*self.git(), "diff", *args, cwd=sources_dir, logger=self.logger) def fetch_until(self, sources_dir: Path, *, branch: str | None = None, commit_sha: str | None = None) -> None: """ @@ -306,18 +312,37 @@ class Sources(LazyLogging): commits_count = 1 while commit_sha is not None: - command = ["git", "fetch", "--quiet", "--depth", str(commits_count)] + command = self.git() + ["fetch", "--quiet", "--depth", str(commits_count)] if branch is not None: command += ["origin", branch] check_output(*command, cwd=sources_dir, logger=self.logger) # fetch one more level try: # check if there is an object in current git directory - check_output("git", "cat-file", "-e", commit_sha, cwd=sources_dir, logger=self.logger) + check_output(*self.git(), "cat-file", "-e", commit_sha, cwd=sources_dir, logger=self.logger) commit_sha = None # reset search except CalledProcessError: commits_count += 1 # increase depth + def git(self, gitconfig: dict[str, str] | None = None) -> list[str]: + """ + git command prefix + + Args: + gitconfig(dict[str, str] | None, optional): additional git config flags if any (Default value = None) + + Returns: + list[str]: git command prefix with valid default flags + """ + gitconfig = gitconfig or {} + + def configuration_flags() -> Generator[str, None, None]: + for option, value in (self.GITCONFIG | gitconfig).items(): + yield "-c" + yield f"{option}=\"{value}\"" + + return ["git"] + list(configuration_flags()) + def has_changes(self, sources_dir: Path) -> bool: """ check if there are changes in current git tree @@ -329,7 +354,7 @@ class Sources(LazyLogging): bool: True if there are uncommitted changes and False otherwise """ # there is --exit-code argument to diff, however, there might be other process errors - changes = check_output("git", "diff", "--cached", "--name-only", cwd=sources_dir, logger=self.logger) + changes = check_output(*self.git(), "diff", "--cached", "--name-only", cwd=sources_dir, logger=self.logger) return bool(changes) def head(self, sources_dir: Path, ref_name: str = "HEAD") -> str: @@ -344,7 +369,7 @@ class Sources(LazyLogging): str: HEAD commit hash """ # we might want to parse git files instead though - return check_output("git", "rev-parse", ref_name, cwd=sources_dir, logger=self.logger) + return check_output(*self.git(), "rev-parse", ref_name, cwd=sources_dir, logger=self.logger) def move(self, pkgbuild_dir: Path, sources_dir: Path) -> None: """ @@ -372,7 +397,7 @@ class Sources(LazyLogging): # create patch self.logger.info("apply patch %s from database at %s", patch.key, sources_dir) if patch.is_plain_diff: - check_output("git", "apply", "--ignore-space-change", "--ignore-whitespace", + check_output(*self.git(), "apply", "--ignore-space-change", "--ignore-whitespace", cwd=sources_dir, input_data=patch.serialize(), logger=self.logger) else: patch.write(sources_dir / "PKGBUILD") diff --git a/tests/ahriman/core/build_tools/test_sources.py b/tests/ahriman/core/build_tools/test_sources.py index c1e8e1d7..41d1b8f6 100644 --- a/tests/ahriman/core/build_tools/test_sources.py +++ b/tests/ahriman/core/build_tools/test_sources.py @@ -74,7 +74,7 @@ def test_fetch_empty(remote_source: RemoteSource, mocker: MockerFixture) -> None check_output_mock.assert_not_called() -def test_fetch_existing(remote_source: RemoteSource, mocker: MockerFixture) -> None: +def test_fetch_existing(sources: Sources, remote_source: RemoteSource, mocker: MockerFixture) -> None: """ must fetch new package via fetch command """ @@ -86,18 +86,19 @@ def test_fetch_existing(remote_source: RemoteSource, mocker: MockerFixture) -> N head_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.head", return_value="sha") local = Path("local") - assert Sources.fetch(local, remote_source) == "sha" + assert sources.fetch(local, remote_source) == "sha" fetch_mock.assert_called_once_with(local, branch=remote_source.branch) check_output_mock.assert_has_calls([ - MockCall("git", "checkout", "--force", remote_source.branch, cwd=local, logger=pytest.helpers.anyvar(int)), - MockCall("git", "reset", "--quiet", "--hard", f"origin/{remote_source.branch}", + MockCall(*sources.git(), "checkout", "--force", remote_source.branch, + cwd=local, logger=pytest.helpers.anyvar(int)), + MockCall(*sources.git(), "reset", "--quiet", "--hard", f"origin/{remote_source.branch}", cwd=local, logger=pytest.helpers.anyvar(int)), ]) move_mock.assert_called_once_with(local.resolve(), local) head_mock.assert_called_once_with(local) -def test_fetch_new(remote_source: RemoteSource, mocker: MockerFixture) -> None: +def test_fetch_new(sources: Sources, remote_source: RemoteSource, mocker: MockerFixture) -> None: """ must fetch new package via clone command """ @@ -107,19 +108,21 @@ def test_fetch_new(remote_source: RemoteSource, mocker: MockerFixture) -> None: head_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.head", return_value="sha") local = Path("local") - assert Sources.fetch(local, remote_source) == "sha" + assert sources.fetch(local, remote_source) == "sha" check_output_mock.assert_has_calls([ - MockCall("git", "clone", "--quiet", "--depth", "1", "--branch", remote_source.branch, "--single-branch", - remote_source.git_url, str(local), cwd=local.parent, logger=pytest.helpers.anyvar(int)), - MockCall("git", "checkout", "--force", remote_source.branch, cwd=local, logger=pytest.helpers.anyvar(int)), - MockCall("git", "reset", "--quiet", "--hard", f"origin/{remote_source.branch}", + MockCall(*sources.git(), "clone", "--quiet", "--depth", "1", "--branch", remote_source.branch, + "--single-branch", remote_source.git_url, str(local), + cwd=local.parent, logger=pytest.helpers.anyvar(int)), + MockCall(*sources.git(), "checkout", "--force", remote_source.branch, + cwd=local, logger=pytest.helpers.anyvar(int)), + MockCall(*sources.git(), "reset", "--quiet", "--hard", f"origin/{remote_source.branch}", cwd=local, logger=pytest.helpers.anyvar(int)) ]) move_mock.assert_called_once_with(local.resolve(), local) head_mock.assert_called_once_with(local) -def test_fetch_new_without_remote(mocker: MockerFixture) -> None: +def test_fetch_new_without_remote(sources: Sources, mocker: MockerFixture) -> None: """ must fetch nothing in case if no remote set """ @@ -129,10 +132,11 @@ def test_fetch_new_without_remote(mocker: MockerFixture) -> None: head_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.head", return_value="sha") local = Path("local") - assert Sources.fetch(local, RemoteSource(source=PackageSource.Archive)) == "sha" + assert sources.fetch(local, RemoteSource(source=PackageSource.Archive)) == "sha" check_output_mock.assert_has_calls([ - MockCall("git", "checkout", "--force", Sources.DEFAULT_BRANCH, cwd=local, logger=pytest.helpers.anyvar(int)), - MockCall("git", "reset", "--quiet", "--hard", f"origin/{Sources.DEFAULT_BRANCH}", + MockCall(*sources.git(), "checkout", "--force", sources.DEFAULT_BRANCH, + cwd=local, logger=pytest.helpers.anyvar(int)), + MockCall(*sources.git(), "reset", "--quiet", "--hard", f"origin/{sources.DEFAULT_BRANCH}", cwd=local, logger=pytest.helpers.anyvar(int)) ]) move_mock.assert_called_once_with(local.resolve(), local) @@ -153,15 +157,15 @@ def test_fetch_relative(remote_source: RemoteSource, mocker: MockerFixture) -> N head_mock.assert_called_once_with(local) -def test_has_remotes(mocker: MockerFixture) -> None: +def test_has_remotes(sources: Sources, mocker: MockerFixture) -> None: """ must ask for remotes """ check_output_mock = mocker.patch("ahriman.core.build_tools.sources.check_output", return_value="origin") local = Path("local") - assert Sources.has_remotes(local) - check_output_mock.assert_called_once_with("git", "remote", cwd=local, logger=pytest.helpers.anyvar(int)) + assert sources.has_remotes(local) + check_output_mock.assert_called_once_with(*sources.git(), "remote", cwd=local, logger=pytest.helpers.anyvar(int)) def test_has_remotes_empty(mocker: MockerFixture) -> None: @@ -172,7 +176,7 @@ def test_has_remotes_empty(mocker: MockerFixture) -> None: assert not Sources.has_remotes(Path("local")) -def test_init(mocker: MockerFixture) -> None: +def test_init(sources: Sources, mocker: MockerFixture) -> None: """ must create empty repository at the specified path """ @@ -183,9 +187,9 @@ def test_init(mocker: MockerFixture) -> None: commit_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.commit") local = Path("local") - Sources.init(local) - check_output_mock.assert_called_once_with("git", "init", "--quiet", "--initial-branch", Sources.DEFAULT_BRANCH, - cwd=local, logger=pytest.helpers.anyvar(int)) + sources.init(local) + check_output_mock.assert_called_once_with(*sources.git(), "init", "--quiet", "--initial-branch", + sources.DEFAULT_BRANCH, cwd=local, logger=pytest.helpers.anyvar(int)) add_mock.assert_called_once_with(local, "PKGBUILD", ".SRCINFO", "local") commit_mock.assert_called_once_with(local) @@ -267,7 +271,7 @@ def test_patch_create_with_newline(mocker: MockerFixture) -> None: assert Sources.patch_create(Path("local"), "glob").endswith("\n") -def test_push(package_ahriman: Package, mocker: MockerFixture) -> None: +def test_push(package_ahriman: Package, sources: Sources, mocker: MockerFixture) -> None: """ must correctly push files to remote repository """ @@ -277,11 +281,11 @@ def test_push(package_ahriman: Package, mocker: MockerFixture) -> None: commit_author = ("commit author", "user@host") local = Path("local") - Sources.push(local, package_ahriman.remote, "glob", commit_author=commit_author) + sources.push(local, package_ahriman.remote, "glob", commit_author=commit_author) add_mock.assert_called_once_with(local, "glob") commit_mock.assert_called_once_with(local, commit_author=commit_author) check_output_mock.assert_called_once_with( - "git", "push", "--quiet", package_ahriman.remote.git_url, package_ahriman.remote.branch, + *sources.git(), "push", "--quiet", package_ahriman.remote.git_url, package_ahriman.remote.branch, cwd=local, logger=pytest.helpers.anyvar(int)) @@ -308,7 +312,7 @@ def test_add(sources: Sources, mocker: MockerFixture) -> None: sources.add(local, "pattern1", "pattern2") glob_mock.assert_has_calls([MockCall("pattern1"), MockCall("pattern2")]) check_output_mock.assert_called_once_with( - "git", "add", "1", "2", "1", "2", cwd=local, logger=sources.logger + *sources.git(), "add", "1", "2", "1", "2", cwd=local, logger=sources.logger ) @@ -323,7 +327,7 @@ def test_add_intent_to_add(sources: Sources, mocker: MockerFixture) -> None: sources.add(local, "pattern1", "pattern2", intent_to_add=True) glob_mock.assert_has_calls([MockCall("pattern1"), MockCall("pattern2")]) check_output_mock.assert_called_once_with( - "git", "add", "--intent-to-add", "1", "2", "1", "2", cwd=local, logger=sources.logger + *sources.git(), "add", "--intent-to-add", "1", "2", "1", "2", cwd=local, logger=sources.logger ) @@ -350,13 +354,8 @@ def test_commit(sources: Sources, mocker: MockerFixture) -> None: user, email = sources.DEFAULT_COMMIT_AUTHOR assert sources.commit(local, message=message) check_output_mock.assert_called_once_with( - "git", "commit", "--quiet", "--message", message, - cwd=local, logger=sources.logger, environment={ - "GIT_AUTHOR_NAME": user, - "GIT_AUTHOR_EMAIL": email, - "GIT_COMMITTER_NAME": user, - "GIT_COMMITTER_EMAIL": email, - } + *sources.git(), "-c", f"user.email=\"{email}\"", "-c", f"user.name=\"{user}\"", + "commit", "--quiet", "--message", message, cwd=local, logger=sources.logger ) @@ -383,13 +382,8 @@ def test_commit_author(sources: Sources, mocker: MockerFixture) -> None: user, email = author = ("commit author", "user@host") assert sources.commit(Path("local"), message=message, commit_author=author) check_output_mock.assert_called_once_with( - "git", "commit", "--quiet", "--message", message, - cwd=local, logger=sources.logger, environment={ - "GIT_AUTHOR_NAME": user, - "GIT_AUTHOR_EMAIL": email, - "GIT_COMMITTER_NAME": user, - "GIT_COMMITTER_EMAIL": email, - } + *sources.git(), "-c", f"user.email=\"{email}\"", "-c", f"user.name=\"{user}\"", + "commit", "--quiet", "--message", message, cwd=local, logger=sources.logger ) @@ -404,13 +398,8 @@ def test_commit_autogenerated_message(sources: Sources, mocker: MockerFixture) - assert sources.commit(Path("local")) user, email = sources.DEFAULT_COMMIT_AUTHOR check_output_mock.assert_called_once_with( - "git", "commit", "--quiet", "--message", pytest.helpers.anyvar(str, strict=True), - cwd=local, logger=sources.logger, environment={ - "GIT_AUTHOR_NAME": user, - "GIT_AUTHOR_EMAIL": email, - "GIT_COMMITTER_NAME": user, - "GIT_COMMITTER_EMAIL": email, - } + *sources.git(), "-c", f"user.email=\"{email}\"", "-c", f"user.name=\"{user}\"", + "commit", "--quiet", "--message", pytest.helpers.anyvar(str, strict=True), cwd=local, logger=sources.logger ) @@ -422,7 +411,7 @@ def test_diff(sources: Sources, mocker: MockerFixture) -> None: local = Path("local") assert sources.diff(local) - check_output_mock.assert_called_once_with("git", "diff", cwd=local, logger=sources.logger) + check_output_mock.assert_called_once_with(*sources.git(), "diff", cwd=local, logger=sources.logger) def test_diff_specific(sources: Sources, mocker: MockerFixture) -> None: @@ -433,7 +422,7 @@ def test_diff_specific(sources: Sources, mocker: MockerFixture) -> None: local = Path("local") assert sources.diff(local, "hash") - check_output_mock.assert_called_once_with("git", "diff", "hash", cwd=local, logger=sources.logger) + check_output_mock.assert_called_once_with(*sources.git(), "diff", "hash", cwd=local, logger=sources.logger) def test_fetch_until(sources: Sources, mocker: MockerFixture) -> None: @@ -450,10 +439,12 @@ def test_fetch_until(sources: Sources, mocker: MockerFixture) -> None: local = Path("local") sources.fetch_until(local, branch="master", commit_sha="sha") check_output_mock.assert_has_calls([ - MockCall("git", "fetch", "--quiet", "--depth", "1", "origin", "master", cwd=local, logger=sources.logger), - MockCall("git", "cat-file", "-e", "sha", cwd=local, logger=sources.logger), - MockCall("git", "fetch", "--quiet", "--depth", "2", "origin", "master", cwd=local, logger=sources.logger), - MockCall("git", "cat-file", "-e", "sha", cwd=local, logger=sources.logger), + MockCall(*sources.git(), "fetch", "--quiet", "--depth", "1", "origin", "master", + cwd=local, logger=sources.logger), + MockCall(*sources.git(), "cat-file", "-e", "sha", cwd=local, logger=sources.logger), + MockCall(*sources.git(), "fetch", "--quiet", "--depth", "2", "origin", "master", + cwd=local, logger=sources.logger), + MockCall(*sources.git(), "cat-file", "-e", "sha", cwd=local, logger=sources.logger), ]) @@ -466,8 +457,9 @@ def test_fetch_until_first(sources: Sources, mocker: MockerFixture) -> None: local = Path("local") sources.fetch_until(local, branch="master") check_output_mock.assert_has_calls([ - MockCall("git", "fetch", "--quiet", "--depth", "1", "origin", "master", cwd=local, logger=sources.logger), - MockCall("git", "cat-file", "-e", "HEAD", cwd=local, logger=sources.logger), + MockCall(*sources.git(), "fetch", "--quiet", "--depth", "1", "origin", "master", + cwd=local, logger=sources.logger), + MockCall(*sources.git(), "cat-file", "-e", "HEAD", cwd=local, logger=sources.logger), ]) @@ -480,11 +472,27 @@ def test_fetch_until_all_branches(sources: Sources, mocker: MockerFixture) -> No local = Path("local") sources.fetch_until(local) check_output_mock.assert_has_calls([ - MockCall("git", "fetch", "--quiet", "--depth", "1", cwd=local, logger=sources.logger), - MockCall("git", "cat-file", "-e", "HEAD", cwd=local, logger=sources.logger), + MockCall(*sources.git(), "fetch", "--quiet", "--depth", "1", cwd=local, logger=sources.logger), + MockCall(*sources.git(), "cat-file", "-e", "HEAD", cwd=local, logger=sources.logger), ]) +def test_git(sources: Sources) -> None: + """ + must correctly generate git command + """ + assert sources.git() == ["git", "-c", "init.defaultBranch=\"master\""] + + +def test_git_overrides(sources: Sources) -> None: + """ + must correctly generate git command with additional settings + """ + assert sources.git({"user.email": "ahriman@localhost"}) == [ + "git", "-c", "init.defaultBranch=\"master\"", "-c", "user.email=\"ahriman@localhost\"" + ] + + def test_has_changes(sources: Sources, mocker: MockerFixture) -> None: """ must correctly identify if there are changes @@ -493,12 +501,12 @@ def test_has_changes(sources: Sources, mocker: MockerFixture) -> None: check_output_mock = mocker.patch("ahriman.core.build_tools.sources.check_output", return_value="M a.txt") assert sources.has_changes(local) - check_output_mock.assert_called_once_with("git", "diff", "--cached", "--name-only", + check_output_mock.assert_called_once_with(*sources.git(), "diff", "--cached", "--name-only", cwd=local, logger=sources.logger) check_output_mock = mocker.patch("ahriman.core.build_tools.sources.check_output", return_value="") assert not sources.has_changes(local) - check_output_mock.assert_called_once_with("git", "diff", "--cached", "--name-only", + check_output_mock.assert_called_once_with(*sources.git(), "diff", "--cached", "--name-only", cwd=local, logger=sources.logger) @@ -510,7 +518,7 @@ def test_head(sources: Sources, mocker: MockerFixture) -> None: local = Path("local") assert sources.head(local) == "sha" - check_output_mock.assert_called_once_with("git", "rev-parse", "HEAD", cwd=local, logger=sources.logger) + check_output_mock.assert_called_once_with(*sources.git(), "rev-parse", "HEAD", cwd=local, logger=sources.logger) def test_head_specific(sources: Sources, mocker: MockerFixture) -> None: @@ -521,7 +529,7 @@ def test_head_specific(sources: Sources, mocker: MockerFixture) -> None: local = Path("local") assert sources.head(local, "master") == "sha" - check_output_mock.assert_called_once_with("git", "rev-parse", "master", cwd=local, logger=sources.logger) + check_output_mock.assert_called_once_with(*sources.git(), "rev-parse", "master", cwd=local, logger=sources.logger) def test_move(sources: Sources, mocker: MockerFixture) -> None: @@ -554,7 +562,7 @@ def test_patch_apply(sources: Sources, mocker: MockerFixture) -> None: local = Path("local") sources.patch_apply(local, patch) check_output_mock.assert_called_once_with( - "git", "apply", "--ignore-space-change", "--ignore-whitespace", + *sources.git(), "apply", "--ignore-space-change", "--ignore-whitespace", cwd=local, input_data=patch.value, logger=sources.logger )