Skip to content

Commit 7a8344f

Browse files
committed
update: git/docker version
1 parent f5149c8 commit 7a8344f

2 files changed

Lines changed: 73 additions & 7 deletions

File tree

colrev/ops/commit.py

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44
from __future__ import annotations
55

66
import importlib
7-
import os
7+
import shutil
88
import sys
99
import typing
1010
from importlib.metadata import version
1111
from pathlib import Path
1212

1313
import git
1414
import gitdb.exc
15+
from docker import errors as docker_errors
16+
from docker import from_env as docker_from_env
1517

1618
import colrev.env.environment_manager
1719
import colrev.env.utils
@@ -86,12 +88,37 @@ def _set_versions(self) -> None:
8688
self.colrev_version = f'version {version("colrev")}'
8789
sys_v = sys.version
8890
self.python_version = f'version {sys_v[: sys_v.find(" ")]}'
89-
stream = os.popen("git --version")
90-
self.git_version = stream.read().replace("git ", "").replace("\n", "")
91-
stream = os.popen("docker --version")
92-
self.docker_version = stream.read().replace("Docker ", "").replace("\n", "")
93-
if self.docker_version == "": # pragma: no cover
94-
self.docker_version = "Not installed"
91+
self.git_version = self._get_git_version()
92+
self.docker_version = self._get_docker_version()
93+
94+
def _get_git_version(self) -> str:
95+
git_executable = shutil.which("git")
96+
if git_executable is None:
97+
return "Not installed"
98+
99+
try:
100+
# Use the resolved absolute executable path to avoid partial-path execution.
101+
git.refresh(path=git_executable)
102+
version_info = git.cmd.Git().version_info
103+
return "version " + ".".join(map(str, version_info))
104+
except (git.exc.GitError, TypeError, ValueError):
105+
return "Not installed"
106+
107+
def _get_docker_version(self) -> str:
108+
# This validates Docker daemon availability/version through the Docker SDK,
109+
# not just whether the docker CLI binary exists on PATH.
110+
client = None
111+
try:
112+
client = docker_from_env()
113+
docker_version = client.version().get("Version", "")
114+
if docker_version == "": # pragma: no cover
115+
return "Not installed"
116+
return f"version {docker_version}"
117+
except docker_errors.DockerException:
118+
return "Not installed"
119+
finally:
120+
if client is not None:
121+
client.close()
95122

96123
def _set_script_information(self, script_name: str) -> None:
97124
self.ext_script_name = ""

tests/review_manager/2_ops/commit_test.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#!/usr/bin/env python
22
"""Tests of the CoLRev commit operation"""
33

4+
import git
45
import pytest
6+
from docker import errors as docker_errors
57

68
import colrev.exceptions as colrev_exceptions
79
import colrev.ops.check
@@ -61,3 +63,40 @@ def patched_has_record_changes() -> bool:
6163
commit_fixture.review_manager.force_mode = False
6264
commit_fixture.review_manager.force_mode = True
6365
commit_fixture.create()
66+
67+
68+
def test_get_git_version_success(commit_fixture, mocker): # type: ignore
69+
mocker.patch("colrev.ops.commit.shutil.which", return_value="/usr/bin/git")
70+
mocker.patch("colrev.ops.commit.git.refresh")
71+
mocker.patch(
72+
"colrev.ops.commit.git.cmd.Git.version_info",
73+
new_callable=mocker.PropertyMock,
74+
return_value=(2, 44, 0),
75+
)
76+
77+
assert commit_fixture._get_git_version() == "version 2.44.0"
78+
79+
80+
def test_get_git_version_failure(commit_fixture, mocker): # type: ignore
81+
mocker.patch("colrev.ops.commit.shutil.which", return_value="/usr/bin/git")
82+
mocker.patch("colrev.ops.commit.git.refresh", side_effect=git.exc.GitError("err"))
83+
84+
assert commit_fixture._get_git_version() == "Not installed"
85+
86+
87+
def test_get_docker_version_success(commit_fixture, mocker): # type: ignore
88+
docker_client = mocker.MagicMock()
89+
docker_client.version.return_value = {"Version": "27.1.0"}
90+
mocker.patch("colrev.ops.commit.docker_from_env", return_value=docker_client)
91+
92+
assert commit_fixture._get_docker_version() == "version 27.1.0"
93+
docker_client.close.assert_called_once()
94+
95+
96+
def test_get_docker_version_failure(commit_fixture, mocker): # type: ignore
97+
mocker.patch(
98+
"colrev.ops.commit.docker_from_env",
99+
side_effect=docker_errors.DockerException("unavailable"),
100+
)
101+
102+
assert commit_fixture._get_docker_version() == "Not installed"

0 commit comments

Comments
 (0)