Skip to content

Commit 7ce28cd

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

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

dvc/repo/__init__.py

Lines changed: 11 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:
@@ -350,6 +351,16 @@ def fs(self, fs: "FileSystem"):
350351
# fs.
351352
self._reset()
352353

354+
@property
355+
def subrepo_relpath(self) -> str:
356+
from dvc.fs import GitFileSystem
357+
358+
scm_root_dir = "/" if isinstance(self.fs, GitFileSystem) else self.scm.root_dir
359+
360+
relpath = as_posix(self.fs.relpath(self.root_dir, scm_root_dir))
361+
362+
return "" if relpath == "." else relpath
363+
353364
@property
354365
def data_index(self) -> "DataIndex":
355366
from dvc_data.index import DataIndex

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.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.subrepo_relpath == "project_a"
153+
154+
monorepo_project_b = Repo.init(tmp_dir / "subdir" / "project_b", subdir=True)
155+
156+
assert monorepo_project_b.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.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.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.subrepo_relpath == "subdir/project_b"

0 commit comments

Comments
 (0)