Skip to content

Commit 5d28576

Browse files
authored
Resolves #130: Replace GitPython with dulwich (#218)
* resolves #130: Replace GitPython with dulwich * Remove debugging * Add better testing for initializing git repos * Refactor RepoManager * Add integration test for dulwich * Add minimum version for dulwich * Fix linting for exception match * Add debug for ci * Move asserts so it fails early * Add debugging for integration test * Return docker compose config in CI * Add more debugs for files * Run command on docker host * Get container logs * Comment out integration test for git repo * Remove print
1 parent f883e36 commit 5d28576

File tree

14 files changed

+250
-73
lines changed

14 files changed

+250
-73
lines changed

changelog/130.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Replace GitPython with dulwich

infrahub_sdk/checks.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
from typing import TYPE_CHECKING, Any
99

1010
import ujson
11-
from git.repo import Repo
1211
from pydantic import BaseModel, Field
1312

13+
from infrahub_sdk.repository import GitRepoManager
14+
1415
from .exceptions import UninitializedError
1516

1617
if TYPE_CHECKING:
@@ -43,7 +44,7 @@ def __init__(
4344
params: dict | None = None,
4445
client: InfrahubClient | None = None,
4546
):
46-
self.git: Repo | None = None
47+
self.git: GitRepoManager | None = None
4748
self.initializer = initializer or InfrahubCheckInitializer()
4849

4950
self.logs: list[dict[str, Any]] = []
@@ -137,10 +138,9 @@ def branch_name(self) -> str:
137138
return self.branch
138139

139140
if not self.git:
140-
self.git = Repo(self.root_directory)
141+
self.git = GitRepoManager(self.root_directory)
141142

142143
self.branch = str(self.git.active_branch)
143-
144144
return self.branch
145145

146146
@abstractmethod

infrahub_sdk/generator.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from abc import abstractmethod
55
from typing import TYPE_CHECKING
66

7-
from git.repo import Repo
7+
from infrahub_sdk.repository import GitRepoManager
88

99
from .exceptions import UninitializedError
1010

@@ -30,7 +30,7 @@ def __init__(
3030
) -> None:
3131
self.query = query
3232
self.branch = branch
33-
self.git: Repo | None = None
33+
self.git: GitRepoManager | None = None
3434
self.params = params or {}
3535
self.root_directory = root_directory or os.getcwd()
3636
self.generator_instance = generator_instance
@@ -81,7 +81,7 @@ def branch_name(self) -> str:
8181
return self.branch
8282

8383
if not self.git:
84-
self.git = Repo(self.root_directory)
84+
self.git = GitRepoManager(self.root_directory)
8585

8686
self.branch = str(self.git.active_branch)
8787

infrahub_sdk/pytest_plugin/items/base.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import pytest
88
import ujson
9-
from git.exc import InvalidGitRepositoryError
109

1110
from ..exceptions import InvalidResourceConfigError
1211
from ..models import InfrahubInputOutputTest
@@ -28,7 +27,6 @@ def __init__(
2827
**kwargs: dict[str, Any],
2928
):
3029
super().__init__(*args, **kwargs) # type: ignore[arg-type]
31-
3230
self.resource_name: str = resource_name
3331
self.resource_config: InfrahubRepositoryConfigElement = resource_config
3432
self.test: InfrahubTest = test
@@ -68,9 +66,6 @@ def runtest(self) -> None:
6866
"""Run the test logic."""
6967

7068
def repr_failure(self, excinfo: pytest.ExceptionInfo, style: str | None = None) -> str: # noqa: ARG002
71-
if isinstance(excinfo.value, InvalidGitRepositoryError):
72-
return f"Invalid Git repository at {excinfo.value}"
73-
7469
return str(excinfo.value)
7570

7671
def reportinfo(self) -> tuple[Path | str, int | None, str]:

infrahub_sdk/repository.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from __future__ import annotations
2+
3+
from pathlib import Path
4+
5+
from dulwich import porcelain
6+
from dulwich.repo import Repo
7+
8+
9+
class GitRepoManager:
10+
def __init__(self, root_directory: str, branch: str = "main"):
11+
self.root_directory = root_directory
12+
self.branch = branch
13+
self.git: Repo = self.initialize_repo()
14+
15+
def initialize_repo(self) -> Repo:
16+
# Check if the directory already has a repository
17+
18+
root_path = Path(self.root_directory)
19+
20+
if root_path.exists() and (root_path / ".git").is_dir():
21+
repo = Repo(self.root_directory) # Open existing repo
22+
else:
23+
repo = Repo.init(self.root_directory, default_branch=self.branch.encode("utf-8"))
24+
25+
if not repo:
26+
raise ValueError("Failed to initialize or open a repository.")
27+
28+
return repo
29+
30+
@property
31+
def active_branch(self) -> str | None:
32+
active_branch = porcelain.active_branch(self.root_directory).decode("utf-8")
33+
return active_branch

