diff --git a/dvc/commands/plots.py b/dvc/commands/plots.py index a6b0f2cea72..8589db35d28 100644 --- a/dvc/commands/plots.py +++ b/dvc/commands/plots.py @@ -3,7 +3,7 @@ import os from typing import TYPE_CHECKING, Dict, List -from funcy import first +from funcy import compact, first from dvc.cli import completion from dvc.cli.command import CmdBase @@ -24,35 +24,31 @@ def _show_json(renderers_with_errors: List["RendererWithErrors"], split=False): from dvc.utils.serialize import encode_exception errors: List[Dict] = [] - out = {} + data = {} for renderer, src_errors, def_errors in renderers_with_errors: name = renderer.name - out[name] = to_json(renderer, split) - if src_errors: - errors.extend( - { - "name": name, - "revision": rev, - "source": source, - **encode_exception(e), - } - for rev, per_rev_src_errors in src_errors.items() - for source, e in per_rev_src_errors.items() - ) - if def_errors: - errors.extend( - { - "name": name, - "revision": rev, - **encode_exception(e), - } - for rev, e in def_errors.items() - ) + data[name] = to_json(renderer, split) + errors.extend( + { + "name": name, + "revision": rev, + "source": source, + **encode_exception(e), + } + for rev, per_rev_src_errors in src_errors.items() + for source, e in per_rev_src_errors.items() + ) + errors.extend( + { + "name": name, + "revision": rev, + **encode_exception(e), + } + for rev, e in def_errors.items() + ) - if errors: - out = {"errors": errors, **out} - ui.write_json(out, highlight=False) + ui.write_json(compact({"errors": errors, "data": data}), highlight=False) def _adjust_vega_renderers(renderers): diff --git a/tests/func/plots/test_show.py b/tests/func/plots/test_show.py index 0d49745abcf..0a31c7fcf74 100644 --- a/tests/func/plots/test_show.py +++ b/tests/func/plots/test_show.py @@ -418,5 +418,8 @@ def test_show_plots_defined_with_native_os_path(tmp_dir, dvc, scm, capsys): assert main(["plots", "show", "--json"]) == 0 out, _ = capsys.readouterr() json_out = json.loads(out) - assert json_out[f"dvc.yaml::{top_level_plot}"] - assert json_out[stage_plot] + assert "errors" not in json_out + + json_data = json_out["data"] + assert json_data[f"dvc.yaml::{top_level_plot}"] + assert json_data[stage_plot] diff --git a/tests/integration/plots/test_plots.py b/tests/integration/plots/test_plots.py index 5af9385b6b9..3c7b05e91b8 100644 --- a/tests/integration/plots/test_plots.py +++ b/tests/integration/plots/test_plots.py @@ -182,7 +182,13 @@ def test_repo_with_plots(tmp_dir, scm, dvc, capsys, run_copy_metrics, repo_with_ html_path, json_result, split_json_result = call(capsys) html_result = extract_vega_specs(html_path, ["linear.json", "confusion.json"]) - assert json_result["linear.json"][0]["content"]["data"][ + assert "errors" not in json_result + assert "errors" not in split_json_result + + json_data = json_result["data"] + split_json_data = split_json_result["data"] + + assert json_data["linear.json"][0]["content"]["data"][ "values" ] == _update_datapoints( linear_v1, @@ -200,7 +206,7 @@ def test_repo_with_plots(tmp_dir, scm, dvc, capsys, run_copy_metrics, repo_with_ REVISION_FIELD: "workspace", }, ) - assert json_result["confusion.json"][0]["content"]["data"][ + assert json_data["confusion.json"][0]["content"]["data"][ "values" ] == _update_datapoints( confusion_v1, @@ -218,34 +224,40 @@ def test_repo_with_plots(tmp_dir, scm, dvc, capsys, run_copy_metrics, repo_with_ REVISION_FIELD: "workspace", }, ) - verify_image(tmp_dir, "workspace", "image.png", image_v1, html_path, json_result) + verify_image(tmp_dir, "workspace", "image.png", image_v1, html_path, json_data) for plot in ["linear.json", "confusion.json"]: verify_vega( "workspace", html_result[plot], - json_result[plot], - split_json_result[plot], + json_data[plot], + split_json_data[plot], ) - verify_vega_props("confusion.json", json_result, **confusion_props) + verify_vega_props("confusion.json", json_data, **confusion_props) image_v2, linear_v2, confusion_v2, confusion_props = next(repo_state) html_path, json_result, split_json_result = call(capsys, subcommand="diff") html_result = extract_vega_specs(html_path, ["linear.json", "confusion.json"]) - verify_image(tmp_dir, "workspace", "image.png", image_v2, html_path, json_result) - verify_image(tmp_dir, "HEAD", "image.png", image_v1, html_path, json_result) + assert "errors" not in json_result + assert "errors" not in split_json_result + + json_data = json_result["data"] + split_json_data = split_json_result["data"] + + verify_image(tmp_dir, "workspace", "image.png", image_v2, html_path, json_data) + verify_image(tmp_dir, "HEAD", "image.png", image_v1, html_path, json_data) for plot in ["linear.json", "confusion.json"]: verify_vega( ["HEAD", "workspace"], html_result[plot], - json_result[plot], - split_json_result[plot], + json_data[plot], + split_json_data[plot], ) - verify_vega_props("confusion.json", json_result, **confusion_props) + verify_vega_props("confusion.json", json_data, **confusion_props) path = tmp_dir / "subdir" path.mkdir() with path.chdir(): @@ -254,7 +266,13 @@ def test_repo_with_plots(tmp_dir, scm, dvc, capsys, run_copy_metrics, repo_with_ html_path, ["../linear.json", "../confusion.json"], ) - assert json_result["../linear.json"][0]["content"]["data"][ + + assert "errors" not in json_result + assert "errors" not in split_json_result + + json_data = json_result["data"] + split_json_data = split_json_result["data"] + assert json_data["../linear.json"][0]["content"]["data"][ "values" ] == _update_datapoints( linear_v2, @@ -286,7 +304,7 @@ def test_repo_with_plots(tmp_dir, scm, dvc, capsys, run_copy_metrics, repo_with_ REVISION_FIELD: "HEAD", }, ) - assert json_result["../confusion.json"][0]["content"]["data"][ + assert json_data["../confusion.json"][0]["content"]["data"][ "values" ] == _update_datapoints( confusion_v2, @@ -326,8 +344,8 @@ def test_repo_with_plots(tmp_dir, scm, dvc, capsys, run_copy_metrics, repo_with_ verify_vega( ["HEAD", "workspace"], html_result[plot], - json_result[plot], - split_json_result[plot], + json_data[plot], + split_json_data[plot], ) verify_image( path, @@ -335,7 +353,7 @@ def test_repo_with_plots(tmp_dir, scm, dvc, capsys, run_copy_metrics, repo_with_ "../image.png", image_v2, html_path, - json_result, + json_data, ) verify_image( path, @@ -343,7 +361,7 @@ def test_repo_with_plots(tmp_dir, scm, dvc, capsys, run_copy_metrics, repo_with_ "../image.png", image_v1, html_path, - json_result, + json_data, ) @@ -377,9 +395,11 @@ def test_repo_with_removed_plots(tmp_dir, capsys, repo_with_plots): ] expected_result = { "errors": errors, - "image.png": [], - "confusion.json": [], - "linear.json": [], + "data": { + "image.png": [], + "confusion.json": [], + "linear.json": [], + }, } assert json_result == expected_result assert split_json_result == expected_result