Skip to content

Commit 7c5c1c7

Browse files
committed
repo: add get_subrepo_relpath helper for studio live experiments monorepo support
1 parent 79238fd commit 7c5c1c7

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

dvc/repo/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
)
1414
from dvc.ignore import DvcIgnoreFilter
1515
from dvc.log import logger
16+
from dvc.utils import as_posix
1617
from dvc.utils.objects import cached_property
1718

1819
if TYPE_CHECKING:
@@ -339,6 +340,15 @@ def experiments(self) -> "Experiments":
339340

340341
return Experiments(self)
341342

343+
def get_subrepo_relpath(self) -> str:
344+
from dvc.fs import GitFileSystem
345+
346+
scm_root_dir = "/" if isinstance(self.fs, GitFileSystem) else self.scm.root_dir
347+
348+
relpath = as_posix(self.fs.relpath(self.root_dir, scm_root_dir))
349+
350+
return "" if relpath == "." else relpath
351+
342352
@property
343353
def fs(self) -> "FileSystem":
344354
return self._fs

tests/unit/repo/test_repo.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,51 @@ def test_dynamic_cache_initialization(tmp_dir, scm):
135135
dvc.close()
136136

137137
Repo(str(tmp_dir)).close()
138+
139+
140+
def test_monorepo_relpath(tmp_dir, scm):
141+
from dvc.repo.destroy import destroy
142+
143+
tmp_dir.gen({"project_a": {}, "subdir/project_b": {}})
144+
145+
non_monorepo = Repo.init(tmp_dir)
146+
assert non_monorepo.get_subrepo_relpath() == ""
147+
148+
destroy(non_monorepo)
149+
150+
monorepo_project_a = Repo.init(tmp_dir / "project_a", subdir=True)
151+
152+
assert monorepo_project_a.get_subrepo_relpath() == "project_a"
153+
154+
monorepo_project_b = Repo.init(tmp_dir / "subdir" / "project_b", subdir=True)
155+
156+
assert monorepo_project_b.get_subrepo_relpath() == "subdir/project_b"
157+
158+
159+
def test_virtual_monorepo_relpath(tmp_dir, scm):
160+
from dvc.fs.git import GitFileSystem
161+
from dvc.repo.destroy import destroy
162+
163+
tmp_dir.gen({"project_a": {}, "subdir/project_b": {}})
164+
scm.commit("initial commit")
165+
gfs = GitFileSystem(scm=scm, rev="master")
166+
167+
non_monorepo = Repo.init(tmp_dir)
168+
non_monorepo.fs = gfs
169+
non_monorepo.root_dir = "/"
170+
171+
assert non_monorepo.get_subrepo_relpath() == ""
172+
173+
destroy(non_monorepo)
174+
175+
monorepo_project_a = Repo.init(tmp_dir / "project_a", subdir=True)
176+
monorepo_project_a.fs = gfs
177+
monorepo_project_a.root_dir = "/project_a"
178+
179+
assert monorepo_project_a.get_subrepo_relpath() == "project_a"
180+
181+
monorepo_project_b = Repo.init(tmp_dir / "subdir" / "project_b", subdir=True)
182+
monorepo_project_b.fs = gfs
183+
monorepo_project_b.root_dir = "/subdir/project_b"
184+
185+
assert monorepo_project_b.get_subrepo_relpath() == "subdir/project_b"

0 commit comments

Comments
 (0)