From beb610c3aba87df31fb932d85569ed1d509acdea Mon Sep 17 00:00:00 2001 From: Saugat Pachhai Date: Mon, 12 Jul 2021 20:43:41 +0545 Subject: [PATCH] add: ignore duplicated entries (#6286) --- dvc/repo/add.py | 9 ++++++++- dvc/ui/__init__.py | 4 ++++ tests/func/test_add.py | 9 +++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/dvc/repo/add.py b/dvc/repo/add.py index 02ffa7346..2d07d9439 100644 --- a/dvc/repo/add.py +++ b/dvc/repo/add.py @@ -43,7 +43,14 @@ def check_recursive_and_fname(args): def transform_targets(args): - args.targets = ensure_list(args.targets) + from funcy import count_reps + + counts = count_reps(ensure_list(args.targets)) + dupes = [key for key, count in counts.items() if count > 1] + if dupes: + msg = ", ".join(f"[b]{key}[/]" for key in dupes) + ui.error_write(f"ignoring duplicated targets: {msg}", styled=True) + args.targets = list(counts) def check_arg_combinations(args): diff --git a/dvc/ui/__init__.py b/dvc/ui/__init__.py index 6ca054fab..bce0c836a 100644 --- a/dvc/ui/__init__.py +++ b/dvc/ui/__init__.py @@ -61,6 +61,8 @@ class Console: style: str = None, sep: str = None, end: str = None, + styled: bool = True, + force: bool = True, ) -> None: return self.write( *objects, @@ -68,6 +70,8 @@ class Console: sep=sep, end=end, stderr=True, + force=force, + styled=styled, ) def write( diff --git a/tests/func/test_add.py b/tests/func/test_add.py index 9273951e2..0b6164563 100644 --- a/tests/func/test_add.py +++ b/tests/func/test_add.py @@ -1229,3 +1229,12 @@ def test_add_does_not_remove_stage_file_on_failure( assert str(exc_info.value) == exc_msg assert (tmp_dir / "foo.dvc").exists() assert (tmp_dir / stage.path).read_text() == dvcfile_contents + + +def test_add_ignore_duplicated_targets(tmp_dir, dvc, capsys): + tmp_dir.gen({"foo": "foo", "bar": "bar", "foobar": "foobar"}) + stages = dvc.add(["foo", "bar", "foobar", "bar", "foo"]) + + _, err = capsys.readouterr() + assert len(stages) == 3 + assert "ignoring duplicated targets: foo, bar" in err