From 6bdc2b2a190eb3df3c8a84ce399d64cbb6e80c42 Mon Sep 17 00:00:00 2001 From: Andrew Olsen Date: Thu, 8 Jul 2021 10:57:11 +1200 Subject: [PATCH] Fix for #453 - error writing diff output to file. Added test --- kart/base_diff_writer.py | 15 ++++++++++++++- kart/output_util.py | 8 ++++++-- tests/test_diff.py | 12 ++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/kart/base_diff_writer.py b/kart/base_diff_writer.py index b30c20d07..8f4421c54 100644 --- a/kart/base_diff_writer.py +++ b/kart/base_diff_writer.py @@ -1,5 +1,6 @@ import itertools import logging +from pathlib import Path import re import sys @@ -83,7 +84,9 @@ def __init__( self.all_ds_paths = sorted(list(all_ds_paths)) - self.output_path = self._check_output_path(repo, output_path) + self.output_path = self._check_output_path( + repo, self._normalize_output_path(output_path) + ) self.json_style = json_style self.target_crs = target_crs @@ -97,6 +100,16 @@ def include_target_commit_as_header(self): """ self.commit = self.target_rs.commit + @classmethod + def _normalize_output_path(cls, output_path): + if not output_path or output_path == "-": + return output_path + if isinstance(output_path, str): + output_path = Path(output_path) + if isinstance(output_path, Path): + output_path = output_path.expanduser() + return output_path + @classmethod def _check_output_path(cls, repo, output_path): """Make sure the given output_path is valid for this implementation (ie, are directories supported).""" diff --git a/kart/output_util.py b/kart/output_util.py index 34d5c8f98..a147c134a 100644 --- a/kart/output_util.py +++ b/kart/output_util.py @@ -233,6 +233,11 @@ def resolve_output_path(output_path): * a file-like object * the string '-' or None (both will return sys.stdout) """ + if (not output_path) or output_path == "-": + return sys.stdout + + if isinstance(output_path, str): + output_path = Path(output_path) if isinstance(output_path, Path): output_path = output_path.expanduser() @@ -241,8 +246,7 @@ def resolve_output_path(output_path): # but in some circumstances it can be something else. # e.g. click on windows may wrap it with a colorama.ansitowin32.StreamWrapper. return output_path - elif (not output_path) or output_path == "-": - return sys.stdout + else: return output_path.open("w") diff --git a/tests/test_diff.py b/tests/test_diff.py index 6fe1df248..0ced37c75 100644 --- a/tests/test_diff.py +++ b/tests/test_diff.py @@ -1638,3 +1638,15 @@ def override_get_feature(self, *args, **kwargs): expected_calls += 1 assert old.get_feature_calls == expected_calls assert new.get_feature_calls == expected_calls + + +@pytest.mark.parametrize( + "output_format", [o for o in DIFF_OUTPUT_FORMATS if o not in {"html", "quiet"}] +) +def test_diff_output_to_file(output_format, data_archive, cli_runner): + with data_archive("points") as repo_path: + r = cli_runner.invoke( + ["show", f"--output-format={output_format}", "--output=out"] + ) + assert r.exit_code == 0, r + assert (repo_path / "out").exists()