Repository: iterative/dvc

Issue:
plots: replace --show-json with --show-vega
Requested by @dmpetrov for cml. `--show-vega` should require a target and return a filled vega template. `--show-json` is not needed, let's delete it.

Discussion:

Patch:
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 910a94380..f8eb17fd2 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -1,10 +1,17 @@
 ---
-name: Bug report
-about: Create a report to help us improve
-
+name: "\U0001F41B Bug Report"
+about: Create a bug report to help us improve DVC
+labels: bug, triage
 ---
 
+## Bug Report
+
+### Please provide information about your setup
+**Output of `dvc version`:**
+```sh
+$ dvc version
+```
 
-**Please provide information about your setup**
-DVC version(i.e. `dvc --version`), Platform and method of installation (pip, homebrew, pkg Mac, exe (Windows), DEB(Linux), RPM(Linux))
+**Additional Information (if any):**
 
+If applicable, please also provide a `--verbose` output of the command, eg: `dvc add --verbose`.
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 000000000..9ac0922e3
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,5 @@
+blank_issues_enabled: false
+contact_links:
+  - name: "🤗 Need help?"
+    url: https://dvc.org/chat
+    about: If you have a question, ask us on Discord. Please join with this invite 👉
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index d06eebb38..1829c929d 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -1,6 +1,6 @@
 ---
-name: Feature request
+name: "\U0001F680 Feature Request"
 about: Suggest an idea for this project
-
+labels: feature request, triage
 ---
 
diff --git a/dvc/command/plots.py b/dvc/command/plots.py
index b7900a697..ef50de6e7 100644
--- a/dvc/command/plots.py
+++ b/dvc/command/plots.py
@@ -33,6 +33,16 @@ class CmdPlots(CmdBase):
         raise NotImplementedError
 
     def run(self):
+        if self.args.show_vega:
+            if not self.args.targets:
+                logger.error("please specify a target for `--show-vega`")
+                return 1
+            if len(self.args.targets) > 1:
+                logger.error(
+                    "you can only specify one target for `--show-vega`"
+                )
+                return 1
+
         try:
             plots = self._func(
                 targets=self.args.targets,
@@ -45,10 +55,9 @@ class CmdPlots(CmdBase):
                 y_title=self.args.ylab,
             )
 
-            if self.args.show_json:
-                import json
-
-                logger.info(json.dumps(plots))
+            if self.args.show_vega:
+                target = self.args.targets[0]
+                logger.info(plots[target])
                 return 0
 
             divs = [
@@ -138,10 +147,10 @@ def add_parser(subparsers, parent_parser):
         help="Required when CSV or TSV datafile does not have a header.",
     )
     plots_show_parser.add_argument(
-        "--show-json",
+        "--show-vega",
         action="store_true",
         default=False,
-        help="Show output in JSON format.",
+        help="Show output in VEGA format.",
     )
     plots_show_parser.add_argument("--title", default=None, help="Plot title.")
     plots_show_parser.add_argument(
@@ -201,10 +210,10 @@ def add_parser(subparsers, parent_parser):
         help="Provided CSV ot TSV datafile does not have a header.",
     )
     plots_diff_parser.add_argument(
-        "--show-json",
+        "--show-vega",
         action="store_true",
         default=False,
-        help="Show output in JSON format.",
+        help="Show output in VEGA format.",
     )
     plots_diff_parser.add_argument("--title", default=None, help="Plot title.")
     plots_diff_parser.add_argument(
diff --git a/dvc/ignore.py b/dvc/ignore.py
index 9b42c7547..2cc35a816 100644
--- a/dvc/ignore.py
+++ b/dvc/ignore.py
@@ -115,8 +115,12 @@ class DvcIgnoreFilter:
 
 
 class CleanTree(BaseTree):
-    def __init__(self, tree):
+    def __init__(self, tree, tree_root=None):
         self.tree = tree
+        if tree_root:
+            self._tree_root = tree_root
+        else:
+            self._tree_root = self.tree.tree_root
 
     @cached_property
     def dvcignore(self):
@@ -124,7 +128,7 @@ class CleanTree(BaseTree):
 
     @property
     def tree_root(self):
-        return self.tree.tree_root
+        return self._tree_root
 
     def open(self, path, mode="r", encoding="utf-8"):
         if self.isfile(path):
@@ -146,8 +150,11 @@ class CleanTree(BaseTree):
         )
 
     def _valid_dirname(self, path):
-        dirname, basename = os.path.split(os.path.normpath(path))
-        dirs, _ = self.dvcignore(os.path.abspath(dirname), [basename], [])
+        path = os.path.abspath(path)
+        if path == self.tree_root:
+            return True
+        dirname, basename = os.path.split(path)
+        dirs, _ = self.dvcignore(dirname, [basename], [])
         if dirs:
             return True
         return False
diff --git a/dvc/remote/gdrive.py b/dvc/remote/gdrive.py
index 947c37ffb..dfc7b1d5a 100644
--- a/dvc/remote/gdrive.py
+++ b/dvc/remote/gdrive.py
@@ -340,7 +340,7 @@ class GDriveRemote(BaseRemote):
                     "use the `gdrive_user_credentials_file` config\n"
                     "   option if you use multiple GDrive remotes with "
                     "different email accounts.\n\nDetails".format(
-                        item_id, self.path_info, self._credentials_location
+                        item_id, self.path_info, self.credentials_location
                     )
                 ) from exc
             raise
