exp: add rename command (#9812)

* Add renaming for finished experiments

* Update arg parser

* Add rename by rev

* Add rename tests

* Change remove to rename; Refactor arguments error

* Remove --rev; Use resolve_name; Add test

* Update testing; Fix python3.10 rename failure

* Update rename test

* Update tests and error handling

* exp rename: Add `--force`.

Fail if experiment new_name exists but allow to overwrite it.

---------

Co-authored-by: daavoo <[email protected]>
This commit is contained in:
BradyJ27
2023-09-18 17:01:32 +00:00
committed by GitHub
co-authored by daavoo
parent 784a5b5199
commit 51dc78a135
7 changed files with 203 additions and 2 deletions
+33
View File
@@ -0,0 +1,33 @@
import pytest
from dvc.repo.experiments.exceptions import (
ExperimentExistsError,
UnresolvedExpNamesError,
)
from dvc.repo.experiments.utils import exp_refs_by_names
def test_rename_experiment_by_name(scm, dvc, exp_stage):
dvc.experiments.run(exp_stage.addressing, name="test-name", params=["foo=1"])
old_ref = exp_refs_by_names(scm, {"test-name"})
dvc.experiments.rename("new-name", "test-name")
new_ref = exp_refs_by_names(scm, {"new-name"})
assert scm.get_ref(str(old_ref["test-name"][0])) is None
assert scm.get_ref(str(new_ref["new-name"][0])) is not None
with pytest.raises(UnresolvedExpNamesError):
dvc.experiments.rename("new-name", "foo")
def test_same_name(dvc, exp_stage):
dvc.experiments.run(exp_stage.addressing, name="same-name", params=["foo=1"])
assert dvc.experiments.rename("same-name", "same-name") is None
def test_existing_name(dvc, exp_stage):
dvc.experiments.run(exp_stage.addressing, name="first-name", params=["foo=1"])
dvc.experiments.run(exp_stage.addressing, name="second-name", params=["foo=2"])
with pytest.raises(ExperimentExistsError):
dvc.experiments.rename("second-name", "first-name")
dvc.experiments.rename("second-name", "first-name", force=True)
+35
View File
@@ -9,6 +9,7 @@ from dvc.commands.experiments.ls import CmdExperimentsList
from dvc.commands.experiments.pull import CmdExperimentsPull
from dvc.commands.experiments.push import CmdExperimentsPush
from dvc.commands.experiments.remove import CmdExperimentsRemove
from dvc.commands.experiments.rename import CmdExperimentsRename
from dvc.commands.experiments.run import CmdExperimentsRun
from dvc.commands.experiments.save import CmdExperimentsSave
from dvc.commands.experiments.show import CmdExperimentsShow
@@ -418,6 +419,40 @@ def test_experiments_remove_invalid(dvc, scm, mocker, capsys, caplog):
)
def test_experiments_rename_flag(dvc, scm, mocker, capsys, caplog):
cli_args = parse_args(
[
"experiments",
"rename",
"--git-remote",
"myremote",
"exp-123",
"exp-234",
]
)
assert cli_args.func == CmdExperimentsRename
cmd = cli_args.func(cli_args)
m = mocker.patch("dvc.repo.experiments.rename.rename", return_value={})
assert cmd.run() == 0
m.assert_called_once_with(
cmd.repo,
exp_name="exp-123",
new_name="exp-234",
git_remote="myremote",
force=False,
)
def test_experiments_rename_invalid(dvc, scm, mocker, capsys, caplog):
cmd = CmdExperimentsRename(parse_args(["exp", "rename", "exp-1"]))
with pytest.raises(InvalidArgumentError) as excinfo:
cmd.run()
assert (
str(excinfo.value)
== "An experiment to rename and a new experiment name are required."
)
def test_experiments_save(dvc, scm, mocker):
cli_args = parse_args(["exp", "save", "--name", "exp-name", "--force"])
assert cli_args.func == CmdExperimentsSave