Skip to content

Commit

Permalink
Adds a basic CLI for converting recipe files
Browse files Browse the repository at this point in the history
- Usage: `percy convert [-o output] FILE`
- Error and warning messages dump to `STDERR` by default (like `curl` does)
- By default the converted recipe is dumped to `STDOUT`. The `-o` option allows
  the user to specify an output file.
  • Loading branch information
schuylermartin45 committed Jan 31, 2024
1 parent 8b6aae4 commit 96062ee
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 3 deletions.
5 changes: 2 additions & 3 deletions .pytest.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# This surpresses deprecation `pytest` warnings related to using `conda.*` packages.
# TODO Future: remove/upgrade deprecated packages
[pytest]
filterwarnings =
ignore:conda.* is pending deprecation:PendingDeprecationWarning
ignore:conda.* is deprecated:DeprecationWarning
ignore::DeprecationWarning
ignore::PendingDeprecationWarning
69 changes: 69 additions & 0 deletions percy/commands/convert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"""
File: convert.py
Description: CLI for converting an old recipe file to the "new" format.
"""
from __future__ import annotations

import os
import sys
from typing import Final

import click

from percy.parser.recipe_parser import RecipeParser
from percy.parser.types import MessageCategory, MessageTable

# Required file name for the recipe, specified in CEP-13
NEW_FORMAT_RECIPE_FILE_NAME: Final[str] = "recipe.yaml"


def print_out(*args, **kwargs):
"""
Convenience wrapper that prints to STDOUT
"""
print(*args, file=sys.stdout, **kwargs)


def print_err(*args, **kwargs):
"""
Convenience wrapper that prints to STDERR
"""
print(*args, file=sys.stderr, **kwargs)


def print_messages(category: MessageCategory, msg_tbl: MessageTable):
"""
Convenience function for dumping a series of messages of a certain category
:param category: Category of messages to print
:param msg_tbl: `MessageTable` instance containing the messages to print
"""
msgs: Final[list[str]] = msg_tbl.get_messages(category)
for msg in msgs:
print_err(f"[{category.upper()}]: {msg}")


@click.command(short_help="Converts a `meta.yaml` formatted-recipe file to the new `recipe.yaml` format")
@click.argument("file", type=click.File("r", encoding="utf-8"))
@click.option("--output", "-o", type=click.Path(exists=False), default=None, help="File to dump a new recipe to.")
def convert(file: click.File, output: click.Path) -> None: # pylint: disable=redefined-outer-name
"""
Recipe conversion CLI utility. By default, recipes print to STDOUT. Messages always print to STDERR.
"""
recipe_content: Final[str] = file.read()

parser = RecipeParser(recipe_content)
result, msg_tbl = parser.render_to_new_recipe_format()

if output is None:
print_out(result)
else:
if not os.path.basename(output) == "recipe.yaml":
print_err("WARNING: File is not called `recipe.yaml`.")
with open(output, "w", encoding="utf-8") as fptr:
fptr.write(result)

summary: Final[str] = msg_tbl.get_totals_message()
if summary:
print_messages(MessageCategory.WARNING, msg_tbl)
print_messages(MessageCategory.ERROR, msg_tbl)
print_err(summary)
2 changes: 2 additions & 0 deletions percy/commands/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import click

from percy.commands.aggregate import aggregate
from percy.commands.convert import convert
from percy.commands.recipe import recipe


Expand All @@ -21,6 +22,7 @@ def cli() -> None:
# add subcommands
cli.add_command(recipe)
cli.add_command(aggregate)
cli.add_command(convert)


@cli.command()
Expand Down
22 changes: 22 additions & 0 deletions percy/tests/commands/test_convert_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""
File: test_convert_cli.py
Description: Tests the `convert` CLI
"""
from click.testing import CliRunner

from percy.commands.convert import convert


def test_usage() -> None:
"""
Ensure failure to provide a sub-command results in rendering the help menu
"""
runner = CliRunner()
# No commands are provided
result = runner.invoke(convert, [])
assert result.exit_code != 0
assert result.output.startswith("Usage:")
# Help is specified
result = runner.invoke(convert, ["--help"])
assert result.exit_code == 0
assert result.output.startswith("Usage:")

0 comments on commit 96062ee

Please sign in to comment.