Skip to content

Commit

Permalink
feat: Check if the .makim.yaml file is valid according to the schema …
Browse files Browse the repository at this point in the history
…file (#122)
  • Loading branch information
xmnlab authored Oct 17, 2024
1 parent 677e864 commit 29d0b51
Show file tree
Hide file tree
Showing 26 changed files with 330 additions and 68 deletions.
2 changes: 1 addition & 1 deletion .makim.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
version: 1.0
groups:
clean:
tasks:
Expand Down Expand Up @@ -87,6 +86,7 @@ groups:
- task: smoke-tests.interactive-args
- task: smoke-tests.run-hooks
- task: smoke-tests.matrix
- task: makim smoke-tests.shell-app

ci:
help: Run all tasks used on CI
Expand Down
1 change: 0 additions & 1 deletion docs/tutorials/introduction/.makim.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
version: 1.0
dir: "/tmp"

groups:
Expand Down
1 change: 0 additions & 1 deletion docs/tutorials/makim-for-nox-users/.makim.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
version: 1.0
groups:
nox:
help: A set of functionality ported from noxfile.py
Expand Down
22 changes: 11 additions & 11 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ packages = [
{include = "makim", from="src"},
]

include = ["src/makim/py.typed"]
include = [
"src/makim/py.typed",
"src/makim/schema.json",
]

exclude = [
".git/*",
Expand All @@ -34,6 +37,7 @@ fuzzywuzzy = ">=0.18.0"
python-levenshtein = ">=0.23.0"
rich = ">=10.11.0"
shellingham = ">=1.5.4"
jsonschema = ">=4"

[tool.poetry.group.dev.dependencies]
containers-sugar = ">=1.11.1"
Expand Down
52 changes: 52 additions & 0 deletions src/makim/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import copy
import io
import json
import os
import pprint
import sys
Expand All @@ -26,11 +27,14 @@
import yaml # type: ignore

from jinja2 import Environment
from jsonschema import ValidationError, validate
from typing_extensions import TypeAlias

from makim.console import get_terminal_size
from makim.logs import MakimError, MakimLogs

SUGAR_CURRENT_PATH = Path(__file__).parent

AppConfigType: TypeAlias = Dict[str, Union[str, List[str]]]

SCOPE_GLOBAL = 0
Expand Down Expand Up @@ -183,6 +187,52 @@ def _verify_args(self) -> None:
MakimError.MAKIM_CONFIG_FILE_NOT_FOUND,
)

def validate_config(self) -> None:
"""
Validate the .makim.yaml against the predefined JSON Schema.
Raises
------
MakimError: If the configuration does not conform to the schema.
"""
try:
with open(SUGAR_CURRENT_PATH / 'schema.json', 'r') as schema_file:
schema = json.load(schema_file)

config_data = self.global_data

# Validate the configuration against the schema
validate(instance=config_data, schema=schema)

if self.verbose:
MakimLogs.print_info('Configuration validation successful.')

except ValidationError as ve:
error_message = f'Configuration validation error: {ve.message}'
MakimLogs.raise_error(
error_message, MakimError.CONFIG_VALIDATION_ERROR
)
except yaml.YAMLError as ye:
error_message = f'YAML parsing error: {ye}'
MakimLogs.raise_error(error_message, MakimError.YAML_PARSING_ERROR)
except json.JSONDecodeError as je:
error_message = f'JSON schema decoding error: {je}'
MakimLogs.raise_error(
error_message, MakimError.JSON_SCHEMA_DECODING_ERROR
)
except FileNotFoundError:
error_message = f'Configuration file {self.file} not found.'
MakimLogs.raise_error(
error_message, MakimError.MAKIM_CONFIG_FILE_NOT_FOUND
)
except Exception as e:
error_message = (
f'Unexpected error during configuration validation: {e}'
)
MakimLogs.raise_error(
error_message, MakimError.CONFIG_VALIDATION_UNEXPECTED_ERROR
)

def _verify_config(self) -> None:
if not len(self.global_data['groups']):
MakimLogs.raise_error(
Expand Down Expand Up @@ -239,6 +289,8 @@ def _load_config_data(self) -> None:
content_io = io.StringIO(content)
self.global_data = yaml.safe_load(content_io)

self.validate_config()

def _resolve_working_directory(self, scope: str) -> Optional[Path]:
scope_options = ('global', 'group', 'task')
if scope not in scope_options:
Expand Down
4 changes: 4 additions & 0 deletions src/makim/logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ class MakimError(Enum):
MAKIM_ARGUMENT_REQUIRED = 8
MAKIM_ENV_FILE_NOT_FOUND = 9
MAKIM_CONFIG_FILE_INVALID = 10
CONFIG_VALIDATION_ERROR = 11
YAML_PARSING_ERROR = 12
JSON_SCHEMA_DECODING_ERROR = 13
CONFIG_VALIDATION_UNEXPECTED_ERROR = 14


class MakimLogs:
Expand Down
Loading

0 comments on commit 29d0b51

Please sign in to comment.