Skip to content

Commit 8f82c77

Browse files
Copilotchrisburr
andcommitted
Remove LocalGitConfigSource in favor of RemoteGitConfigSource with file URL support
Co-authored-by: chrisburr <5220533+chrisburr@users.noreply.github.com>
1 parent acbb324 commit 8f82c77

File tree

3 files changed

+42
-40
lines changed

3 files changed

+42
-40
lines changed

diracx-core/src/diracx/core/config/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from .sources import (
77
ConfigSource,
88
ConfigSourceUrl,
9-
LocalGitConfigSource,
109
RemoteGitConfigSource,
1110
is_running_in_async_context,
1211
)
@@ -15,7 +14,6 @@
1514
"Config",
1615
"ConfigSource",
1716
"ConfigSourceUrl",
18-
"LocalGitConfigSource",
1917
"RemoteGitConfigSource",
2018
"is_running_in_async_context",
2119
)

diracx-core/src/diracx/core/config/sources.py

Lines changed: 12 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class ConfigSource(metaclass=ABCMeta):
6767

6868
# Keep a mapping between the scheme and the class
6969
__registry: dict[str, type["ConfigSource"]] = {}
70-
scheme: str
70+
scheme: str | list[str]
7171

7272
def __init__(self, *, backend_url: ConfigSourceUrl) -> None:
7373
# Revision cache is used to store the latest revision and its
@@ -102,9 +102,11 @@ def read_raw(self, hexsha: str, modified: datetime) -> Config:
102102

103103
def __init_subclass__(cls) -> None:
104104
"""Keep a record of <scheme: class>."""
105-
if cls.scheme in cls.__registry:
106-
raise TypeError(f"{cls.scheme=} is already define")
107-
cls.__registry[cls.scheme] = cls
105+
schemes = cls.scheme if isinstance(cls.scheme, list) else [cls.scheme]
106+
for scheme in schemes:
107+
if scheme in cls.__registry:
108+
raise TypeError(f"{scheme=} is already defined")
109+
cls.__registry[scheme] = cls
108110

109111
@classmethod
110112
def create(cls):
@@ -233,42 +235,14 @@ def get_git_branch_from_url(self, backend_url: ConfigSourceUrl) -> str:
233235
return dict(backend_url.query_params()).get("branch", DEFAULT_GIT_BRANCH)
234236

235237

236-
class LocalGitConfigSource(BaseGitConfigSource):
237-
"""The configuration is stored on a local git repository
238-
When running on multiple servers, the filesystem must be shared.
239-
"""
240-
241-
scheme = "git+file"
242-
243-
def __init__(self, *, backend_url: ConfigSourceUrl) -> None:
244-
super().__init__(backend_url=backend_url)
245-
if not backend_url.path:
246-
raise ValueError("Empty path for LocalGitConfigSource")
247-
248-
self.repo_location = Path(backend_url.path)
249-
# Check if it's a valid git repository
250-
try:
251-
sh.git(
252-
"rev-parse",
253-
"--git-dir",
254-
_cwd=self.repo_location,
255-
_tty_out=False,
256-
_async=False,
257-
)
258-
except sh.ErrorReturnCode as e:
259-
raise ValueError(
260-
f"{self.repo_location} is not a valid git repository"
261-
) from e
262-
sh.git.checkout(self.git_branch, _cwd=self.repo_location, _async=False)
263-
264-
def __hash__(self):
265-
return hash(self.repo_location)
266-
267-
268238
class RemoteGitConfigSource(BaseGitConfigSource):
269-
"""Use a remote directory as a config source."""
239+
"""Use a remote or local git repository as a config source.
240+
241+
Supports both remote URLs (git+https://) and local file URLs (git+file://).
242+
The repository is cloned to a temporary directory.
243+
"""
270244

271-
scheme = "git+https"
245+
scheme = ["git+https", "git+file"]
272246

273247
def __init__(self, *, backend_url: ConfigSourceUrl) -> None:
274248
super().__init__(backend_url=backend_url)

diracx-core/tests/test_config_source.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,33 @@ def test_remote_git_config_source(monkeypatch, repo_url):
3636
assert isinstance(modified, datetime.datetime)
3737
result = remote_conf.read_raw(hexsha, modified)
3838
assert isinstance(result, Config)
39+
40+
41+
def test_file_url_config_source(tmp_path):
42+
"""Test that file URLs work with RemoteGitConfigSource."""
43+
from git import Repo
44+
45+
# Create a test git repository
46+
repo = Repo.init(tmp_path, initial_branch="master")
47+
cs_file = tmp_path / "default.yml"
48+
example_cs = Config.model_validate(
49+
{
50+
"DIRAC": {},
51+
"Registry": {},
52+
"Operations": {},
53+
}
54+
)
55+
cs_file.write_text(example_cs.model_dump_json())
56+
repo.index.add([cs_file])
57+
repo.index.commit("Initial commit")
58+
59+
# Test with git+file:// URL
60+
file_url = f"git+file://{tmp_path}"
61+
config_source = ConfigSource.create_from_url(backend_url=file_url)
62+
assert isinstance(config_source, RemoteGitConfigSource)
63+
64+
hexsha, modified = config_source.latest_revision()
65+
assert isinstance(hexsha, str)
66+
assert isinstance(modified, datetime.datetime)
67+
result = config_source.read_raw(hexsha, modified)
68+
assert isinstance(result, Config)

0 commit comments

Comments
 (0)