Skip to content

Commit 3bc5a1e

Browse files
committed
added validate-compose to cli
1 parent 33e3d0c commit 3bc5a1e

4 files changed

Lines changed: 39 additions & 11 deletions

File tree

pod_porter/pod_porter.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
import json
88
import os
99
from yaml import safe_load, safe_dump
10-
from jsonschema import validate, Draft202012Validator
10+
from jsonschema import validate, Draft202012Validator, ValidationError
1111
from pod_porter.render.render import Render
1212
from pod_porter.util.directories import create_temp_working_directory, delete_temp_working_directory
1313
from pod_porter.util.file_read_write import write_file, extract_tar_gz_file
1414
from pod_porter.util.schemas import MapSchema
1515

1616
JSON_SCHEMA_FORMAT_CHECKERS = Draft202012Validator.FORMAT_CHECKER
17+
COMPOSE_SPEC: Path = Path(__file__).parent.joinpath("render").joinpath("compose_spec").joinpath("compose-spec.json")
1718

1819

1920
class _PorterMap: # pylint: disable=too-many-instance-attributes
@@ -72,7 +73,8 @@ def __repr__(self) -> str:
7273
"""
7374
return f'PorterMap(path="{self._path}", release_name="{self._release_name}")'
7475

75-
def validate_value_json_schema(self, values_data: dict, values_path: str) -> None:
76+
@staticmethod
77+
def validate_value_json_schema(values_data: dict, values_path: str) -> None:
7678
"""Validate data against a JSON schema.
7779
7880
:type values_data: dict
@@ -341,8 +343,6 @@ class PorterMapsRunner: # pylint: disable=too-many-instance-attributes
341343
:returns: Nothing
342344
"""
343345

344-
COMPOSE_SPEC: Path = Path(__file__).parent.joinpath("render").joinpath("compose_spec").joinpath("compose-spec.json")
345-
346346
def __init__(self, path: str, release_name: Optional[str] = None, values_override: Optional[str] = None) -> None:
347347
self._path = path
348348
self._release_name = release_name or "release-name"
@@ -421,22 +421,32 @@ def _collect_maps(self) -> List[Dict]:
421421

422422
return maps
423423

424-
def validate_compose_json_schema(self, compose_data: dict) -> None:
424+
@staticmethod
425+
def validate_compose_json_schema(compose_data: dict) -> None:
425426
"""Validate the created compose data against the compose spec JSON schema
427+
https://github.com/compose-spec/compose-spec/blob/main/schema/compose-spec.json
426428
427429
:type compose_data: dict
428430
:param compose_data: The compose data
429431
430432
:rtype: None
431433
:returns: Nothing it validates the JSON data against the JSON schema
432434
"""
433-
if not self.COMPOSE_SPEC.is_file():
434-
raise FileNotFoundError(f"compose file json spec not found {self.COMPOSE_SPEC.as_posix()}")
435+
if not COMPOSE_SPEC.is_file():
436+
raise FileNotFoundError(f"compose file json spec not found {COMPOSE_SPEC.as_posix()}")
435437

436-
with open(self.COMPOSE_SPEC.as_posix(), "r", encoding="utf-8") as compose_schema_file:
438+
with open(COMPOSE_SPEC.as_posix(), "r", encoding="utf-8") as compose_schema_file:
437439
compose_json_schema = json.load(compose_schema_file)
438440

439-
validate(instance=compose_data, schema=compose_json_schema, format_checker=JSON_SCHEMA_FORMAT_CHECKERS)
441+
try:
442+
validate(instance=compose_data, schema=compose_json_schema, format_checker=JSON_SCHEMA_FORMAT_CHECKERS)
443+
444+
except ValidationError as err:
445+
readable_error = (
446+
f"Error in validating compose file!\nArgument Error: {err.args}\n"
447+
f"In Schema Path: {'.'.join(err.absolute_path)}"
448+
)
449+
raise ValueError(readable_error)
440450

441451
def render_compose(self) -> str:
442452
"""Render the compose file

pod_porter/pod_porter_cli.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
from argparse import ArgumentParser
66
from importlib.metadata import version
7+
8+
from jsonschema import ValidationError
9+
from yaml import safe_load
710
from pod_porter.pod_porter import PorterMapsRunner
811
from pod_porter.util.file_read_write import write_file, create_tar_gz_file, extract_tar_gz_file, create_new_map
912

@@ -95,6 +98,11 @@ def cli_argument_parser() -> ArgumentParser:
9598
arg_parser_map_create.set_defaults(which_sub="create")
9699
common_sub_parser_map_arguments(sub_arg_parser=arg_parser_map_create)
97100

101+
# This is the sub parser to create a new map
102+
arg_parser_validate_compose = subparsers.add_parser("validate-compose", help="Validate a compose file")
103+
arg_parser_validate_compose.set_defaults(which_sub="validate-compose")
104+
arg_parser_validate_compose.add_argument("-f", "--file", required=True, help="Path to the compose file")
105+
98106
return arg_parser
99107

100108

@@ -134,6 +142,16 @@ def cli() -> None: # pragma: no cover
134142
if args.which_sub == "create":
135143
create_new_map(map_name_and_path=args.map)
136144

145+
if args.which_sub == "validate-compose":
146+
with open(args.file, "r", encoding="utf-8") as file:
147+
data = safe_load(file.read())
148+
149+
try:
150+
PorterMapsRunner.validate_compose_json_schema(compose_data=data)
151+
152+
except ValueError as error:
153+
print(error)
154+
137155
except AttributeError as error:
138156
print(f"\n !!! {error} !!! \n")
139157
arg_parser.print_help()

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta"
88
[project]
99
name = "pod-porter"
1010
dynamic = ["readme"]
11-
version = "0.2.3"
11+
version = "1.0.0"
1212
requires-python = ">=3.10"
1313
description = "Like Helm but for Container Compose Files"
1414
keywords = [

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)