Skip to content

Commit

Permalink
Update CLI to use JSON as default output format
Browse files Browse the repository at this point in the history
[Resolves #708], [Resolves #672]
  • Loading branch information
ngfgrant committed Jun 13, 2019
1 parent 9657c65 commit f2689ab
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 23 deletions.
2 changes: 1 addition & 1 deletion sceptre/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
@click.option("--debug", is_flag=True, help="Turn on debug logging.")
@click.option("--dir", "directory", help="Specify sceptre directory.")
@click.option(
"--output", type=click.Choice(["text", "yaml", "json"]), default="text",
"--output", type=click.Choice(["text", "yaml", "json"]), default="json",
help="The formatting style for command output.")
@click.option("--no-colour", is_flag=True, help="Turn off output colouring.")
@click.option(
Expand Down
2 changes: 1 addition & 1 deletion sceptre/cli/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def confirmation(
click.confirm(msg, abort=True)


def write(var, output_format="text", no_colour=True):
def write(var, output_format="json", no_colour=True):
"""
Writes ``var`` to stdout. If output_format is set to "json" or "yaml",
write ``var`` as a JSON or YAML string.
Expand Down
6 changes: 3 additions & 3 deletions sceptre/cli/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ def list_outputs(ctx, path, export):
for stack in response.values():
for output in stack:
write("export SCEPTRE_{0}='{1}'".format(
output.get("OutputKey"),
output.get("OutputValue")
), 'str')
output.get("OutputKey"),
output.get("OutputValue")
), 'text')
else:
write(responses, context.output_format)

Expand Down
2 changes: 1 addition & 1 deletion sceptre/cli/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,4 @@ def estimate_cost_command(ctx, path):
click.echo("View the estimated cost for {} at:".format(stack.name))
response = response["Url"]
webbrowser.open(response, new=2)
write(response + "\n", 'str')
write(response + "\n", 'text')
36 changes: 19 additions & 17 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import datetime
import os
import errno
import json

from click.testing import CliRunner
from mock import MagicMock, patch, sentinel
Expand Down Expand Up @@ -130,11 +131,12 @@ def test_validate_template_with_valid_template(self):
"HTTPStatusCode": 200
}
}

result_json = json.dumps({'Parameters': 'Example'}, indent=4)
result = self.runner.invoke(cli, ["validate", "dev/vpc.yaml"])
self.mock_stack_actions.validate.assert_called_with()

assert result.output == "Template mock-stack is valid. Template details:\n\n" \
"{'Parameters': 'Example'}\n"
assert result.output == "Template mock-stack is valid. Template details:\n\n{}\n".format(
result_json)

def test_validate_template_with_invalid_template(self):
client_error = ClientError(
Expand All @@ -151,7 +153,7 @@ def test_validate_template_with_invalid_template(self):

expected_result = str(client_error) + "\n"
result = self.runner.invoke(cli, ["validate", "dev/vpc.yaml"])
assert expected_result in result.output
assert expected_result in result.output.replace("\"", "")

def test_estimate_template_cost_with_browser(self):
self.mock_stack_actions.estimate_cost.return_value = {
Expand Down Expand Up @@ -182,13 +184,12 @@ def test_estimate_template_cost_with_no_browser(self):
"Webbrowser"
)
self.mock_stack_actions.estimate_cost.side_effect = client_error

expected_result = str(client_error) + "\n"
expected_result = "{}\n".format(client_error)
result = self.runner.invoke(
cli,
["estimate-cost", "dev/vpc.yaml"]
)
assert expected_result in result.output
assert expected_result in result.output.replace("\"", "")

def test_lock_stack(self):
self.runner.invoke(
Expand Down Expand Up @@ -220,7 +221,8 @@ def test_describe_policy_with_existing_policy(self):
cli, ["describe", "policy", "dev/vpc.yaml"]
)
assert result.exit_code == 0
assert result.output == "{'dev/vpc': {'Statement': ['Body']}}\n"
assert result.output == "{}\n".format(json.dumps(
{'dev/vpc': {'Statement': ['Body']}}, indent=4))

def test_list_group_resources(self):
response = {
Expand Down Expand Up @@ -401,22 +403,22 @@ def test_list_change_sets_without_200(self):
assert yaml.safe_load(result.output) == response

def test_list_outputs(self):
outputs = [{"OutputKey": "Key", "OutputValue": "Value"}]
outputs = {"OutputKey": "Key", "OutputValue": "Value"}
self.mock_stack_actions.describe_outputs.return_value = outputs
result = self.runner.invoke(
cli, ["list", "outputs", "dev/vpc.yaml"]
)
assert result.exit_code == 0
assert yaml.safe_load(result.output) == [outputs]
assert json.loads(result.output) == [outputs]

def test_list_outputs_with_export(self):
outputs = {'stack': [{"OutputKey": "Key", "OutputValue": "Value"}]}
outputs = {'stack': [{'OutputKey': 'Key', 'OutputValue': 'Value'}]}
self.mock_stack_actions.describe_outputs.return_value = outputs
result = self.runner.invoke(
cli, ["list", "outputs", "dev/vpc.yaml", "-e", "envvar"]
)
assert result.exit_code == 0
assert yaml.safe_load(result.output) == "export SCEPTRE_Key='Value'"
assert result.output == "export SCEPTRE_Key='Value'\n"

def test_status_with_group(self):
self.mock_stack_actions.get_status.return_value = {
Expand All @@ -425,13 +427,13 @@ def test_status_with_group(self):

result = self.runner.invoke(cli, ["status", "dev"])
assert result.exit_code == 0
assert result.output == "mock-stack: {'stack': 'status'}\n"
assert result.output == '"mock-stack: {\'stack\': \'status\'}"\n'

def test_status_with_stack(self):
self.mock_stack_actions.get_status.return_value = "status"
result = self.runner.invoke(cli, ["status", "dev/vpc.yaml"])
assert result.exit_code == 0
assert result.output == "mock-stack: status\n"
assert result.output == '"mock-stack: status"\n'

def test_new_project_non_existant(self):
with self.runner.isolated_filesystem():
Expand Down Expand Up @@ -472,7 +474,7 @@ def test_new_project_already_exist(self):

result = self.runner.invoke(cli, ["new", "project", "example"])
assert result.exit_code == 1
assert result.output == 'Folder \"example\" already exists.\n'
assert result.output == '"Folder \\"example\\" already exists."\n'
assert os.path.isdir(config_dir)
assert os.path.isdir(template_dir)

Expand Down Expand Up @@ -683,13 +685,13 @@ def test_write_formats(
def test_write_status_with_colour(self, mock_echo):
write("stack: CREATE_COMPLETE", no_colour=False)
mock_echo.assert_called_once_with(
"stack: \x1b[32mCREATE_COMPLETE\x1b[0m"
'"stack: \x1b[32mCREATE_COMPLETE\x1b[0m"'
)

@patch("sceptre.cli.click.echo")
def test_write_status_without_colour(self, mock_echo):
write("stack: CREATE_COMPLETE", no_colour=True)
mock_echo.assert_called_once_with("stack: CREATE_COMPLETE")
mock_echo.assert_called_once_with('"stack: CREATE_COMPLETE"')

@patch("sceptre.cli.helpers.StackStatusColourer.colour")
@patch("sceptre.cli.helpers.logging.Formatter.format")
Expand Down

0 comments on commit f2689ab

Please sign in to comment.