Skip to content

Commit

Permalink
Refine CLI for use with get_table as almanack <repo path> (#136)
Browse files Browse the repository at this point in the history
* work towards get table cli

* add tests and adjust cli

* correct docstring

Co-Authored-By: Gregory Way <[email protected]>

* updates to subprocess test util

Co-Authored-By: Gregory Way <[email protected]>
Co-Authored-By: Faisal Alquaddoomi <[email protected]>

* serialize via json.dumps with python-fire

Co-Authored-By: Faisal Alquaddoomi <[email protected]>

---------

Co-authored-by: Gregory Way <[email protected]>
Co-authored-by: Faisal Alquaddoomi <[email protected]>
  • Loading branch information
3 people authored Nov 12, 2024
1 parent f35a001 commit 906da2b
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 27 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jsonschema = "^4.23.0"
sbomdiff = "^0.5.6"

[tool.poetry.scripts]
almanack = "almanack.reporting.cli:trigger"
almanack = "almanack.cli:cli_get_table"

[tool.poetry-dynamic-versioning]
enable = true
Expand Down
29 changes: 29 additions & 0 deletions src/almanack/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""
Setup almanack CLI through python-fire
"""

import json

import fire

from .metrics.data import get_table


def cli_get_table() -> None:
"""
Creates Fire CLI for get_table_json_wrapper.
This enables the use of CLI such as:
`almanck <repo path>`
"""
fire.Fire(component=get_table, serialize=json.dumps)


if __name__ == "__main__":
"""
Setup the CLI with python-fire for the almanack package.
This allows the function `check` to be ran through the
command line interface.
"""
cli_get_table()
4 changes: 2 additions & 2 deletions src/almanack/metrics/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import shutil
import tempfile
from datetime import datetime, timezone
from typing import Any, Dict, Optional, Tuple
from typing import Any, Dict, List, Optional, Tuple

import pygit2
import yaml
Expand All @@ -20,7 +20,7 @@
METRICS_TABLE = f"{pathlib.Path(__file__).parent!s}/metrics.yml"


def get_table(repo_path: str) -> Dict[str, Any]:
def get_table(repo_path: str) -> List[Dict[str, Any]]:
"""
Gather metrics on a repository and return the results in a structured format.
Expand Down
24 changes: 0 additions & 24 deletions src/almanack/reporting/cli.py

This file was deleted.

56 changes: 56 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""
Tests CLI functionality.
"""

import json

import yaml

from almanack.metrics.data import METRICS_TABLE
from tests.data.almanack.repo_setup.create_repo import repo_setup

from .utils import run_cli_command


def test_cli_util():
"""
Test the run_cli_command for successful output
"""

_, _, returncode = run_cli_command(["echo", "'hello world'"])

assert returncode == 0


def test_cli_almanack(tmp_path):
"""
Tests running `almanack` as a CLI
"""

# create a repo with a single file and commit
repo = repo_setup(repo_path=tmp_path, files={"example.txt": "example"})

# gather output and return code from running a CLI command
stdout, _, returncode = run_cli_command(command=["almanack", repo.path])

# make sure we return 0 on success
assert returncode == 0

# gather result of CLI as json
results = json.loads(stdout)

# make sure we have a list of output
assert isinstance(results, list)

# open the metrics table
with open(METRICS_TABLE, "r") as f:
metrics_table = yaml.safe_load(f)

# check that all keys exist in the output from metrics table to cli str
assert all(
x == y
for x, y in zip(
sorted([result["name"] for result in results]),
sorted([metric["name"] for metric in metrics_table["metrics"]]),
)
)
16 changes: 16 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""

import subprocess
from typing import Tuple


def check_subproc_run_for_nonzero(completed_proc: subprocess.CompletedProcess) -> None:
Expand All @@ -17,3 +18,18 @@ def check_subproc_run_for_nonzero(completed_proc: subprocess.CompletedProcess) -
except Exception as exc:
# raise the exception with decoded output from linkchecker for readability
raise Exception(completed_proc.stdout.decode()) from exc


def run_cli_command(command: str) -> Tuple[str, str, int]:
"""
Run a CLI command using subprocess and capture the output and return code.
Args:
command (list): The command to run as a list of strings.
Returns:
tuple: (str: stdout, str: stderr, int: returncode)
"""

result = subprocess.run(args=command, capture_output=True, text=True, check=False)
return result.stdout, result.stderr, result.returncode

0 comments on commit 906da2b

Please sign in to comment.