Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 38 additions & 95 deletions dvc/command/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,9 @@
def show_metrics(
metrics, all_branches=False, all_tags=False, all_commits=False
):
"""
Args:
metrics (list): Where each element is either a `list`
if an xpath was specified, otherwise a `str`
"""
from flatten_json import flatten
from dvc.utils.diff import format_dict

# When `metrics` contains a `None` key, it means that some files
# specified as `targets` in `repo.metrics.show` didn't contain any metrics.
missing = metrics.pop(None, None)
Expand All @@ -28,21 +26,13 @@ def show_metrics(
logger.info("{branch}:".format(branch=branch))

for fname, metric in val.items():
if isinstance(metric, dict):
lines = list(metric.values())
elif isinstance(metric, list):
lines = metric
else:
lines = metric.splitlines()
if not isinstance(metric, dict):
logger.info("\t{}: {}".format(fname, str(metric)))
continue

if len(lines) > 1:
logger.info("\t{fname}:".format(fname=fname))

for line in lines:
logger.info("\t\t{content}".format(content=line))

else:
logger.info("\t{}: {}".format(fname, metric))
logger.info("\t{}:".format(fname))
for key, value in flatten(format_dict(metric), ".").items():
logger.info("\t\t{}: {}".format(key, value))

if missing:
raise BadMetricError(missing)
Expand All @@ -53,35 +43,25 @@ def run(self):
try:
metrics = self.repo.metrics.show(
self.args.targets,
typ=self.args.type,
xpath=self.args.xpath,
all_branches=self.args.all_branches,
all_tags=self.args.all_tags,
all_commits=self.args.all_commits,
recursive=self.args.recursive,
)

show_metrics(
metrics,
self.args.all_branches,
self.args.all_tags,
self.args.all_commits,
)
except DvcException:
logger.exception("failed to show metrics")
return 1

return 0

if self.args.show_json:
import json

class CmdMetricsModify(CmdBase):
def run(self):
try:
self.repo.metrics.modify(
self.args.path, typ=self.args.type, xpath=self.args.xpath
)
logger.info(json.dumps(metrics))
else:
show_metrics(
metrics,
self.args.all_branches,
self.args.all_tags,
self.args.all_commits,
)
except DvcException:
logger.exception("failed to modify metric file settings")
logger.exception("failed to show metrics")
return 1

return 0
Expand All @@ -90,9 +70,7 @@ def run(self):
class CmdMetricsAdd(CmdBase):
def run(self):
try:
self.repo.metrics.add(
self.args.path, self.args.type, self.args.xpath
)
self.repo.metrics.add(self.args.path)
except DvcException:
msg = "failed to add metric file '{}'".format(self.args.path)
logger.exception(msg)
Expand All @@ -114,11 +92,14 @@ def run(self):


def _show_diff(diff):
from collections import OrderedDict

from dvc.utils.diff import table

rows = []
for fname, mdiff in diff.items():
for metric, change in mdiff.items():
sorted_mdiff = OrderedDict(sorted(mdiff.items()))
for metric, change in sorted_mdiff.items():
rows.append(
[
fname,
Expand All @@ -138,9 +119,8 @@ def run(self):
a_rev=self.args.a_rev,
b_rev=self.args.b_rev,
targets=self.args.targets,
typ=self.args.type,
xpath=self.args.xpath,
recursive=self.args.recursive,
all=self.args.all,
)

if self.args.show_json:
Expand Down Expand Up @@ -185,32 +165,9 @@ def add_parser(subparsers, parent_parser):
help=METRICS_ADD_HELP,
formatter_class=argparse.RawDescriptionHelpFormatter,
)
metrics_add_parser.add_argument(
"-t", "--type", help="Type of metrics (json/yaml).", metavar="<type>",
)
metrics_add_parser.add_argument(
"-x", "--xpath", help="json/yaml path.", metavar="<path>",
)
metrics_add_parser.add_argument("path", help="Path to a metric file.")
metrics_add_parser.set_defaults(func=CmdMetricsAdd)

METRICS_MODIFY_HELP = "Modify metric default formatting."
metrics_modify_parser = metrics_subparsers.add_parser(
"modify",
parents=[parent_parser],
description=append_doc_link(METRICS_MODIFY_HELP, "metrics/modify"),
help=METRICS_MODIFY_HELP,
formatter_class=argparse.RawDescriptionHelpFormatter,
)
metrics_modify_parser.add_argument(
"-t", "--type", help="Type of metrics (json/yaml).", metavar="<type>",
)
metrics_modify_parser.add_argument(
"-x", "--xpath", help="json/yaml path.", metavar="<path>",
)
metrics_modify_parser.add_argument("path", help="Path to a metric file.")
metrics_modify_parser.set_defaults(func=CmdMetricsModify)

METRICS_SHOW_HELP = "Print metrics, with optional formatting."
metrics_show_parser = metrics_subparsers.add_parser(
"show",
Expand All @@ -224,19 +181,6 @@ def add_parser(subparsers, parent_parser):
nargs="*",
help="Metric files or directories (see -R) to show",
)
metrics_show_parser.add_argument(
"-t",
"--type",
help=(
"Type of metrics (json/yaml). "
"It can be detected by the file extension automatically. "
"Unsupported types will be treated as raw."
),
metavar="<type>",
)
metrics_show_parser.add_argument(
"-x", "--xpath", help="json/yaml path.", metavar="<path>",
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we wanted to keep for metrics show (may be diff as well)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not in the same shape. As a filter - maybe, but later.

metrics_show_parser.add_argument(
"-a",
"--all-branches",
Expand Down Expand Up @@ -267,6 +211,12 @@ def add_parser(subparsers, parent_parser):
"metric files."
),
)
metrics_show_parser.add_argument(
"--show-json",
action="store_true",
default=False,
help="Show output in JSON format.",
)
metrics_show_parser.set_defaults(func=CmdMetricsShow)

METRICS_DIFF_HELP = "Show changes in metrics between commits"
Expand Down Expand Up @@ -295,19 +245,6 @@ def add_parser(subparsers, parent_parser):
),
metavar="<paths>",
)
metrics_diff_parser.add_argument(
"-t",
"--type",
help=(
"Type of metrics (json/yaml). "
"It can be detected by the file extension automatically. "
"Unsupported types will be treated as raw."
),
metavar="<type>",
)
metrics_diff_parser.add_argument(
"-x", "--xpath", help="json/yaml path.", metavar="<path>",
)
metrics_diff_parser.add_argument(
"-R",
"--recursive",
Expand All @@ -318,6 +255,12 @@ def add_parser(subparsers, parent_parser):
"metric files."
),
)
metrics_diff_parser.add_argument(
"--all",
action="store_true",
default=False,
help="Show unchanged metrics as well.",
)
metrics_diff_parser.add_argument(
"--show-json",
action="store_true",
Expand Down
1 change: 1 addition & 0 deletions dvc/remote/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def get(self, md5):
return self.checksum_to_path_info(md5).url

def exists(self, path_info):
assert is_working_tree(self.repo.tree)
assert path_info.scheme == "local"
return self.repo.tree.exists(fspath_py35(path_info))

Expand Down
5 changes: 0 additions & 5 deletions dvc/repo/metrics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ def add(self, *args, **kwargs):

return add(self.repo, *args, **kwargs)

def modify(self, *args, **kwargs):
from dvc.repo.metrics.modify import modify

return modify(self.repo, *args, **kwargs)

def show(self, *args, **kwargs):
from dvc.repo.metrics.show import show

Expand Down
6 changes: 2 additions & 4 deletions dvc/repo/metrics/add.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from dvc.repo.metrics.modify import modify


def add(repo, path, typ=None, xpath=None):
if not typ:
typ = "raw"
modify(repo, path, typ, xpath)
def add(repo, path):
modify(repo, path)
8 changes: 6 additions & 2 deletions dvc/repo/metrics/diff.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import dvc.utils.diff
from dvc.utils.diff import format_dict, diff as _diff
from dvc.exceptions import NoMetricsError


Expand All @@ -13,7 +13,11 @@ def _get_metrics(repo, *args, rev=None, **kwargs):


def diff(repo, *args, a_rev=None, b_rev=None, **kwargs):
with_unchanged = kwargs.pop("all", False)

old = _get_metrics(repo, *args, **kwargs, rev=(a_rev or "HEAD"))
new = _get_metrics(repo, *args, **kwargs, rev=b_rev)

return dvc.utils.diff.diff(old, new)
return _diff(
format_dict(old), format_dict(new), with_unchanged=with_unchanged
)
22 changes: 1 addition & 21 deletions dvc/repo/metrics/modify.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@


@locked
def modify(repo, path, typ=None, xpath=None, delete=False):
supported_types = ["raw", "json", "csv", "tsv", "hcsv", "htsv"]
def modify(repo, path, delete=False):
outs = repo.find_outs_by_path(path)
assert len(outs) == 1
out = outs[0]
Expand All @@ -14,25 +13,6 @@ def modify(repo, path, typ=None, xpath=None, delete=False):
msg = "output '{}' scheme '{}' is not supported for metrics"
raise DvcException(msg.format(out.path, out.path_info.scheme))

if typ is not None:
typ = typ.lower().strip()
if typ not in ["raw", "json", "csv", "tsv", "hcsv", "htsv"]:
msg = (
"metric type '{typ}' is not supported, "
"must be one of [{types}]"
)
raise DvcException(
msg.format(typ=typ, types=", ".join(supported_types))
)
if not isinstance(out.metric, dict):
out.metric = {}
out.metric[out.PARAM_METRIC_TYPE] = typ

if xpath is not None:
if not isinstance(out.metric, dict):
out.metric = {}
out.metric[out.PARAM_METRIC_XPATH] = xpath

if delete:
out.metric = None

Expand Down
Loading