Skip to content

Commit

Permalink
Merge pull request #10 from MAK-Relic-Tool/cli-support
Browse files Browse the repository at this point in the history
Adds SGA support to the command line interface
Unpacking:
`relic sga unpack src_file out_dir`

Packing:
`relic sga pack {vX} -h` where vX is the version of SGA to pack. `-h` will print the commands help, which will ispecify how to run that SGA's packer.
  • Loading branch information
ModernMAK authored Oct 15, 2023
2 parents 2add115 + 4866ee5 commit 1850c19
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 2 deletions.
9 changes: 8 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ classifiers =
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
License :: OSI Approved :: GNU General Public License v3 (GPLv3)

[options]
Expand All @@ -24,13 +25,19 @@ python_requires = >=3.9

install_requires =
mak-serialization-tools >= 2022.0a19
relic-tool-core
relic-tool-core >= 1.1.1
fs

[options.entry_points]
fs.opener =
sga = relic.sga.core.filesystem:EssenceFSOpener

relic.cli =
sga = relic.sga.core.cli:RelicSgaCli

relic.cli.sga =
unpack = relic.sga.core.cli:RelicSgaUnpackCli
pack = relic.sga.core.cli:RelicSgaPackCli

[options.packages.find]
where = src
2 changes: 1 addition & 1 deletion src/relic/sga/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
"""
from relic.sga.core.definitions import Version, MagicWord, StorageType, VerificationType

__version__ = "1.0.1"
__version__ = "1.1.0"
66 changes: 66 additions & 0 deletions src/relic/sga/core/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from __future__ import annotations

from argparse import ArgumentParser, Namespace
from typing import Optional

import fs.copy
from fs.base import FS
from relic.core.cli import CliPluginGroup, _SubParsersAction, CliPlugin


class RelicSgaCli(CliPluginGroup):
GROUP = "relic.cli.sga"

def _create_parser(
self, command_group: Optional[_SubParsersAction] = None
) -> ArgumentParser:
if command_group is None:
return ArgumentParser("sga")
else:
return command_group.add_parser("sga")


class RelicSgaUnpackCli(CliPlugin):
def _create_parser(
self, command_group: Optional[_SubParsersAction] = None
) -> ArgumentParser:
parser: ArgumentParser
if command_group is None:
parser = ArgumentParser("unpack")
else:
parser = command_group.add_parser("unpack")

parser.add_argument("src_sga", type=str, help="Source SGA File")
parser.add_argument("out_dir", type=str, help="Output Directory")

return parser

def command(self, ns: Namespace) -> Optional[int]:
infile: str = ns.src_sga
outdir: str = ns.out_dir

print(f"Unpacking `{infile}`")

def _callback(_1: FS, srcfile: str, _2: FS, _3: str) -> None:
print(f"\t\tUnpacking File `{srcfile}`")

fs.copy.copy_fs(f"sga://{infile}", f"osfs://{outdir}", on_copy=_callback)

return None # To shut-up mypy


class RelicSgaPackCli(CliPluginGroup):
GROUP = "relic.cli.sga.pack"

def _create_parser(
self, command_group: Optional[_SubParsersAction] = None
) -> ArgumentParser:
parser: ArgumentParser
if command_group is None:
parser = ArgumentParser("pack")
else:
parser = command_group.add_parser("pack")

# pack further delegates to version plugins

return parser
44 changes: 44 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import io
import subprocess

# Local testing requires running `pip install -e "."`
from contextlib import redirect_stdout
from typing import Sequence

import pytest


class CommandTests:
def test_run(self, args: Sequence[str], output: str, exit_code: int):
_args = ["relic", *args]
cmd = subprocess.run(_args, capture_output=True, text=True)
result = cmd.stdout
status = cmd.returncode
print(f"'{result}'") # Visual Aid for Debugging
assert output in result
assert status == exit_code

def test_run_with(self, args: Sequence[str], output: str, exit_code: int):
from relic.core.cli import cli_root

with io.StringIO() as f:
with redirect_stdout(f):
status = cli_root.run_with(*args)
f.seek(0)
result = f.read()
print(f"'{result}'") # Visual Aid for Debugging
assert output in result
assert status == exit_code


_SGA_HELP = ["sga", "-h"], """usage: relic sga [-h] {pack,unpack} ...""", 0
_SGA_PACK_HELP = ["sga", "pack", "-h"], """usage: relic sga pack [-h] {} ...""", 0
_SGA_UNPACK_HELP = ["sga", "unpack", "-h"], """usage: relic sga unpack [-h]""", 0

_TESTS = [_SGA_HELP, _SGA_PACK_HELP, _SGA_UNPACK_HELP]
_TEST_IDS = [" ".join(_[0]) for _ in _TESTS]


@pytest.mark.parametrize(["args", "output", "exit_code"], _TESTS, ids=_TEST_IDS)
class TestRelicSgaCli(CommandTests):
...

0 comments on commit 1850c19

Please sign in to comment.