Skip to content

Commit 989aa2d

Browse files
authored
custom check for subrepo (#950)
1 parent b211ea4 commit 989aa2d

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

tests/integration/test_nested_repo.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,37 @@ def test_subrepo(proj_path):
6262
assert node_loaded.outs == {"param1": 3, "param2": 4}
6363

6464

65+
def test_from_rev_in_subrepo(proj_path):
66+
"""Test loading a node with from_rev when cwd is inside a subrepo.
67+
68+
This tests the scenario where:
69+
1. The DVC repo root is at the parent directory
70+
2. The project is in a subdirectory
71+
3. The user is inside that subdirectory
72+
4. The user calls zntrack.from_rev("NodeName") without specifying a path
73+
74+
This should work because the zntrack.json and other files are in the
75+
current directory. The path should NOT be duplicated.
76+
"""
77+
directory = pathlib.Path("subrepo")
78+
directory.mkdir(parents=True, exist_ok=True)
79+
os.chdir(directory)
80+
81+
project = zntrack.Project()
82+
with project:
83+
_ = zntrack.examples.ParamsToOuts(
84+
params={"param1": 1, "param2": 2},
85+
)
86+
project.repro()
87+
88+
# Now we're inside the subdirectory and want to load the node
89+
# This should work - we shouldn't need to specify the path since
90+
# zntrack.json is in the current directory
91+
node_loaded = zntrack.from_rev("ParamsToOuts")
92+
assert node_loaded.params == {"param1": 1, "param2": 2}
93+
assert node_loaded.outs == {"param1": 1, "param2": 2}
94+
95+
6596
def test_subrepo_external_node(proj_path):
6697
"""Test subrepo functionality with external dataclasses."""
6798
# Create external node module file that can be imported

zntrack/from_rev.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,25 @@ def from_rev(
7676
# DVC Issue where stage.path is relative to the DVC root
7777
# if rev is given, if only remote is given, it is relative to file system
7878
# so we need to use path_in_repo instead.
79+
80+
# When using local filesystem (no remote/rev), check if the current working
81+
# directory is already inside the stage's path. If so, use an empty path
82+
# to avoid path duplication issues.
83+
if remote is None and rev is None and fs.repo is not None:
84+
repo_root = pathlib.Path(fs.repo.root_dir).resolve()
85+
cwd = pathlib.Path.cwd().resolve()
86+
try:
87+
cwd_relative = cwd.relative_to(repo_root)
88+
# If cwd is at or inside the stage's path, adjust accordingly
89+
if cwd_relative == path or str(cwd_relative).startswith(str(path) + "/"):
90+
# We're inside the stage directory, use empty path
91+
path = pathlib.Path()
92+
elif str(path).startswith(str(cwd_relative) + "/"):
93+
# Stage is inside cwd, use relative path from cwd
94+
path = pathlib.Path(str(path)[len(str(cwd_relative)) + 1 :])
95+
except ValueError:
96+
# cwd is not inside repo_root, keep the path as-is
97+
pass
7998
except AttributeError:
8099
raise ValueError("Stage is not a ZnTrack pipeline stage.")
81100

0 commit comments

Comments
 (0)