Skip to content

Commit

Permalink
update msg for multiple overlapping outputs
Browse files Browse the repository at this point in the history
  • Loading branch information
dberenbaum committed Aug 21, 2023
1 parent fc9af7a commit 0dcd072
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 13 deletions.
25 changes: 13 additions & 12 deletions dvc/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Exceptions raised by the dvc."""
import errno
from typing import Dict, List
from typing import Any, Dict, List

from dvc.utils import format_link

Expand Down Expand Up @@ -31,24 +31,25 @@ class OutputDuplicationError(DvcException):
stages (list): list of paths to stages.
"""

def __init__(self, output, stages):
def __init__(self, output: str, stages: List[Any]):
from funcy import first

assert isinstance(output, str)
assert all(hasattr(stage, "relpath") for stage in stages)
msg = ""
stage_names = [s.addressing for s in stages]
stages_str = " ".join(stage_names)
if len(stages) == 1:
stage_name = first(stages)
msg = f"output '{output}' is already specified in {stage_name}."
stage = first(stages)
msg = (
f"output '{output}' is already specified in {stage}."
f"\nUse `dvc remove {stage.addressing}` to stop tracking the"
"overlapping output."
)
else:
msg = "output '{}' is already specified in stages:\n{}".format(
output, "\n".join(f"\t- {s}" for s in stage_names)
stage_names = "\n".join(["\t- " + s.addressing for s in stages])
msg = (
f"output '{output}' is specified in:\n{stage_names}"
"\nUse `dvc remove` with any of the above targets to stop tracking the "
"overlapping output."
)
msg += (
f"\nUse `dvc remove {stages_str}` to stop tracking the overlapping output."
)
super().__init__(msg)
self.stages = stages
self.output = output
Expand Down
22 changes: 21 additions & 1 deletion tests/func/test_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from dvc.stage import Stage
from dvc.stage.exceptions import StageExternalOutputsError, StagePathNotFoundError
from dvc.utils.fs import path_isin
from dvc.utils.serialize import YAMLFileCorruptedError
from dvc.utils.serialize import YAMLFileCorruptedError, dump_yaml
from dvc_data.hashfile.hash import file_md5
from dvc_data.hashfile.hash_info import HashInfo
from tests.utils import get_gitignore_content
Expand Down Expand Up @@ -656,6 +656,26 @@ def test_try_adding_pipeline_tracked_output(tmp_dir, dvc, run_copy):
dvc.add("bar")


def test_try_adding_multiple_overlaps(tmp_dir, dvc):
tmp_dir.dvc_gen("foo", "foo")
dvcyaml_content = {
"stages": {
"echo-foo": {
"cmd": "echo foo > foo",
"outs": ["foo"],
}
}
}
dump_yaml("dvc.yaml", dvcyaml_content)
msg = (
"output 'foo' is specified in:\n\t- foo.dvc\n\t- echo-foo"
"\nUse `dvc remove` with any of the above targets to stop tracking the "
"overlapping output."
)
with pytest.raises(DvcException, match=msg):
dvc.add("foo")


def test_add_pipeline_file(tmp_dir, dvc, run_copy):
from dvc.dvcfile import PROJECT_FILE

Expand Down

0 comments on commit 0dcd072

Please sign in to comment.