feat: integrated with typer
This commit is contained in:
parent
5fe565d8aa
commit
7cfede725d
13 changed files with 162 additions and 14 deletions
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
|
@ -2,9 +2,9 @@ name: CI
|
|||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
branches: [ main, dev ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
branches: [ main, dev ]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
|
@ -91,4 +91,4 @@ jobs:
|
|||
run: |
|
||||
pip install pytest
|
||||
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
2
compose_viz/__init__.py
Normal file
|
@ -0,0 +1,2 @@
|
|||
__app_name__ = "compose_viz"
|
||||
__version__ = "0.1.0"
|
9
compose_viz/__main__.py
Normal file
9
compose_viz/__main__.py
Normal 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
59
compose_viz/cli.py
Normal 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
10
compose_viz/compose.py
Normal 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
10
compose_viz/parser.py
Normal 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
13
compose_viz/service.py
Normal 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
0
tests/__init__.py
Normal file
14
tests/test_cli.py
Normal file
14
tests/test_cli.py
Normal 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
29
tests/test_parse_file.py
Normal 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
|
|
@ -1,5 +0,0 @@
|
|||
import sys
|
||||
import pytest
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([sys.argv[1]])
|
13
tests/test_version.py
Normal file
13
tests/test_version.py
Normal 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
|
|
@ -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
|
Loading…
Reference in a new issue