Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --json-style option for diff/show #70

Merged
merged 1 commit into from
May 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions sno/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,9 @@ def get_dataset_diff(base_rs, target_rs, working_copy, dataset_path, pk_filter):
return diff


def diff_with_writer(ctx, diff_writer, *, output_path='-', exit_code, args):
def diff_with_writer(
ctx, diff_writer, *, output_path='-', exit_code, args, json_style="pretty"
):
"""
Calculates the appropriate diff from the arguments,
and writes it using the given writer contextmanager.
Expand Down Expand Up @@ -461,6 +463,7 @@ def diff_with_writer(ctx, diff_writer, *, output_path='-', exit_code, args):
"target": target_rs,
"output_path": output_path,
"dataset_count": len(all_datasets),
"json_style": json_style,
}

L.debug(
Expand Down Expand Up @@ -558,8 +561,16 @@ def diff_with_writer(ctx, diff_writer, *, output_path='-', exit_code, args):
help="Output to a specific file/directory instead of stdout.",
type=click.Path(writable=True, allow_dash=True),
)
@click.option(
"--json-style",
type=click.Choice(["extracompact", "compact", "pretty"]),
default="pretty",
help="How to format the output. Only used with --json or --geojson",
cls=MutexOption,
exclusive_with=["html", "text", "quiet"],
)
@click.argument("args", nargs=-1)
def diff(ctx, output_format, output_path, exit_code, args):
def diff(ctx, output_format, output_path, exit_code, json_style, args):
"""
Show changes between commits, commit and working tree, etc

Expand All @@ -573,5 +584,10 @@ def diff(ctx, output_format, output_path, exit_code, args):
exit_code = True

return diff_with_writer(
ctx, diff_writer, output_path=output_path, exit_code=exit_code, args=args,
ctx,
diff_writer,
output_path=output_path,
exit_code=exit_code,
args=args,
json_style=json_style,
)
10 changes: 6 additions & 4 deletions sno/diff_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def repr_row(row, prefix="", exclude=None):


@contextlib.contextmanager
def diff_output_geojson(*, output_path, dataset_count, **kwargs):
def diff_output_geojson(*, output_path, dataset_count, json_style, **kwargs):
"""
Contextmanager.

Expand Down Expand Up @@ -221,13 +221,13 @@ def _out(dataset, diff):
fc["features"].append(_json_row(v_old, "U-", pk_field))
fc["features"].append(_json_row(v_new, "U+", pk_field))

dump_json_output(fc, fp)
dump_json_output(fc, fp, json_style=json_style)

yield _out


@contextlib.contextmanager
def diff_output_json(*, output_path, dataset_count, **kwargs):
def diff_output_json(*, output_path, dataset_count, json_style="pretty", **kwargs):
"""
Contextmanager.
Yields a callable which can be called with dataset diffs
Expand Down Expand Up @@ -277,7 +277,9 @@ def _out(dataset, diff):

yield _out

dump_json_output({"sno.diff/v1": accumulated}, output_path)
dump_json_output(
{"sno.diff/v1": accumulated}, output_path, json_style=json_style
)


def _json_row(row, change, pk_field):
Expand Down
17 changes: 10 additions & 7 deletions sno/output_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,31 @@
import json
import sys

JSON_PARAMS = {
"compact": {},
"pretty": {"indent": 2, "sort_keys": True},
"extracompact": {"separators": (',', ':')},
}

def dump_json_output(output, output_path, pretty=True):

def dump_json_output(output, output_path, json_style="pretty"):
"""
Dumps the output to JSON in the output file.
"""

fp = resolve_output_path(output_path)

json_params = {}
if pretty:
json_params.update({"indent": 2, "sort_keys": True})
if pretty and fp == sys.stdout and fp.isatty():
if json_style == 'pretty' and fp == sys.stdout and fp.isatty():
# Add syntax highlighting
from pygments import highlight
from pygments.lexers import JsonLexer
from pygments.formatters import TerminalFormatter

dumped = json.dumps(output, **json_params)
dumped = json.dumps(output, **JSON_PARAMS[json_style])
highlighted = highlight(dumped.encode(), JsonLexer(), TerminalFormatter())
fp.write(highlighted)
else:
json.dump(output, fp, **json_params)
json.dump(output, fp, **JSON_PARAMS[json_style])


def resolve_output_path(output_path):
Expand Down
24 changes: 19 additions & 5 deletions sno/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,16 @@
cls=MutexOption,
exclusive_with=["text"],
)
@click.option(
"--json-style",
type=click.Choice(["extracompact", "compact", "pretty"]),
default="pretty",
help="How to format the output. Only used with --json",
cls=MutexOption,
exclusive_with=["text"],
)
@click.argument("refish", default='HEAD', required=False)
def show(ctx, *, refish, output_format, **kwargs):
def show(ctx, *, refish, output_format, json_style, **kwargs):
"""
Show the given commit, or HEAD
"""
Expand All @@ -50,7 +58,11 @@ def show(ctx, *, refish, output_format, **kwargs):
patch_writer = globals()[f"patch_output_{output_format}"]

return diff.diff_with_writer(
ctx, patch_writer, exit_code=False, args=[f"{refish}^..{refish}"],
ctx,
patch_writer,
exit_code=False,
args=[f"{refish}^..{refish}"],
json_style=json_style,
)


Expand Down Expand Up @@ -99,7 +111,7 @@ def patch_output_text(*, target, output_path, **kwargs):


@contextlib.contextmanager
def patch_output_json(*, target, output_path, **kwargs):
def patch_output_json(*, target, output_path, json_style, **kwargs):
"""
Contextmanager.

Expand All @@ -125,7 +137,9 @@ def patch_output_json(*, target, output_path, **kwargs):
buf = StringIO()

output_path, original_output_path = buf, output_path
with diff.diff_output_json(output_path=output_path, **kwargs) as diff_writer:
with diff.diff_output_json(
output_path=output_path, json_style=json_style, **kwargs
) as diff_writer:
yield diff_writer

# At this point, the diff_writer has been used, meaning the StringIO has
Expand All @@ -145,4 +159,4 @@ def patch_output_json(*, target, output_path, **kwargs):
"message": commit.message,
}

dump_json_output(output, original_output_path)
dump_json_output(output, original_output_path, json_style=json_style)
9 changes: 9 additions & 0 deletions tests/test_diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -1747,3 +1747,12 @@ def test_show_points_HEAD(output_format, data_archive_readonly, cli_runner):
'authorTimeOffset': '+01:00',
'message': 'Improve naming on Coromandel East coast',
}


def test_show_json_format(data_archive_readonly, cli_runner):
with data_archive_readonly("points"):
r = cli_runner.invoke(["show", f"--json", "--json-style=compact", "HEAD"])

assert r.exit_code == 0, r
# output is compact, no indentation
assert '"sno.diff/v1": {"' in r.stdout