From f2d0ce0d22d011aaa44098bee9af9fec81a79310 Mon Sep 17 00:00:00 2001 From: Xyphuz Date: Tue, 10 Jan 2023 22:31:59 +0800 Subject: [PATCH 1/3] chore: update doc of --root-service --- README.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 327fd3f..11cc93e 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,9 @@ You need to install [Graphviz](https://graphviz.org/download/) to generate graph #### Using `pip` -`pip install compose-viz` +``` +pip install compose-viz +``` #### Using `.whl` @@ -115,13 +117,13 @@ Check out the result [here](https://github.com/compose-viz/compose-viz/blob/main ### Options -| Option | Description | -| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `-o, --output-filename` | Output filename for the generated visualization file. [default: compose-viz] | -| `-m, --format` | Output format for the generated visualization file. See [supported formats](https://github.com/compose-viz/compose-viz/blob/main/compose_viz/models/viz_formats.py). [default: png] | -| `-r, --root-service` | Root of the service tree (convenient for large compose yamls) | -| `-v, --version` | Show the version of compose-viz. | -| `--help` | Show help and exit. | +| Option | Description | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `-o, --output-filename FILENAME` | Output filename for the generated visualization file. [default: compose-viz] | +| `-m, --format FORMAT` | Output format for the generated visualization file. See [supported formats](https://github.com/compose-viz/compose-viz/blob/main/compose_viz/models/viz_formats.py). [default: png] | +| `-r, --root-service SERVICE_NAME` | Root of the service tree (convenient for large compose yamls) | +| `-v, --version` | Show the version of compose-viz. | +| `--help` | Show help and exit. |

(back to top)

From 168d034c05ac6ba889dd12bafb496e69aab78bfd Mon Sep 17 00:00:00 2001 From: Xyphuz Date: Tue, 10 Jan 2023 22:37:51 +0800 Subject: [PATCH 2/3] fix: handle key error during parsing root service --- compose_viz/parser.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compose_viz/parser.py b/compose_viz/parser.py index a9842ff..127f4ce 100644 --- a/compose_viz/parser.py +++ b/compose_viz/parser.py @@ -28,6 +28,8 @@ class Parser: @staticmethod def compile_dependencies(service_name: str, compose_data: spec.ComposeSpecification) -> List[str]: assert compose_data.services + assert service_name in compose_data.services, f"Service '{service_name}' not found in given compose file." + dependencies = [] for dependency in Parser._unwrap_depends_on(compose_data.services[service_name].depends_on): if dependency: @@ -47,7 +49,7 @@ class Parser: assert compose_data.services is not None, "No services found, aborting." - root_dependencies: List[str] = list() + root_dependencies: List[str] = [] if root_service: root_dependencies = Parser.compile_dependencies(root_service, compose_data) root_dependencies.append(root_service) From eb84c5ed05f42bff12fb3caeaa5d38cf508d8407 Mon Sep 17 00:00:00 2001 From: Xyphuz Date: Wed, 11 Jan 2023 00:54:06 +0800 Subject: [PATCH 3/3] test: add test for root service --- compose_viz/parser.py | 12 ++++++------ tests/test_cli.py | 1 + tests/test_root_service.py | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 tests/test_root_service.py diff --git a/compose_viz/parser.py b/compose_viz/parser.py index 127f4ce..4e45da7 100644 --- a/compose_viz/parser.py +++ b/compose_viz/parser.py @@ -26,15 +26,14 @@ class Parser: return service_depends_on @staticmethod - def compile_dependencies(service_name: str, compose_data: spec.ComposeSpecification) -> List[str]: - assert compose_data.services - assert service_name in compose_data.services, f"Service '{service_name}' not found in given compose file." + def compile_dependencies(service_name: str, services: Dict[Any, spec.Service], file_path: str) -> List[str]: + assert service_name in services, f"Service '{service_name}' not found in given compose file: '{file_path}'" dependencies = [] - for dependency in Parser._unwrap_depends_on(compose_data.services[service_name].depends_on): + for dependency in Parser._unwrap_depends_on(services[service_name].depends_on): if dependency: dependencies.append(dependency) - dependencies.extend(Parser.compile_dependencies(dependency, compose_data)) + dependencies.extend(Parser.compile_dependencies(dependency, services, file_path)) return dependencies def parse(self, file_path: str, root_service: Optional[str] = None) -> Compose: @@ -51,8 +50,9 @@ class Parser: root_dependencies: List[str] = [] if root_service: - root_dependencies = Parser.compile_dependencies(root_service, compose_data) + root_dependencies = Parser.compile_dependencies(root_service, compose_data.services, file_path) root_dependencies.append(root_service) + root_dependencies = list(set(root_dependencies)) for service_name, service_data in compose_data.services.items(): service_name = str(service_name) diff --git a/tests/test_cli.py b/tests/test_cli.py index 503047b..31ebbb0 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -26,6 +26,7 @@ runner = CliRunner() "tests/ymls/volumes/docker-compose.yml", "examples/full-stack-node-app/docker-compose.yml", "examples/non-normative/docker-compose.yml", + "examples/voting-app/docker-compose.yml", ], ) def test_cli(test_file_path: str) -> None: diff --git a/tests/test_root_service.py b/tests/test_root_service.py new file mode 100644 index 0000000..376db45 --- /dev/null +++ b/tests/test_root_service.py @@ -0,0 +1,32 @@ +import os + +from typer.testing import CliRunner + +from compose_viz import cli + +runner = CliRunner() + + +def test_root_service() -> None: + input_path = "examples/voting-app/docker-compose.yml" + output_filename = "compose-viz-test" + default_format = "png" + result = runner.invoke(cli.app, ["-r", "vote", "-o", output_filename, input_path]) + + assert result.exit_code == 0 + assert f"Successfully parsed {input_path}\n" in result.stdout + assert os.path.exists(f"{output_filename}.{default_format}") + + os.remove(f"{output_filename}.{default_format}") + + +def test_root_service_key_error() -> None: + input_path = "examples/voting-app/docker-compose.yml" + output_filename = "compose-viz-test" + default_format = "png" + result = runner.invoke(cli.app, ["-r", "not_exist_service", "-o", output_filename, input_path]) + + assert result.exit_code == 1 + assert result.exception is not None + assert result.exception.args[0] == f"Service 'not_exist_service' not found in given compose file: '{input_path}'" + assert not os.path.exists(f"{output_filename}.{default_format}")