From 01bd7cdc14d3558e37c4899819e624bf375a9685 Mon Sep 17 00:00:00 2001 From: Nikita Kodenko Date: Sun, 12 Jul 2020 13:03:39 +0700 Subject: [PATCH 1/5] remove: remove dvc.yaml, dvc.lock if they are empty --- dvc/dvcfile.py | 2 ++ tests/func/test_dvcfile.py | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/dvc/dvcfile.py b/dvc/dvcfile.py index 8269edaa8a..451eac4b5e 100644 --- a/dvc/dvcfile.py +++ b/dvc/dvcfile.py @@ -234,6 +234,8 @@ def remove_stage(self, stage): logger.debug("Removing '%s' from '%s'", stage.name, self.path) del d["stages"][stage.name] dump_yaml(self.path, d) + if len(d["stages"]) == 0: + self.remove(force=True) class Lockfile(FileMixin): diff --git a/tests/func/test_dvcfile.py b/tests/func/test_dvcfile.py index 8c7978d648..26c0158d03 100644 --- a/tests/func/test_dvcfile.py +++ b/tests/func/test_dvcfile.py @@ -285,6 +285,33 @@ def test_remove_stage_preserves_comment(tmp_dir, dvc, run_copy): ) +def test_remove_stage_removes_dvcfiles_if_no_stages_left(tmp_dir, dvc): + tmp_dir.gen( + "dvc.yaml", + textwrap.dedent( + """\ + stages: + generate-foo: + cmd: "echo foo > foo" + # This copies 'foo' text to 'foo' file. + outs: + - foo""" + ), + ) + + dvc.reproduce(PIPELINE_FILE) + + dvc_file = Dvcfile(dvc, PIPELINE_FILE) + + assert dvc_file.exists() + assert (tmp_dir / PIPELINE_LOCK).exists() + assert (tmp_dir / "foo").exists() + + dvc_file.remove_stage(dvc_file.stages["generate-foo"]) + assert not dvc_file.exists() + assert not (tmp_dir / PIPELINE_LOCK).exists() + + def test_dvcfile_dump_preserves_meta(tmp_dir, dvc, run_copy): tmp_dir.gen("foo", "foo") stage = run_copy("foo", "bar", name="run_copy") From 4a1885e6aa3898a0966d64444c0b4b1c13cfd5d9 Mon Sep 17 00:00:00 2001 From: Nikita Kodenko Date: Sun, 12 Jul 2020 13:33:35 +0700 Subject: [PATCH 2/5] tests: remove: simplified dvc.yaml in test_remove_stage_removes_dvcfiles_if_no_stages_left --- tests/func/test_dvcfile.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/func/test_dvcfile.py b/tests/func/test_dvcfile.py index 26c0158d03..ea4d85a344 100644 --- a/tests/func/test_dvcfile.py +++ b/tests/func/test_dvcfile.py @@ -293,7 +293,6 @@ def test_remove_stage_removes_dvcfiles_if_no_stages_left(tmp_dir, dvc): stages: generate-foo: cmd: "echo foo > foo" - # This copies 'foo' text to 'foo' file. outs: - foo""" ), From bb0acbc35a7038aada839a59f5e1f3e5751659e0 Mon Sep 17 00:00:00 2001 From: Nikita Kodenko Date: Sun, 12 Jul 2020 13:48:14 +0700 Subject: [PATCH 3/5] tests: remove: minor fixes --- tests/func/test_dvcfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/func/test_dvcfile.py b/tests/func/test_dvcfile.py index ea4d85a344..f9d61b6e94 100644 --- a/tests/func/test_dvcfile.py +++ b/tests/func/test_dvcfile.py @@ -307,8 +307,8 @@ def test_remove_stage_removes_dvcfiles_if_no_stages_left(tmp_dir, dvc): assert (tmp_dir / "foo").exists() dvc_file.remove_stage(dvc_file.stages["generate-foo"]) - assert not dvc_file.exists() assert not (tmp_dir / PIPELINE_LOCK).exists() + assert not dvc_file.exists() def test_dvcfile_dump_preserves_meta(tmp_dir, dvc, run_copy): From 1fa368d41582e64416e623b313855bb00c2c9bb3 Mon Sep 17 00:00:00 2001 From: Nikita Kodenko Date: Mon, 13 Jul 2020 22:02:49 +0700 Subject: [PATCH 4/5] tests: remove: simplified test_remove_stage_removes_dvcfiles_if_no_stages_left --- tests/func/test_dvcfile.py | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/tests/func/test_dvcfile.py b/tests/func/test_dvcfile.py index f9d61b6e94..5ba42a093c 100644 --- a/tests/func/test_dvcfile.py +++ b/tests/func/test_dvcfile.py @@ -285,20 +285,11 @@ def test_remove_stage_preserves_comment(tmp_dir, dvc, run_copy): ) -def test_remove_stage_removes_dvcfiles_if_no_stages_left(tmp_dir, dvc): - tmp_dir.gen( - "dvc.yaml", - textwrap.dedent( - """\ - stages: - generate-foo: - cmd: "echo foo > foo" - outs: - - foo""" - ), - ) - - dvc.reproduce(PIPELINE_FILE) +def test_remove_stage_removes_dvcfiles_if_no_stages_left( + tmp_dir, dvc, run_copy +): + tmp_dir.gen("foo", "foo") + run_copy("foo", "bar", name="run_copy") dvc_file = Dvcfile(dvc, PIPELINE_FILE) @@ -306,9 +297,9 @@ def test_remove_stage_removes_dvcfiles_if_no_stages_left(tmp_dir, dvc): assert (tmp_dir / PIPELINE_LOCK).exists() assert (tmp_dir / "foo").exists() - dvc_file.remove_stage(dvc_file.stages["generate-foo"]) - assert not (tmp_dir / PIPELINE_LOCK).exists() + dvc_file.remove_stage(dvc_file.stages["run_copy"]) assert not dvc_file.exists() + assert not (tmp_dir / PIPELINE_LOCK).exists() def test_dvcfile_dump_preserves_meta(tmp_dir, dvc, run_copy): From a512225e4acfc24ad38e0c87317cb29d8801265f Mon Sep 17 00:00:00 2001 From: Nikita Kodenko Date: Mon, 13 Jul 2020 22:03:33 +0700 Subject: [PATCH 5/5] remove: independent removal of dvc.lock and dvc.yaml --- dvc/dvcfile.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/dvc/dvcfile.py b/dvc/dvcfile.py index 451eac4b5e..5b0f2f38c6 100644 --- a/dvc/dvcfile.py +++ b/dvc/dvcfile.py @@ -233,9 +233,11 @@ def remove_stage(self, stage): logger.debug("Removing '%s' from '%s'", stage.name, self.path) del d["stages"][stage.name] - dump_yaml(self.path, d) - if len(d["stages"]) == 0: - self.remove(force=True) + + if d["stages"]: + dump_yaml(self.path, d) + else: + super().remove() class Lockfile(FileMixin): @@ -288,7 +290,10 @@ def remove_stage(self, stage): logger.debug("Removing '%s' from '%s'", stage.name, self.path) del d[stage.name] - dump_yaml(self.path, d) + if d: + dump_yaml(self.path, d) + else: + self.remove() class Dvcfile: