summon: raise SummonError appropiately

This commit is contained in:
Mr. Outis
2019-12-24 20:20:03 -06:00
parent fbb7aebd31
commit 1e65c76ef1
3 changed files with 38 additions and 14 deletions
+14 -11
View File
@@ -12,8 +12,9 @@ except ImportError:
import ruamel.yaml
from voluptuous import Schema, Optional, Invalid, ALLOW_EXTRA
from dvc.utils.compat import urlparse, builtin_str, FileNotFoundError
from dvc.utils.compat import urlparse, builtin_str
from dvc.repo import Repo
from dvc.exceptions import SummonError, FileMissingError
from dvc.external_repo import external_repo
@@ -128,19 +129,21 @@ def _get_object_from_summoners_file(name, path):
Given a summonable object's name, search for it on the given file
and bring it to life.
"""
with open(path, "r") as fobj:
try:
try:
with open(path, "r") as fobj:
content = summon_schema(ruamel.yaml.safe_load(fobj.read()))
objects = content["objects"]
return next(x for x in objects if x["name"] == name)
except FileNotFoundError:
pass # XXX: No such YAML file with path: '<path>'
except ruamel.yaml.ScannerError:
pass # XXX: Failed to parse YAML correctly
except Invalid:
pass # XXX: YAML file dosen't match with the schema
except StopIteration:
pass # XXX: No such object with name: '<name>'
except FileMissingError as exc:
# XXX: Prints ugly absolute path.
raise SummonError("No such YAML file with path: '{}'".format(path))
except ruamel.yaml.YAMLError as exc:
raise SummonError("Failed to parse YAML correctly", exc)
except Invalid as exc:
# XXX: Doesn't point out the error.
raise SummonError("YAML file dosen't match with the schema", exc)
except StopIteration:
raise SummonError("No such object with name '{}'".format(name))
def _invoke_method(call, args, path):
+4
View File
@@ -353,3 +353,7 @@ class PathMissingError(DvcException):
" neighther as an output nor a git-handled file."
)
super(PathMissingError, self).__init__(msg.format(path, repo))
class SummonError(DvcException):
pass
+20 -3
View File
@@ -13,6 +13,7 @@ from dvc.main import main
from dvc.path_info import URLInfo
from dvc.remote.config import RemoteConfig
from dvc.utils.compat import fspath
from dvc.exceptions import SummonError
from tests.remotes import Azure, GCP, HDFS, Local, OSS, S3, SSH
@@ -151,14 +152,18 @@ def test_summon(tmp_dir, erepo_dir, dvc, monkeypatch):
different_objects["objects"][0]["summon"]["args"]["x"] = 100
dvcsummon_yaml = ruamel.yaml.dump(objects)
non_canon_yaml = ruamel.yaml.dump(different_objects)
different_yaml = ruamel.yaml.dump(different_objects)
invalid_yaml = ruamel.yaml.dump({"name": "sum"})
not_yaml = "a: - this is not a valid YAML file"
with monkeypatch.context() as m:
m.chdir(fspath(erepo_dir))
erepo_dir.dvc_gen("number", "100", commit="Add number.dvc")
erepo_dir.scm_gen("dvcsummon.yaml", dvcsummon_yaml)
erepo_dir.scm_gen("non-canon.yaml", non_canon_yaml)
erepo_dir.scm_gen("different.yaml", different_yaml)
erepo_dir.scm_gen("invalid.yaml", invalid_yaml)
erepo_dir.scm_gen("not_yaml.yaml", not_yaml)
erepo_dir.scm_gen(
"calculator.py",
"def add_to_num(x): return x + int(open('number').read())",
@@ -169,4 +174,16 @@ def test_summon(tmp_dir, erepo_dir, dvc, monkeypatch):
assert api.summon("sum", repo=repo_url) == 101
assert api.summon("sum", repo=repo_url, args={"x": 2}) == 102
assert api.summon("sum", repo=repo_url, fname="non-canon.yaml") == 200
assert api.summon("sum", repo=repo_url, fname="different.yaml") == 200
with pytest.raises(SummonError):
api.summon("sum", repo=repo_url, fname="not-existent-file.yaml")
with pytest.raises(SummonError):
api.summon("non-existent", repo=repo_url)
with pytest.raises(SummonError):
api.summon("sum", repo=repo_url, fname="invalid.yaml")
with pytest.raises(SummonError):
api.summon("sum", repo=repo_url, fname="not_yaml.yaml")