feat: integrated with typer

This commit is contained in:
Xyphuz 2022-05-08 00:42:14 +08:00
parent 5fe565d8aa
commit 7cfede725d
13 changed files with 162 additions and 14 deletions

View file

@ -2,9 +2,9 @@ name: CI
on: on:
push: push:
branches: [ main ] branches: [ main, dev ]
pull_request: pull_request:
branches: [ main ] branches: [ main, dev ]
jobs: jobs:
test: test:
@ -91,4 +91,4 @@ jobs:
run: | run: |
pip install pytest pip install pytest
pip install pytest-cov pip install pytest-cov
python tests/test_validate_input_file.py tests/validate_input_file.py tests/in/docker-compose.yaml pytest

2
compose_viz/__init__.py Normal file
View file

@ -0,0 +1,2 @@
__app_name__ = "compose_viz"
__version__ = "0.1.0"

9
compose_viz/__main__.py Normal file
View file

@ -0,0 +1,9 @@
from compose_viz import cli, __app_name__
def main() -> None:
cli.app(prog_name=__app_name__)
if __name__ == "__main__":
main()

59
compose_viz/cli.py Normal file
View file

@ -0,0 +1,59 @@
from ast import parse
from enum import Enum
import typer
from typing import Optional
from compose_viz import __app_name__, __version__
from compose_viz.compose import Compose
from compose_viz.parser import Parser
class VisualizationFormats(str, Enum):
png = "PNG"
dot = "DOT"
app = typer.Typer(
invoke_without_command=True,
no_args_is_help=True,
subcommand_metavar="",
add_completion=False,
)
def _version_callback(value: bool) -> None:
if value:
typer.echo(f"{__app_name__} {__version__}")
raise typer.Exit()
@app.callback()
def compose_viz(
input_path: str,
output_path: Optional[str] = typer.Option(
None,
"--output_path",
"-o",
help="Output path for the generated visualization.",
),
format: VisualizationFormats = typer.Option(
"PNG",
"--format",
"-m",
help="Output format for the generated visualization.",
),
_: Optional[bool] = typer.Option(
None,
"--version",
"-v",
help="Show the version of compose_viz.",
callback=_version_callback,
is_eager=True,
)
) -> None:
parser = Parser()
compose = parser.parse(input_path)
if compose:
typer.echo(f"Successfully parsed {input_path}")
raise typer.Exit()

10
compose_viz/compose.py Normal file
View file

@ -0,0 +1,10 @@
from typing import List
from compose_viz.service import Service
class Compose:
def __init__(self, services: List[Service]) -> None:
self.services = services
def extract_networks(self) -> List[str]:
raise NotImplementedError

10
compose_viz/parser.py Normal file
View file

@ -0,0 +1,10 @@
from compose_viz.compose import Compose
class Parser:
def __init__(self):
pass
def parse(self, file_path: str) -> Compose:
# validate input file using `docker-compose config -q sys.argv[1]` first
raise NotImplementedError

13
compose_viz/service.py Normal file
View file

@ -0,0 +1,13 @@
from typing import List
class Service:
def __init__(self, name: str, image: str, ports: List[str] = [], networks: List[str] = [], volumes: List[str] = [], depends_on: List[str] = [], links: List[str] = [], extends: List[str] = []) -> None:
self.name = name
self.image = image
self.ports = ports
self.networks = networks
self.volumes = volumes
self.depends_on = depends_on
self.links = links
self.extends = extends

0
tests/__init__.py Normal file
View file

14
tests/test_cli.py Normal file
View file

@ -0,0 +1,14 @@
import pytest
from typer.testing import CliRunner
from compose_viz import cli
runner = CliRunner()
def test_cli():
input_path = "tests/in/000001.yaml"
result = runner.invoke(cli.app, [input_path])
assert result.exit_code == 0
assert f"Successfully parsed {input_path}\n" in result.stdout

29
tests/test_parse_file.py Normal file
View file

@ -0,0 +1,29 @@
from typer.testing import CliRunner
from compose_viz.parser import Parser
from compose_viz.compose import Compose
from compose_viz.service import Service
def test_parse_file():
expected: Compose = Compose([
Service(
name='frontend',
image='awesome/webapp',
networks=['front-tier', 'back-tier'],
),
Service(
name='monitoring',
image='awesome/monitoring',
networks=['admin'],
),
Service(
name='backend',
image='awesome/backend',
networks=['back-tier', 'admin'],
),
])
parser = Parser()
actual = parser.parse('tests/in/000001.yaml')
assert actual == expected

View file

@ -1,5 +0,0 @@
import sys
import pytest
if __name__ == '__main__':
pytest.main([sys.argv[1]])

13
tests/test_version.py Normal file
View file

@ -0,0 +1,13 @@
import pytest
from typer.testing import CliRunner
from compose_viz import cli, __app_name__, __version__
runner = CliRunner()
def test_version():
result = runner.invoke(cli.app, ["--version"])
assert result.exit_code == 0
assert f"{__app_name__} {__version__}\n" in result.stdout

View file

@ -1,6 +0,0 @@
import os
import sys
def test_validate_input_file():
process = os.system("docker-compose -f " + sys.argv[2] + " config -q")
assert process == 0