diff --git a/dvc/commands/plots.py b/dvc/commands/plots.py index 1f0f88209..b471bd229 100644 --- a/dvc/commands/plots.py +++ b/dvc/commands/plots.py @@ -223,31 +223,22 @@ class CmdPlotsModify(CmdPlots): class CmdPlotsTemplates(CmdBase): - TEMPLATES_CHOICES = [ - "simple", - "linear", - "confusion", - "confusion_normalized", - "scatter", - "smooth", - "bar_horizontal_sorted", - "bar_horizontal", - ] - def run(self): - from dvc_render.vega_templates import dump_templates + from dvc.exceptions import InvalidArgumentError + from dvc_render.vega_templates import TEMPLATES try: - out = ( - os.path.join(os.getcwd(), self.args.out) - if self.args.out - else self.repo.plots.templates_dir - ) + target = self.args.template + if target: + for template in TEMPLATES: + if target == template.DEFAULT_NAME: + ui.write(json.dumps(template.DEFAULT_CONTENT)) + return 0 + raise InvalidArgumentError(f"Unexpected template: {target}.") - targets = [self.args.target] if self.args.target else None - dump_templates(output=out, targets=targets) - templates_path = os.path.relpath(out, os.getcwd()) - ui.write(f"Templates have been written into '{templates_path}'.") + else: + for template in TEMPLATES: + ui.write(template.DEFAULT_NAME) return 0 except DvcException: @@ -357,8 +348,7 @@ def add_parser(subparsers, parent_parser): plots_modify_parser.set_defaults(func=CmdPlotsModify) TEMPLATES_HELP = ( - "Write built-in plots templates to a directory " - "(.dvc/plots by default)." + "List built-in plots templates or show JSON specification for one." ) plots_templates_parser = plots_subparsers.add_parser( "templates", @@ -368,13 +358,14 @@ def add_parser(subparsers, parent_parser): formatter_class=argparse.RawDescriptionHelpFormatter, ) plots_templates_parser.add_argument( - "target", + "template", default=None, nargs="?", - choices=CmdPlotsTemplates.TEMPLATES_CHOICES, - help="Template to write. Writes all templates by default.", + help=( + "Template for which to show JSON specification. " + "List all template names by default." + ), ) - _add_output_argument(plots_templates_parser, typ="templates") plots_templates_parser.set_defaults(func=CmdPlotsTemplates) diff --git a/tests/unit/command/test_plots.py b/tests/unit/command/test_plots.py index d9ba1a4f3..753cc25e6 100644 --- a/tests/unit/command/test_plots.py +++ b/tests/unit/command/test_plots.py @@ -4,7 +4,6 @@ import posixpath from pathlib import Path import pytest -from funcy import pluck_attr from dvc.cli import parse_args from dvc.commands.plots import CmdPlotsDiff, CmdPlotsShow, CmdPlotsTemplates @@ -348,39 +347,38 @@ def test_plots_diff_json(dvc, mocker, capsys): render_mock.assert_not_called() -@pytest.mark.parametrize("target", (("t1"), (None))) -def test_plots_templates(tmp_dir, dvc, mocker, capsys, target): - assert not os.path.exists(dvc.plots.templates_dir) - mocker.patch( - "dvc.commands.plots.CmdPlotsTemplates.TEMPLATES_CHOICES", - ["t1", "t2"], - ) +@pytest.mark.parametrize( + "target,expected_out,expected_rtn", + (("t1", "\"{'t1'}\"", 0), (None, "t1\nt2", 0), ("t3", "", 1)), +) +def test_plots_templates( + dvc, mocker, capsys, target, expected_out, expected_rtn +): + t1 = mocker.Mock() + t1.DEFAULT_NAME = "t1" + t1.DEFAULT_CONTENT = "{'t1'}" - arguments = ["plots", "templates", "--out", "output"] + t2 = mocker.Mock() + t2.DEFAULT_NAME = "t2" + t2.DEFAULT_CONTENT = "{'t2'}" + + mocker.patch("dvc_render.vega_templates.TEMPLATES", [t1, t2]) + + arguments = ["plots", "templates"] if target: arguments += [target] cli_args = parse_args(arguments) assert cli_args.func == CmdPlotsTemplates - dump_mock = mocker.patch("dvc_render.vega_templates.dump_templates") cmd = cli_args.func(cli_args) - assert cmd.run() == 0 + rtn = cmd.run() + out, _ = capsys.readouterr() - dump_mock.assert_called_once_with( - output=os.path.abspath("output"), targets=[target] if target else None - ) - assert "Templates have been written into 'output'." in out - - -def test_plots_templates_choices(tmp_dir, dvc): - from dvc_render import TEMPLATES - - assert CmdPlotsTemplates.TEMPLATES_CHOICES == list( - pluck_attr("DEFAULT_NAME", TEMPLATES) - ) + assert out.strip() == expected_out + assert rtn == expected_rtn @pytest.mark.parametrize("split", (True, False))