Skip to content

Commit

Permalink
Merge pull request #16 from petermorrowdev/bug/required-field-validat…
Browse files Browse the repository at this point in the history
…ion-fails

Bug/required field validation fails
  • Loading branch information
petermorrowdev authored Sep 7, 2024
2 parents cd6777a + 7a1e2ac commit d4e9e05
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 30 deletions.
7 changes: 1 addition & 6 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,16 @@ on:
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12']
fail-fast: false

steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: pip

- name: Install Hatch
run: pip install hatch

- name: Test
run: hatch run test
run: hatch test --parallel --all
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Create a `chart.py` file:
import gybe
def create_standard_container(image: str, command: List[str]):
def create_standard_container(image: str, command: list[str]):
return gybe.k8s.Container(image=image, command=command, name='my-python-server')
Expand Down
2 changes: 1 addition & 1 deletion gybe/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""A simple YAML transpilation tool for rendering kubernetes manifests"""

__version__ = '0.3.2'
__version__ = '0.3.3'


from gybe import k8s
Expand Down
8 changes: 6 additions & 2 deletions gybe/decorators.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Decorators for building CLI commands."""

import inspect
import sys
from dataclasses import fields
from typing import Any, Callable
Expand All @@ -18,7 +19,10 @@ def _omit_none_values(obj: K8sSpec) -> dict[str, Any]:
for f in fields(obj):
v = getattr(obj, f.name)
if v is not None:
u[f.name] = _c.unstructure(v)
if inspect.isclass(f.type) and issubclass(f.type, K8sSpec):
u[f.name] = _c.unstructure(v, f.type)
else:
u[f.name] = _c.unstructure(v)
return u


Expand All @@ -34,7 +38,7 @@ def func(file):
try:
input_obj = _c.structure(input_data, input_model)
except Exception as exc:
print('Validation Error:')
print('validation errors:')
for m in transform_error(exc):
print('-', m)
sys.exit(-1)
Expand Down
10 changes: 8 additions & 2 deletions gybe/modeling.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import inspect
from dataclasses import make_dataclass
from typing import Callable
from typing import Any, Callable, Union

from gybe.k8s.types import Manifest

Expand All @@ -16,5 +16,11 @@ def create_input_model(func: Callable[..., Manifest]) -> type:
else:
defaults = dict()

fields = [(k, t, defaults.get(k, ...)) for k, t in argspec.annotations.items() if k != 'return']
fields: list[Union[tuple[str, type, Any], tuple[str, type]]] = []
for k, t in argspec.annotations.items():
if k != 'return':
if k in defaults:
fields.append((k, t, defaults[k]))
else:
fields.append((k, t))
return make_dataclass(f'{func.__name__}', fields)
32 changes: 21 additions & 11 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ dependencies = [
"cattrs",
]

[project.optional-dependencies]
test = [
"pytest",
"pytest-cov",
"coverage[toml]>=6.5",
"mypy",
"ruff",
"types-PyYAML",
]

[project.urls]
Documentation = "https://github.com/petermorrowdev/gybe#readme"
Issues = "https://github.com/petermorrowdev/gybe/issues"
Expand All @@ -41,20 +51,20 @@ path = "gybe/__init__.py"

[tool.hatch.envs.default]
installer = "uv"
dependencies = [
"pytest",
"pytest-cov",
"coverage[toml]>=6.5",
"mypy",
"ruff",
"types-PyYAML",
]
features = ["test"]

[tool.hatch.envs.default.scripts]
test = "pytest && mypy gybe tests && ruff check gybe tests"
genk8s = "bash codegen/kubernetes"

[[tool.hatch.envs.all.matrix]]
python = ["3.8", "3.9", "3.10", "3.11", "3.12"]
[tool.hatch.envs.hatch-test]
installer = "uv"
features = ["test"]

[tool.hatch.envs.hatch-test.scripts]
run = "pytest {env:HATCH_TEST_ARGS:} {args} && mypy gybe tests && ruff check gybe tests"

[[tool.hatch.envs.hatch-test.matrix]]
python = ["3.12", "3.11", "3.10"]

[tool.coverage.run]
source_pkgs = ["gybe", "tests"]
Expand Down
34 changes: 27 additions & 7 deletions tests/test_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def create_standard_container(image: str, command: list[str]):


@gybe.transpiler
def two_pods(image: str, command: list[str], port: int = 8080) -> gybe.Manifest:
def two_pods(image: str, command: list[str]) -> gybe.Manifest:
pod_spec = gybe.k8s.PodSpec(
containers=[create_standard_container(image=image, command=command)],
)
Expand Down Expand Up @@ -62,18 +62,38 @@ def two_pods(image: str, command: list[str], port: int = 8080) -> gybe.Manifest:
name: standard-server
"""

INVALID_VALID_TWO_POD_YAML = """
image: python:3
command: false
"""


def test_two_pods_chart_transpiles_with_valid_yaml(run_cli):
result = run_cli(two_pods, VALID_TWO_POD_YAML)
assert result.exit_code == 0
assert result.stdout.strip() == EXPECTED_TWO_POD_MANIFEST.strip()


EXPECTED_EMPTY_YAML_VALIDATION_ERROR = """
validation errors:
- required field missing @ $.image
- required field missing @ $.command
"""


def test_two_pods_chart_fails_with_empty_yaml(run_cli):
result = run_cli(two_pods, '')
assert result.exit_code == -1
assert result.stdout.strip() == EXPECTED_EMPTY_YAML_VALIDATION_ERROR.strip()


INVALID_TWO_POD_YAML = """
image: python:3
command: false
"""

EXPECTED_INVALID_TWO_POD_YAML = """
validation errors:
- invalid value for type, expected list @ $.command
"""


def test_two_pods_chart_fails_with_invalid_yaml(run_cli):
result = run_cli(two_pods, INVALID_VALID_TWO_POD_YAML)
result = run_cli(two_pods, INVALID_TWO_POD_YAML)
assert result.exit_code == -1
assert result.stdout.strip() == EXPECTED_INVALID_TWO_POD_YAML.strip()

0 comments on commit d4e9e05

Please sign in to comment.