Beispiel #1
0
def test_remove_stage_preserves_comment(tmp_dir, dvc, run_copy):
    tmp_dir.gen(
        "dvc.yaml",
        textwrap.dedent("""\
            stages:
                generate-foo:
                    cmd: "echo foo > foo"
                    # This copies 'foo' text to 'foo' file.
                    outs:
                    - foo
                copy-foo-bar:
                    cmd: "python copy.py foo bar"
                    deps:
                    - foo
                    outs:
                    - bar"""),
    )

    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()
    assert (tmp_dir / "bar").exists()

    dvc_file.remove_stage(dvc_file.stages["copy-foo-bar"])
    assert ("# This copies 'foo' text to 'foo' file."
            in (tmp_dir / PIPELINE_FILE).read_text())
Beispiel #2
0
def run(self, fname=None, no_exec=False, single_stage=False, **kwargs):
    from dvc.stage import PipelineStage, Stage, create_stage
    from dvc.dvcfile import Dvcfile, PIPELINE_FILE

    if not kwargs.get("cmd"):
        raise InvalidArgumentError("command is not specified")

    stage_cls = PipelineStage
    path = PIPELINE_FILE
    stage_name = kwargs.get("name")

    if stage_name and single_stage:
        raise InvalidArgumentError(
            "`-n|--name` is incompatible with `--single-stage`")

    if not stage_name and not single_stage:
        raise InvalidArgumentError("`-n|--name` is required")

    if single_stage:
        kwargs.pop("name", None)
        stage_cls = Stage
        path = fname or _get_file_path(kwargs)
    else:
        if not is_valid_name(stage_name):
            raise InvalidStageName

    params = parse_params(kwargs.pop("params", []))
    stage = create_stage(stage_cls,
                         repo=self,
                         path=path,
                         params=params,
                         **kwargs)
    if stage is None:
        return None

    dvcfile = Dvcfile(self, stage.path)
    if dvcfile.exists():
        if kwargs.get("overwrite", True):
            dvcfile.remove_stage(stage)
        elif stage_cls != PipelineStage:
            raise StageFileAlreadyExistsError(dvcfile.relpath)
        elif stage_name and stage_name in dvcfile.stages:
            raise DuplicateStageName(stage_name, dvcfile)

    try:
        self.check_modified_graph([stage])
    except OutputDuplicationError as exc:
        raise OutputDuplicationError(exc.output, set(exc.stages) - {stage})

    if no_exec:
        stage.ignore_outs()
    else:
        stage.run(
            no_commit=kwargs.get("no_commit", False),
            run_cache=kwargs.get("run_cache", True),
        )

    dvcfile.dump(stage, update_pipeline=True, no_lock=no_exec)
    return stage
Beispiel #3
0
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)

    assert dvc_file.exists()
    assert (tmp_dir / PIPELINE_LOCK).exists()
    assert (tmp_dir / "foo").exists()

    dvc_file.remove_stage(dvc_file.stages["run_copy"])
    assert not dvc_file.exists()
    assert not (tmp_dir / PIPELINE_LOCK).exists()
Beispiel #4
0
def test_remove_stage_on_lockfile_format_error(tmp_dir, dvc, run_copy):
    tmp_dir.gen("foo", "foo")
    stage = run_copy("foo", "bar", name="copy-foo-bar")
    dvc_file = Dvcfile(dvc, stage.path)
    lock_file = dvc_file._lockfile

    data = dvc_file._load()[0]
    lock_data = lock_file.load()
    lock_data["gibberish"] = True
    data["gibberish"] = True
    dump_yaml(lock_file.relpath, lock_data)
    with pytest.raises(StageFileFormatError):
        dvc_file.remove_stage(stage)

    lock_file.remove()
    dvc_file.dump(stage, update_pipeline=False)

    dump_yaml(dvc_file.relpath, data)
    with pytest.raises(StageFileFormatError):
        dvc_file.remove_stage(stage)
Beispiel #5
0
def test_remove_stage_dvcfiles(tmp_dir, dvc, run_copy):
    tmp_dir.gen("foo", "foo")
    stage = run_copy("foo", "bar", single_stage=True)

    dvc_file = Dvcfile(dvc, stage.path)
    assert dvc_file.exists()
    dvc_file.remove_stage(stage)
    assert not dvc_file.exists()

    # re-check to see if it fails if there's no stage entry
    dvc_file.remove_stage(stage)
    dvc_file.remove(force=True)

    # should not fail when there's no file at all.
    dvc_file.remove_stage(stage)
Beispiel #6
0
def test_remove_stage(tmp_dir, dvc, run_copy):
    tmp_dir.gen("foo", "foo")
    stage = run_copy("foo", "bar", name="copy-foo-bar")
    stage2 = run_copy("bar", "foobar", name="copy-bar-foobar")

    dvc_file = Dvcfile(dvc, PIPELINE_FILE)
    assert dvc_file.exists()
    assert {"copy-bar-foobar",
            "copy-foo-bar"} == set(dvc_file._load()[0]["stages"].keys())

    dvc_file.remove_stage(stage)

    assert ["copy-bar-foobar"] == list(dvc_file._load()[0]["stages"].keys())

    # sanity check
    stage2.reload()

    # re-check to see if it fails if there's no stage entry
    dvc_file.remove_stage(stage)
    dvc_file.remove(force=True)
    # should not fail when there's no file at all.
    dvc_file.remove_stage(stage)