infrahub_sdk/testing/repository.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
from pathlib import Path
88
from typing import TYPE_CHECKING
99

10-
from git.repo import Repo
10+
from dulwich import porcelain
1111

1212
from infrahub_sdk.graphql import Mutation
1313
from infrahub_sdk.protocols import CoreGenericRepository
14+
from infrahub_sdk.repository import GitRepoManager
1415

1516
if TYPE_CHECKING:
1617
from infrahub_sdk import InfrahubClient
@@ -37,14 +38,14 @@ class GitRepo:
3738

3839
type: GitRepoType = GitRepoType.INTEGRATED
3940

40-
_repo: Repo | None = None
41+
_repo: GitRepoManager | None = None
4142
initial_branch: str = "main"
4243
directories_to_ignore: list[str] = field(default_factory=list)
4344
remote_directory_name: str = "/remote"
4445
_branches: list[str] = field(default_factory=list)
4546

4647
@property
47-
def repo(self) -> Repo:
48+
def repo(self) -> GitRepoManager:
4849
if self._repo:
4950
return self._repo
5051
raise ValueError("Repo hasn't been initialized yet")
@@ -62,12 +63,17 @@ def init(self) -> None:
6263
dst=self.dst_directory / self.name,
6364
ignore=shutil.ignore_patterns(".git"),
6465
)
65-
self._repo = Repo.init(self.dst_directory / self.name, initial_branch=self.initial_branch)
66-
for untracked in self.repo.untracked_files:
67-
self.repo.index.add(untracked)
68-
self.repo.index.commit("First commit")
6966

70-
self.repo.git.checkout(self.initial_branch)
67+
self._repo = GitRepoManager(str(Path(self.dst_directory / self.name)), branch=self.initial_branch)
68+
69+
files = list(
70+
porcelain.get_untracked_paths(self._repo.git.path, self._repo.git.path, self._repo.git.open_index())
71+
)
72+
files_to_add = [str(Path(self._repo.git.path) / t) for t in files]
73+
if files_to_add:
74+
porcelain.add(repo=self._repo.git.path, paths=files_to_add)
75+
porcelain.commit(repo=self._repo.git.path, message="First commit")
76+
porcelain.checkout_branch(self._repo.git, self.initial_branch.encode("utf-8"))
7177

7278
async def add_to_infrahub(self, client: InfrahubClient, branch: str | None = None) -> dict:
7379
input_data = {

infrahub_sdk/transforms.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from abc import abstractmethod
66
from typing import TYPE_CHECKING, Any
77

8-
from git import Repo
8+
from infrahub_sdk.repository import GitRepoManager
99

1010
from .exceptions import UninitializedError
1111

@@ -27,7 +27,7 @@ def __init__(
2727
server_url: str = "",
2828
client: InfrahubClient | None = None,
2929
):
30-
self.git: Repo
30+
self.git: GitRepoManager
3131

3232
self.branch = branch
3333
self.server_url = server_url or os.environ.get("INFRAHUB_URL", "http://127.0.0.1:8000")
@@ -56,7 +56,7 @@ def branch_name(self) -> str:
5656
return self.branch
5757

5858
if not hasattr(self, "git") or not self.git:
59-
self.git = Repo(self.root_directory)
59+
self.git = GitRepoManager(self.root_directory)
6060

6161
self.branch = str(self.git.active_branch)
6262

infrahub_sdk/utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@
99

1010
import httpx
1111
import ujson
12-
from git.repo import Repo
1312
from graphql import (
1413
FieldNode,
1514
InlineFragmentNode,
1615
SelectionSetNode,
1716
)
1817

18+
from infrahub_sdk.repository import GitRepoManager
19+
1920
from .exceptions import JsonDecodeError
2021

2122
if TYPE_CHECKING:
@@ -246,7 +247,7 @@ def get_branch(branch: str | None = None, directory: str | Path = ".") -> str:
246247
if branch:
247248
return branch
248249

249-
repo = Repo(directory)
250+
repo = GitRepoManager(directory)
250251
return str(repo.active_branch)
251252

252253

0 commit comments

Comments
 (0)