mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-01 23:08:43 +01:00
fix dvc.yaml filepath in error message when reading from git revisions (#10847)
This commit is contained in:
+24
-14
@@ -20,6 +20,7 @@ from dvc.utils.serialize import (
|
||||
parse_yaml,
|
||||
parse_yaml_for_update,
|
||||
)
|
||||
from dvc_objects.fs.local import LocalFileSystem
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from rich.syntax import Syntax
|
||||
@@ -34,15 +35,24 @@ _T = TypeVar("_T")
|
||||
merge_conflict_marker = re.compile("^([<=>]{7}) .*$", re.MULTILINE)
|
||||
|
||||
|
||||
def make_relpath(path: str) -> str:
|
||||
import os
|
||||
def make_relpath(fs_path: str, fs: "Optional[FileSystem]" = None) -> str:
|
||||
from os import curdir, pardir, sep
|
||||
|
||||
from dvc.utils import relpath
|
||||
|
||||
rel = relpath(path)
|
||||
prefix = ""
|
||||
if not rel.startswith(".."):
|
||||
prefix = "./" if os.name == "posix" else ".\\"
|
||||
if not fs_path:
|
||||
return fs_path
|
||||
|
||||
if fs and not isinstance(fs, LocalFileSystem):
|
||||
rel = fs.relpath(fs_path).replace(fs.sep, sep)
|
||||
else:
|
||||
rel = relpath(fs_path)
|
||||
|
||||
if rel.startswith(sep):
|
||||
# if it is an absolute path, return as it is.
|
||||
# This can happen on Windows when we are on a different drive.
|
||||
return rel
|
||||
prefix = curdir + sep if not rel.startswith(pardir) else ""
|
||||
return prefix + rel
|
||||
|
||||
|
||||
@@ -77,14 +87,14 @@ class YAMLSyntaxError(PrettyDvcException, YAMLFileCorruptedError):
|
||||
exc: Exception,
|
||||
rev: Optional[str] = None,
|
||||
) -> None:
|
||||
self.path: str = path
|
||||
self.yaml_text: str = yaml_text
|
||||
self.exc: Exception = exc
|
||||
|
||||
merge_conflicts = merge_conflict_marker.search(self.yaml_text)
|
||||
self.hint = " (possible merge conflicts)" if merge_conflicts else ""
|
||||
self.rev: Optional[str] = rev
|
||||
super().__init__(self.path)
|
||||
super().__init__(path)
|
||||
self.relpath: str = path
|
||||
|
||||
def __pretty_exc__(self, **kwargs: Any) -> None: # noqa: C901
|
||||
from ruamel.yaml.error import MarkedYAMLError
|
||||
@@ -134,9 +144,8 @@ class YAMLSyntaxError(PrettyDvcException, YAMLFileCorruptedError):
|
||||
# if there are no other outputs
|
||||
lines.insert(0, "")
|
||||
|
||||
rel = make_relpath(self.path)
|
||||
rev_msg = f" in revision '{self.rev[:7]}'" if self.rev else ""
|
||||
msg_fmt = f"'{rel}' is invalid{self.hint}{rev_msg}."
|
||||
msg_fmt = f"'{self.relpath}' is invalid{self.hint}{rev_msg}."
|
||||
lines.insert(0, _prepare_message(msg_fmt))
|
||||
for line in lines:
|
||||
ui.error_write(line, styled=True)
|
||||
@@ -198,10 +207,9 @@ class YAMLValidationError(PrettyDvcException):
|
||||
self.text = text or ""
|
||||
self.exc = exc
|
||||
|
||||
rel = make_relpath(path) if path else ""
|
||||
self.path = path or ""
|
||||
|
||||
message = f"'{rel}' validation failed"
|
||||
message = f"'{self.path}' validation failed"
|
||||
message += f" in revision '{rev[:7]}'" if rev else ""
|
||||
if len(self.exc.errors) > 1:
|
||||
message += f": {len(self.exc.errors)} errors"
|
||||
@@ -288,10 +296,12 @@ def load(
|
||||
raise EncodingError(path, encoding) from exc
|
||||
except YAMLFileCorruptedError as exc:
|
||||
cause = exc.__cause__
|
||||
raise YAMLSyntaxError(path, text, exc, rev=rev) from cause
|
||||
relpath = make_relpath(path, fs)
|
||||
raise YAMLSyntaxError(relpath, text, exc, rev=rev) from cause
|
||||
|
||||
if schema:
|
||||
relpath = make_relpath(path, fs)
|
||||
# not returning validated data, as it may remove
|
||||
# details from CommentedMap that we get from roundtrip parser
|
||||
validate(data, schema, text=text, path=path, rev=rev)
|
||||
validate(data, schema, text=text, path=relpath, rev=rev)
|
||||
return data, text
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import os
|
||||
from os import curdir, pardir, sep
|
||||
|
||||
import pytest
|
||||
from ruamel.yaml import __with_libyaml__ as ruamel_clib
|
||||
@@ -372,18 +372,22 @@ def test_on_revision(
|
||||
assert expected.format(short_rev=scm.get_rev()[:7]) in err
|
||||
|
||||
|
||||
def test_make_relpath(tmp_dir, monkeypatch):
|
||||
def test_make_relpath(tmp_dir, dvc, scm, monkeypatch):
|
||||
from dvc.utils.strictyaml import make_relpath
|
||||
|
||||
gitfs = scm.get_fs("HEAD")
|
||||
path = tmp_dir / "dvc.yaml"
|
||||
expected_path = "./dvc.yaml" if os.name == "posix" else ".\\dvc.yaml"
|
||||
expected_path = curdir + sep + "dvc.yaml"
|
||||
assert make_relpath(path) == expected_path
|
||||
assert make_relpath("/dvc.yaml", gitfs) == expected_path
|
||||
|
||||
(tmp_dir / "dir").mkdir(exist_ok=True)
|
||||
monkeypatch.chdir("dir")
|
||||
gitfs.chdir("/dir")
|
||||
|
||||
expected_path = "../dvc.yaml" if os.name == "posix" else "..\\dvc.yaml"
|
||||
expected_path = pardir + sep + "dvc.yaml"
|
||||
assert make_relpath(path) == expected_path
|
||||
assert make_relpath("/dvc.yaml", gitfs) == expected_path
|
||||
|
||||
|
||||
def test_fallback_exception_message(tmp_dir, dvc, mocker, caplog):
|
||||
|
||||
Reference in New Issue
Block a user