diff --git a/dvc/repo/__init__.py b/dvc/repo/__init__.py
index 32030ea6a..3115bffe2 100644
--- a/dvc/repo/__init__.py
+++ b/dvc/repo/__init__.py
@@ -17,6 +17,7 @@ from dvc.exceptions import (
 from dvc.ignore import CleanTree
 from dvc.path_info import PathInfo
 from dvc.repo.tree import RepoTree
+from dvc.scm.tree import is_working_tree
 from dvc.utils.fs import path_isin
 
 from ..stage.exceptions import StageFileDoesNotExistError, StageNotFound
@@ -133,7 +134,13 @@ class Repo:
 
     @tree.setter
     def tree(self, tree):
-        self._tree = tree if isinstance(tree, CleanTree) else CleanTree(tree)
+        if is_working_tree(tree) or tree.tree_root == self.root_dir:
+            root = None
+        else:
+            root = self.root_dir
+        self._tree = (
+            tree if isinstance(tree, CleanTree) else CleanTree(tree, root)
+        )
         # Our graph cache is no longer valid, as it was based on the previous
         # tree.
         self._reset()
diff --git a/dvc/repo/brancher.py b/dvc/repo/brancher.py
index 0fbf2f403..103737464 100644
--- a/dvc/repo/brancher.py
+++ b/dvc/repo/brancher.py
@@ -48,6 +48,9 @@ def brancher(  # noqa: E302
         if revs:
             for sha, names in group_by(scm.resolve_rev, revs).items():
                 self.tree = scm.get_tree(sha)
-                yield ", ".join(names)
+                # ignore revs that don't contain repo root
+                # (i.e. revs from before a subdir=True repo was init'ed)
+                if self.tree.exists(self.root_dir):
+                    yield ", ".join(names)
     finally:
         self.tree = saved_tree


Test patch:
diff --git a/tests/func/metrics/test_show.py b/tests/func/metrics/test_show.py
index 3ff121f9b..268134984 100644
--- a/tests/func/metrics/test_show.py
+++ b/tests/func/metrics/test_show.py
@@ -1,5 +1,8 @@
+import os
+
 import pytest
 
+from dvc.repo import Repo
 from dvc.repo.metrics.show import NoMetricsError
 
 
@@ -56,3 +59,37 @@ def test_show_branch(tmp_dir, scm, dvc, run_copy_metrics):
         "working tree": {"metrics.yaml": {"foo": 1}},
         "branch": {"metrics.yaml": {"foo": 2}},
     }
+
+
+def test_show_subrepo_with_preexisting_tags(tmp_dir, scm):
+    tmp_dir.gen("foo", "foo")
+    scm.add("foo")
+    scm.commit("init")
+    scm.tag("no-metrics")
+
+    tmp_dir.gen({"subdir": {}})
+    subrepo_dir = tmp_dir / "subdir"
+    with subrepo_dir.chdir():
+        dvc = Repo.init(subdir=True)
+        scm.commit("init dvc")
+
+        dvc.run(
+            cmd="echo foo: 1 > metrics.yaml",
+            metrics=["metrics.yaml"],
+            single_stage=True,
+        )
+
+    scm.add(
+        [
+            str(subrepo_dir / "metrics.yaml"),
+            str(subrepo_dir / "metrics.yaml.dvc"),
+        ]
+    )
+    scm.commit("init metrics")
+    scm.tag("v1")
+
+    expected_path = os.path.join("subdir", "metrics.yaml")
+    assert dvc.metrics.show(all_tags=True) == {
+        "working tree": {expected_path: {"foo": 1}},
+        "v1": {expected_path: {"foo": 1}},
+    }
diff --git a/tests/unit/command/test_plots.py b/tests/unit/command/test_plots.py
index 05b115a02..d1728f514 100644
--- a/tests/unit/command/test_plots.py
+++ b/tests/unit/command/test_plots.py
@@ -13,7 +13,7 @@ def test_metrics_diff(dvc, mocker):
             "template",
             "--targets",
             "datafile",
-            "--show-json",
+            "--show-vega",
             "-x",
             "x_field",
             "-y",
@@ -32,7 +32,9 @@ def test_metrics_diff(dvc, mocker):
     assert cli_args.func == CmdPlotsDiff
 
     cmd = cli_args.func(cli_args)
-    m = mocker.patch("dvc.repo.plots.diff.diff", return_value={})
+    m = mocker.patch(
+        "dvc.repo.plots.diff.diff", return_value={"datafile": "filledtemplate"}
+    )
 
     assert cmd.run() == 0
 
@@ -59,7 +61,7 @@ def test_metrics_show(dvc, mocker):
             "result.extension",
             "-t",
             "template",
-            "--show-json",
+            "--show-vega",
             "--no-csv-header",
             "datafile",
         ]
@@ -68,7 +70,9 @@ def test_metrics_show(dvc, mocker):
 
     cmd = cli_args.func(cli_args)
 
-    m = mocker.patch("dvc.repo.plots.show.show", return_value={})
+    m = mocker.patch(
+        "dvc.repo.plots.show.show", return_value={"datafile": "filledtemplate"}
+    )
 
     assert cmd.run() == 0
 
@@ -85,13 +89,21 @@ def test_metrics_show(dvc, mocker):
     )
 
 
-def test_plots_show_json(dvc, mocker, caplog):
+def test_plots_show_vega(dvc, mocker, caplog):
     cli_args = parse_args(
-        ["plots", "diff", "HEAD~10", "HEAD~1", "--show-json"]
+        [
+            "plots",
+            "diff",
+            "HEAD~10",
+            "HEAD~1",
+            "--show-vega",
+            "--targets",
+            "plots.csv",
+        ]
     )
     cmd = cli_args.func(cli_args)
     mocker.patch(
         "dvc.repo.plots.diff.diff", return_value={"plots.csv": "plothtml"}
     )
     assert cmd.run() == 0
-    assert '{"plots.csv": "plothtml"}\n' in caplog.text
+    assert "plothtml" in caplog.text