mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-01 23:08:43 +01:00
run: preserve order when -f/--force overwrite stage (#4035)
This commit preserves comments, meta and order inside a dvc.yaml when `-f/--force` is used. But, it does not maintain comments/meta for .dvc files. Related: #4014
This commit is contained in:
+6
-5
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
from contextlib import suppress
|
||||
|
||||
from funcy import concat, first, lfilter
|
||||
|
||||
@@ -109,12 +110,12 @@ def run(self, fname=None, no_exec=False, single_stage=False, **kwargs):
|
||||
return None
|
||||
|
||||
dvcfile = Dvcfile(self, stage.path)
|
||||
if kwargs.get("force", True):
|
||||
dvcfile.remove_stage(stage)
|
||||
else:
|
||||
_check_stage_exists(dvcfile, stage)
|
||||
|
||||
try:
|
||||
if kwargs.get("force", True):
|
||||
with suppress(ValueError):
|
||||
self.stages.remove(stage)
|
||||
else:
|
||||
_check_stage_exists(dvcfile, stage)
|
||||
self.check_modified_graph([stage])
|
||||
except OutputDuplicationError as exc:
|
||||
raise OutputDuplicationError(exc.output, set(exc.stages) - {stage})
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import textwrap
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
@@ -6,6 +7,7 @@ import yaml
|
||||
from dvc.exceptions import InvalidArgumentError
|
||||
from dvc.repo import Repo
|
||||
from dvc.stage.exceptions import DuplicateStageName, InvalidStageName
|
||||
from dvc.utils.yaml import parse_yaml_for_update
|
||||
|
||||
|
||||
def test_run_with_name(tmp_dir, dvc, run_copy):
|
||||
@@ -315,3 +317,47 @@ def test_run_without_cmd(kwargs):
|
||||
with pytest.raises(InvalidArgumentError) as exc:
|
||||
Repo().run(**kwargs)
|
||||
assert "command is not specified" == str(exc.value)
|
||||
|
||||
|
||||
def test_run_overwrite_order(tmp_dir, dvc, run_copy):
|
||||
from dvc.dvcfile import PIPELINE_FILE
|
||||
|
||||
tmp_dir.gen({"foo": "foo", "foo1": "foo1"})
|
||||
run_copy("foo", "bar", name="copy-foo-bar")
|
||||
run_copy("bar", "foobar", name="copy-bar-foobar")
|
||||
|
||||
run_copy("foo1", "bar1", name="copy-foo-bar", force=True)
|
||||
|
||||
data = parse_yaml_for_update(
|
||||
(tmp_dir / PIPELINE_FILE).read_text(), PIPELINE_FILE
|
||||
)
|
||||
assert list(data["stages"].keys()) == ["copy-foo-bar", "copy-bar-foobar"]
|
||||
|
||||
|
||||
def test_run_overwrite_preserves_meta_and_comment(tmp_dir, dvc, run_copy):
|
||||
from dvc.dvcfile import PIPELINE_FILE
|
||||
|
||||
tmp_dir.gen({"foo": "foo", "foo1": "foo1"})
|
||||
text = textwrap.dedent(
|
||||
"""\
|
||||
stages:
|
||||
copy-foo-bar:
|
||||
cmd: python copy.py {src} {dest}
|
||||
deps:
|
||||
- copy.py
|
||||
- {src}
|
||||
outs:
|
||||
# comments are preserved
|
||||
- {dest}
|
||||
meta:
|
||||
name: meta is preserved too
|
||||
"""
|
||||
)
|
||||
(tmp_dir / PIPELINE_FILE).write_text(text.format(src="foo", dest="bar"))
|
||||
assert dvc.reproduce(PIPELINE_FILE)
|
||||
|
||||
assert run_copy("foo1", "bar1", name="copy-foo-bar", force=True)
|
||||
|
||||
assert (tmp_dir / PIPELINE_FILE).read_text() == text.format(
|
||||
src="foo1", dest="bar1"
|
||||
)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import filecmp
|
||||
import logging
|
||||
import os
|
||||
import textwrap
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
|
||||
@@ -1017,3 +1018,32 @@ class TestRunDirMetrics:
|
||||
metrics_no_cache=["dir"],
|
||||
single_stage=True,
|
||||
)
|
||||
|
||||
|
||||
def test_run_force_doesnot_preserve_comments_and_meta(tmp_dir, dvc, run_copy):
|
||||
"""Depends on loading of stage on `run` where we don't check the file
|
||||
for stage already exists, so we don't copy `stage_text` over due to which
|
||||
`meta` and `comments` don't get preserved."""
|
||||
tmp_dir.gen({"foo": "foo", "foo1": "foo1"})
|
||||
text = textwrap.dedent(
|
||||
"""\
|
||||
cmd: python copy.py foo bar
|
||||
deps:
|
||||
- path: copy.py
|
||||
- path: foo
|
||||
outs:
|
||||
# comment not preserved
|
||||
- path: bar
|
||||
meta:
|
||||
name: copy-foo-bar
|
||||
"""
|
||||
)
|
||||
(tmp_dir / "bar.dvc").write_text(text)
|
||||
dvc.reproduce("bar.dvc")
|
||||
assert "comment" in (tmp_dir / "bar.dvc").read_text()
|
||||
assert "meta" in (tmp_dir / "bar.dvc").read_text()
|
||||
|
||||
run_copy("foo1", "bar1", single_stage=True, force=True, fname="bar.dvc")
|
||||
|
||||
assert "comment" not in (tmp_dir / "bar.dvc").read_text()
|
||||
assert "meta" not in (tmp_dir / "bar.dvc").read_text()
|
||||
|
||||
Reference in New Issue
Block a user