Repository: iterative/dvc

Issue:
metrics: automatic type detection
E.g. if we see that output has `.json` suffix, we could safely assume that it is `--type json` without explicitly specifying it.


Discussion:

Patch:
diff --git a/dvc/command/metrics.py b/dvc/command/metrics.py
--- a/dvc/command/metrics.py
+++ b/dvc/command/metrics.py
@@ -107,7 +107,13 @@ def add_parser(subparsers, parent_parser):
         "path", nargs="?", help="Path to a metric file or a directory."
     )
     metrics_show_parser.add_argument(
-        "-t", "--type", help="Type of metrics (raw/json/tsv/htsv/csv/hcsv)."
+        "-t",
+        "--type",
+        help=(
+            "Type of metrics (json/tsv/htsv/csv/hcsv). "
+            "It can be detected by the file extension automatically. "
+            "Unsupported types will be treated as raw."
+        ),
     )
     metrics_show_parser.add_argument(
         "-x", "--xpath", help="json/tsv/htsv/csv/hcsv path."
diff --git a/dvc/repo/metrics/show.py b/dvc/repo/metrics/show.py
--- a/dvc/repo/metrics/show.py
+++ b/dvc/repo/metrics/show.py
@@ -129,6 +129,8 @@ def _read_metrics(self, metrics, branch):
     res = {}
     for out, typ, xpath in metrics:
         assert out.scheme == "local"
+        if not typ:
+            typ = os.path.splitext(out.path.lower())[1].replace(".", "")
         if out.use_cache:
             metric = _read_metrics_filesystem(
                 self.cache.local.get(out.checksum),


Test patch:
diff --git a/tests/test_metrics.py b/tests/test_metrics.py
--- a/tests/test_metrics.py
+++ b/tests/test_metrics.py
@@ -541,3 +541,58 @@ def test_add(self):
 
     def test_run(self):
         self._test_metrics(self._do_run)
+
+
+class TestMetricsType(TestDvc):
+    branches = ["foo", "bar", "baz"]
+    files = [
+        "metric",
+        "metric.txt",
+        "metric.json",
+        "metric.tsv",
+        "metric.htsv",
+        "metric.csv",
+        "metric.hcsv",
+    ]
+    xpaths = [None, None, "branch", "0,0", "0,branch", "0,0", "0,branch"]
+
+    def setUp(self):
+        super(TestMetricsType, self).setUp()
+        self.dvc.scm.commit("init")
+
+        for branch in self.branches:
+            self.dvc.scm.checkout(branch, create_new=True)
+            with open("metric", "w+") as fd:
+                fd.write(branch)
+            with open("metric.txt", "w+") as fd:
+                fd.write(branch)
+            with open("metric.json", "w+") as fd:
+                json.dump({"branch": branch}, fd)
+            with open("metric.csv", "w+") as fd:
+                fd.write(branch)
+            with open("metric.hcsv", "w+") as fd:
+                fd.write("branch\n")
+                fd.write(branch)
+            with open("metric.tsv", "w+") as fd:
+                fd.write(branch)
+            with open("metric.htsv", "w+") as fd:
+                fd.write("branch\n")
+                fd.write(branch)
+            self.dvc.run(metrics_no_cache=self.files, overwrite=True)
+            self.dvc.scm.add(self.files + ["metric.dvc"])
+            self.dvc.scm.commit("metric")
+
+        self.dvc.scm.checkout("master")
+
+    def test_show(self):
+        for file_name, xpath in zip(self.files, self.xpaths):
+            self._do_show(file_name, xpath)
+
+    def _do_show(self, file_name, xpath):
+        ret = self.dvc.metrics.show(file_name, xpath=xpath, all_branches=True)
+        self.assertEqual(len(ret), 3)
+        for branch in self.branches:
+            if isinstance(ret[branch][file_name], list):
+                self.assertSequenceEqual(ret[branch][file_name], [branch])
+            else:
+                self.assertSequenceEqual(ret[branch][file_name], branch)