mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-02 07:18:25 +01:00
experiments: make dvc exp show more consistent w/viewer (#4489)
* experiments: cleanup show UI * show git tag/branch names instead of SHAs by default * make timestamp formatting more like the viewer * update tests * place timestamps in their own column * update command test * exp: remove unused regex Co-authored-by: Ruslan Kuprieiev <[email protected]>
This commit is contained in:
co-authored by
Ruslan Kuprieiev
parent
fcbbfac7f8
commit
e2b5ab996f
@@ -2,6 +2,7 @@ import argparse
|
||||
import io
|
||||
import logging
|
||||
from collections import OrderedDict
|
||||
from datetime import date
|
||||
from itertools import groupby
|
||||
from typing import Iterable, Optional
|
||||
|
||||
@@ -101,19 +102,18 @@ def _collect_rows(
|
||||
row = []
|
||||
style = None
|
||||
queued = "*" if exp.get("queued", False) else ""
|
||||
if no_timestamp:
|
||||
timestamp = ""
|
||||
else:
|
||||
commit_time = exp.get("timestamp")
|
||||
timestamp = f" ({commit_time})" if commit_time is not None else ""
|
||||
|
||||
if rev == "baseline":
|
||||
row.append(f"{base_rev}{timestamp}")
|
||||
name = exp.get("name", base_rev)
|
||||
row.append(f"{name}")
|
||||
style = "bold"
|
||||
elif i < len(experiments) - 1:
|
||||
row.append(f"├── {queued}{rev[:7]}{timestamp}")
|
||||
row.append(f"├── {queued}{rev[:7]}")
|
||||
else:
|
||||
row.append(f"└── {queued}{rev[:7]}{timestamp}")
|
||||
row.append(f"└── {queued}{rev[:7]}")
|
||||
|
||||
if not no_timestamp:
|
||||
row.append(_format_time(exp.get("timestamp")))
|
||||
|
||||
_extend_row(
|
||||
row, metric_names, exp.get("metrics", {}).items(), precision
|
||||
@@ -123,6 +123,16 @@ def _collect_rows(
|
||||
yield row, style
|
||||
|
||||
|
||||
def _format_time(timestamp):
|
||||
if timestamp is None:
|
||||
return "-"
|
||||
if timestamp.date() == date.today():
|
||||
fmt = "%I:%M %p"
|
||||
else:
|
||||
fmt = "%b %d, %Y"
|
||||
return timestamp.strftime(fmt)
|
||||
|
||||
|
||||
def _extend_row(row, names, items, precision):
|
||||
from flatten_json import flatten
|
||||
|
||||
@@ -181,6 +191,8 @@ def _show_experiments(all_experiments, console, **kwargs):
|
||||
|
||||
table = Table()
|
||||
table.add_column("Experiment", no_wrap=True)
|
||||
if not kwargs.get("no_timestamp", False):
|
||||
table.add_column("Created")
|
||||
for name in metric_names:
|
||||
table.add_column(name, justify="right", no_wrap=True)
|
||||
for name in param_names:
|
||||
@@ -212,6 +224,7 @@ class CmdExperimentsShow(CmdBase):
|
||||
all_branches=self.args.all_branches,
|
||||
all_tags=self.args.all_tags,
|
||||
all_commits=self.args.all_commits,
|
||||
sha_only=self.args.sha,
|
||||
)
|
||||
|
||||
if self.args.no_pager:
|
||||
@@ -414,6 +427,12 @@ def add_parser(subparsers, parent_parser):
|
||||
default=False,
|
||||
help="Do not show experiment timestamps.",
|
||||
)
|
||||
experiments_show_parser.add_argument(
|
||||
"--sha",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Always show git commit SHAs instead of branch/tag names.",
|
||||
)
|
||||
experiments_show_parser.set_defaults(func=CmdExperimentsShow)
|
||||
|
||||
EXPERIMENTS_CHECKOUT_HELP = "Checkout experiments."
|
||||
|
||||
@@ -9,7 +9,9 @@ from dvc.repo.params.show import _collect_configs, _read_params
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _collect_experiment(repo, branch, stash=False):
|
||||
def _collect_experiment(repo, branch, stash=False, sha_only=True):
|
||||
from git.exc import GitCommandError
|
||||
|
||||
res = defaultdict(dict)
|
||||
for rev in repo.brancher(revs=[branch]):
|
||||
if rev == "workspace":
|
||||
@@ -29,12 +31,27 @@ def _collect_experiment(repo, branch, stash=False):
|
||||
vals = _read_metrics(repo, metrics, rev)
|
||||
res["metrics"] = vals
|
||||
|
||||
if not sha_only and rev != "workspace":
|
||||
try:
|
||||
name = repo.scm.repo.git.describe(
|
||||
rev, all=True, exact_match=True
|
||||
)
|
||||
name = name.rsplit("/")[-1]
|
||||
res["name"] = name
|
||||
except GitCommandError:
|
||||
pass
|
||||
|
||||
return res
|
||||
|
||||
|
||||
@locked
|
||||
def show(
|
||||
repo, all_branches=False, all_tags=False, revs=None, all_commits=False
|
||||
repo,
|
||||
all_branches=False,
|
||||
all_tags=False,
|
||||
revs=None,
|
||||
all_commits=False,
|
||||
sha_only=False,
|
||||
):
|
||||
res = defaultdict(OrderedDict)
|
||||
|
||||
@@ -52,7 +69,9 @@ def show(
|
||||
)
|
||||
|
||||
for rev in revs:
|
||||
res[rev]["baseline"] = _collect_experiment(repo, rev)
|
||||
res[rev]["baseline"] = _collect_experiment(
|
||||
repo, rev, sha_only=sha_only
|
||||
)
|
||||
|
||||
# collect reproduced experiments
|
||||
for exp_branch in repo.experiments.scm.list_branches():
|
||||
|
||||
@@ -48,6 +48,7 @@ def test_show_experiment(tmp_dir, scm, dvc):
|
||||
"params": {"params.yaml": {"foo": 1}},
|
||||
"queued": False,
|
||||
"timestamp": timestamp,
|
||||
"name": "master",
|
||||
}
|
||||
expected_params = {"foo": 2}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ def test_experiments_show(dvc, mocker):
|
||||
"--all-tags",
|
||||
"--all-branches",
|
||||
"--all-commits",
|
||||
"--sha",
|
||||
]
|
||||
)
|
||||
assert cli_args.func == CmdExperimentsShow
|
||||
@@ -47,5 +48,9 @@ def test_experiments_show(dvc, mocker):
|
||||
assert cmd.run() == 0
|
||||
|
||||
m.assert_called_once_with(
|
||||
cmd.repo, all_tags=True, all_branches=True, all_commits=True
|
||||
cmd.repo,
|
||||
all_tags=True,
|
||||
all_branches=True,
|
||||
all_commits=True,
|
||||
sha_only=True,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user