mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-02 07:18:25 +01:00
dvc: don't use realpath where not needed
This commit is contained in:
+1
-1
@@ -103,7 +103,7 @@ class Config(dict):
|
||||
self.fs = fs or self.wfs
|
||||
|
||||
if dvc_dir:
|
||||
self.dvc_dir = self.fs.path.abspath(self.fs.path.realpath(dvc_dir))
|
||||
self.dvc_dir = self.fs.path.abspath(dvc_dir)
|
||||
|
||||
self.load(
|
||||
validate=validate, config=config, remote=remote, remote_config=remote_config
|
||||
|
||||
@@ -71,6 +71,10 @@ class OutputNotFoundError(DvcException):
|
||||
)
|
||||
|
||||
|
||||
class StageNotFoundError(DvcException):
|
||||
pass
|
||||
|
||||
|
||||
class StagePathAsOutputError(DvcException):
|
||||
"""Thrown if directory that stage is going to be saved in is specified as
|
||||
an output of another stage.
|
||||
|
||||
@@ -421,7 +421,7 @@ class Repo:
|
||||
|
||||
fs = fs or localfs
|
||||
root = root or os.curdir
|
||||
root_dir = fs.path.realpath(root)
|
||||
root_dir = fs.path.abspath(root)
|
||||
|
||||
if not fs.isdir(root_dir):
|
||||
raise NotDvcRepoError(f"directory '{root}' does not exist")
|
||||
|
||||
@@ -607,7 +607,7 @@ class BaseExecutor(ABC):
|
||||
old_cwd = os.getcwd()
|
||||
|
||||
for path in copy_paths or []:
|
||||
cls._copy_path(os.path.realpath(path), os.path.join(dvc.root_dir, path))
|
||||
cls._copy_path(os.path.abspath(path), os.path.join(dvc.root_dir, path))
|
||||
|
||||
if info.wdir:
|
||||
os.chdir(os.path.join(dvc.scm.root_dir, info.wdir))
|
||||
|
||||
@@ -31,6 +31,9 @@ def check_acyclic(graph: "DiGraph") -> None:
|
||||
|
||||
def get_pipeline(pipelines, node):
|
||||
found = [i for i in pipelines if i.has_node(node)]
|
||||
if not found:
|
||||
return None
|
||||
|
||||
assert len(found) == 1
|
||||
return found[0]
|
||||
|
||||
@@ -60,6 +63,9 @@ def collect_pipeline(stage: "Stage", graph: "DiGraph") -> Iterator["Stage"]:
|
||||
import networkx as nx
|
||||
|
||||
pipeline = get_pipeline(get_pipelines(graph), stage)
|
||||
if not pipeline:
|
||||
return iter([])
|
||||
|
||||
return nx.dfs_postorder_nodes(pipeline, stage)
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ def init(root_dir=os.curdir, no_scm=False, force=False, subdir=False): # noqa:
|
||||
"Cannot initialize repo with `--no-scm` and `--subdir`"
|
||||
)
|
||||
|
||||
root_dir = os.path.realpath(root_dir)
|
||||
root_dir = os.path.abspath(root_dir)
|
||||
dvc_dir = os.path.join(root_dir, Repo.DVC_DIR)
|
||||
|
||||
try:
|
||||
|
||||
+10
-2
@@ -37,11 +37,19 @@ StageSet = Set["Stage"]
|
||||
|
||||
|
||||
def _collect_with_deps(stages: StageList, graph: "DiGraph") -> StageSet:
|
||||
from dvc.exceptions import StageNotFoundError
|
||||
from dvc.repo.graph import collect_pipeline
|
||||
|
||||
res: StageSet = set()
|
||||
for stage in stages:
|
||||
res.update(collect_pipeline(stage, graph=graph))
|
||||
pl = list(collect_pipeline(stage, graph=graph))
|
||||
if not pl:
|
||||
raise StageNotFoundError(
|
||||
f"Stage {stage} is not found in the project. "
|
||||
"Check that there are no symlinks in the parents "
|
||||
"leading up to it within the project."
|
||||
)
|
||||
res.update(pl)
|
||||
return res
|
||||
|
||||
|
||||
@@ -211,7 +219,7 @@ class StageLoad:
|
||||
self, path: Optional[str] = None, name: Optional[str] = None
|
||||
) -> str:
|
||||
if path:
|
||||
return self.repo.fs.path.realpath(path)
|
||||
return self.repo.fs.path.abspath(path)
|
||||
|
||||
path = PROJECT_FILE
|
||||
logger.debug("Assuming '%s' to be a stage inside '%s'", name, path)
|
||||
|
||||
+2
-2
@@ -32,14 +32,14 @@ def check_stage_path(repo, path, is_wdir=False):
|
||||
wdir_or_path="stage working dir" if is_wdir else "file path", path=path
|
||||
)
|
||||
|
||||
real_path = os.path.realpath(path)
|
||||
real_path = os.path.abspath(path)
|
||||
if not os.path.exists(real_path):
|
||||
raise StagePathNotFoundError(error_msg.format("does not exist"))
|
||||
|
||||
if not os.path.isdir(real_path):
|
||||
raise StagePathNotDirectoryError(error_msg.format("is not directory"))
|
||||
|
||||
proj_dir = os.path.realpath(repo.root_dir)
|
||||
proj_dir = os.path.abspath(repo.root_dir)
|
||||
if real_path != proj_dir and not path_isin(real_path, proj_dir):
|
||||
raise StagePathOutsideError(error_msg.format("is outside of DVC repo"))
|
||||
|
||||
|
||||
+3
-13
@@ -218,23 +218,13 @@ def _visual_center(line, width):
|
||||
|
||||
|
||||
def relpath(path, start=os.curdir):
|
||||
path = os.fspath(path)
|
||||
path = os.path.abspath(os.fspath(path))
|
||||
start = os.path.abspath(os.fspath(start))
|
||||
|
||||
# Windows path on different drive than curdir doesn't have relpath
|
||||
if os.name == "nt":
|
||||
# Since python 3.8 os.realpath resolves network shares to their UNC
|
||||
# path. So, to be certain that relative paths correctly captured,
|
||||
# we need to resolve to UNC path first. We resolve only the drive
|
||||
# name so that we don't follow any 'real' symlinks on the path
|
||||
def resolve_network_drive_windows(path_to_resolve):
|
||||
drive, tail = os.path.splitdrive(path_to_resolve)
|
||||
return os.path.join(os.path.realpath(drive), tail)
|
||||
if os.name == "nt" and not os.path.commonprefix([start, path]):
|
||||
return path
|
||||
|
||||
path = resolve_network_drive_windows(os.path.abspath(path))
|
||||
start = resolve_network_drive_windows(start)
|
||||
if not os.path.commonprefix([start, path]):
|
||||
return path
|
||||
return os.path.relpath(path, start)
|
||||
|
||||
|
||||
|
||||
@@ -230,17 +230,31 @@ def test_parent_repo_collect_stages(tmp_dir, scm, dvc):
|
||||
|
||||
@pytest.mark.parametrize("with_deps", (False, True))
|
||||
def test_collect_symlink(tmp_dir, dvc, with_deps):
|
||||
from dvc.exceptions import StageNotFoundError
|
||||
|
||||
tmp_dir.gen({"data": {"foo": "foo contents"}})
|
||||
foo_path = os.path.join("data", "foo")
|
||||
dvc.add(foo_path)
|
||||
|
||||
data_link = tmp_dir / "data_link"
|
||||
data_link.symlink_to("data")
|
||||
stage = list(
|
||||
dvc.stage.collect(target=str(data_link / "foo.dvc"), with_deps=with_deps)
|
||||
)[0]
|
||||
|
||||
assert stage.addressing == f"{foo_path}.dvc"
|
||||
if with_deps:
|
||||
# NOTE: with_deps means that we'll need to collect and use dvcfiles in the repo
|
||||
# and we currently don't follow symlinks when collecting those, so it will not
|
||||
# be able to find the target stage.
|
||||
with pytest.raises(StageNotFoundError):
|
||||
dvc.stage.collect(target=str(data_link / "foo.dvc"), with_deps=with_deps)
|
||||
else:
|
||||
stage = list(
|
||||
dvc.stage.collect(target=str(data_link / "foo.dvc"), with_deps=with_deps)
|
||||
)[0]
|
||||
|
||||
assert stage.addressing == os.path.join("data_link", "foo.dvc")
|
||||
|
||||
stage = list(dvc.stage.collect(target=f"{foo_path}.dvc", with_deps=with_deps))[0]
|
||||
|
||||
assert stage.addressing == os.path.join("data", "foo.dvc")
|
||||
|
||||
|
||||
def test_stage_strings_representation(tmp_dir, dvc, run_copy):
|
||||
|
||||
@@ -40,19 +40,8 @@ def test_fix_env_pyenv(path, orig):
|
||||
|
||||
|
||||
@pytest.mark.skipif(os.name != "nt", reason="Windows specific")
|
||||
def test_relpath_windows(monkeypatch):
|
||||
"""test that relpath correctly generated when run on a
|
||||
windows network share. The drive mapped path is mapped
|
||||
to a UNC path by os.path.realpath"""
|
||||
|
||||
def dummy_realpath(path):
|
||||
return path.replace("x:", "\\\\server\\share")
|
||||
|
||||
monkeypatch.setattr(os.path, "realpath", dummy_realpath)
|
||||
assert (
|
||||
relpath("x:\\dir1\\dir2\\file.txt", "\\\\server\\share\\dir1")
|
||||
== "dir2\\file.txt"
|
||||
)
|
||||
def test_relpath_windows():
|
||||
assert relpath("x:\\dir1\\dir2\\file.txt", "x:\\dir1") == "dir2\\file.txt"
|
||||
|
||||
assert (
|
||||
relpath("y:\\dir1\\dir2\\file.txt", "\\\\server\\share\\dir1")
|
||||
|
||||
Reference in New Issue
Block a user