Skip to content

Commit 2b48f61

Browse files
committed
Convert methods load_from_disk and load_yamlfile_from_disk_and_exit to work with all yaml files
1 parent 4fb041f commit 2b48f61

File tree

3 files changed

+104
-48
lines changed

3 files changed

+104
-48
lines changed

infrahub_sdk/ctl/schema.py

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,12 @@
1111
from infrahub_sdk import InfrahubClient
1212
from infrahub_sdk.async_typer import AsyncTyper
1313
from infrahub_sdk.ctl.client import initialize_client
14-
from infrahub_sdk.ctl.exceptions import FileNotValidError
1514
from infrahub_sdk.ctl.utils import catch_exception, init_logging
1615
from infrahub_sdk.queries import SCHEMA_HASH_SYNC_STATUS
17-
from infrahub_sdk.utils import find_files
1816
from infrahub_sdk.yaml import SchemaFile
1917

2018
from .parameters import CONFIG_PARAM
19+
from .utils import load_yamlfile_from_disk_and_exit
2120

2221
app = AsyncTyper()
2322
console = Console()
@@ -30,45 +29,6 @@ def callback() -> None:
3029
"""
3130

3231

33-
def load_schemas_from_disk(schemas: list[Path]) -> list[SchemaFile]:
34-
schemas_data: list[SchemaFile] = []
35-
for schema in schemas:
36-
if schema.is_file():
37-
schema_file = SchemaFile(location=schema)
38-
schema_file.load_content()
39-
schemas_data.append(schema_file)
40-
elif schema.is_dir():
41-
files = find_files(extension=["yaml", "yml", "json"], directory=schema)
42-
for item in files:
43-
schema_file = SchemaFile(location=item)
44-
schema_file.load_content()
45-
schemas_data.append(schema_file)
46-
else:
47-
raise FileNotValidError(name=schema, message=f"Schema path: {schema} does not exist!")
48-
49-
return schemas_data
50-
51-
52-
def load_schemas_from_disk_and_exit(schemas: list[Path]) -> list[SchemaFile]:
53-
has_error = False
54-
try:
55-
schemas_data = load_schemas_from_disk(schemas=schemas)
56-
except FileNotValidError as exc:
57-
console.print(f"[red]{exc.message}")
58-
raise typer.Exit(1) from exc
59-
60-
for schema_file in schemas_data:
61-
if schema_file.valid and schema_file.content:
62-
continue
63-
console.print(f"[red]{schema_file.error_message} ({schema_file.location})")
64-
has_error = True
65-
66-
if has_error:
67-
raise typer.Exit(1)
68-
69-
return schemas_data
70-
71-
7232
def validate_schema_content_and_exit(client: InfrahubClient, schemas: list[SchemaFile]) -> None:
7333
has_error: bool = False
7434
for schema_file in schemas:
@@ -153,7 +113,7 @@ async def load(
153113

154114
init_logging(debug=debug)
155115

156-
schemas_data = load_schemas_from_disk_and_exit(schemas=schemas)
116+
schemas_data = load_yamlfile_from_disk_and_exit(paths=schemas, file_type=SchemaFile, console=console)
157117
schema_definition = "schema" if len(schemas_data) == 1 else "schemas"
158118
client = await initialize_client()
159119
validate_schema_content_and_exit(client=client, schemas=schemas_data)
@@ -203,7 +163,7 @@ async def check(
203163

204164
init_logging(debug=debug)
205165

206-
schemas_data = load_schemas_from_disk_and_exit(schemas=schemas)
166+
schemas_data = load_yamlfile_from_disk_and_exit(paths=schemas, file_type=SchemaFile, console=console)
207167
client = await initialize_client()
208168
validate_schema_content_and_exit(client=client, schemas=schemas_data)
209169

infrahub_sdk/ctl/utils.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import traceback
44
from functools import wraps
55
from pathlib import Path
6-
from typing import Any, Callable, Optional, Union
6+
from typing import Any, Callable, Optional, TypeVar, Union
77

88
import pendulum
99
import typer
@@ -14,7 +14,7 @@
1414
from rich.logging import RichHandler
1515
from rich.markup import escape
1616

17-
from infrahub_sdk.ctl.exceptions import QueryNotFoundError
17+
from infrahub_sdk.ctl.exceptions import FileNotValidError, QueryNotFoundError
1818
from infrahub_sdk.exceptions import (
1919
AuthenticationError,
2020
Error,
@@ -25,9 +25,12 @@
2525
ServerNotResponsiveError,
2626
)
2727
from infrahub_sdk.schema import InfrahubRepositoryConfig
28+
from infrahub_sdk.yaml import YamlFile
2829

2930
from .client import initialize_client_sync
3031

32+
YamlFileVar = TypeVar("YamlFileVar", bound=YamlFile)
33+
3134

3235
def init_logging(debug: bool = False) -> None:
3336
logging.getLogger("infrahub_sdk").setLevel(logging.CRITICAL)
@@ -179,3 +182,25 @@ def get_fixtures_dir() -> Path:
179182
"""Get the directory which stores fixtures that are common to multiple unit/integration tests."""
180183
here = Path(__file__).resolve().parent
181184
return here.parent.parent / "tests" / "fixtures"
185+
186+
187+
def load_yamlfile_from_disk_and_exit(
188+
paths: list[Path], file_type: type[YamlFileVar], console: Console
189+
) -> list[YamlFileVar]:
190+
has_error = False
191+
try:
192+
data_files = file_type.load_from_disk(paths=paths)
193+
except FileNotValidError as exc:
194+
console.print(f"[red]{exc.message}")
195+
raise typer.Exit(1) from exc
196+
197+
for data_file in data_files:
198+
if data_file.valid and data_file.content:
199+
continue
200+
console.print(f"[red]{data_file.error_message} ({data_file.location})")
201+
has_error = True
202+
203+
if has_error:
204+
raise typer.Exit(1)
205+
206+
return data_files

infrahub_sdk/yaml.py

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,39 @@
1+
from enum import Enum
12
from pathlib import Path
2-
from typing import Optional
3+
from typing import Optional, Self
34

45
import yaml
5-
from pydantic import BaseModel
6+
from pydantic import BaseModel, Field
67

8+
from infrahub_sdk.ctl.exceptions import FileNotValidError
9+
from infrahub_sdk.utils import find_files
710

8-
class SchemaFile(BaseModel):
11+
12+
class InfrahubFileApiVersion(str, Enum):
13+
V1 = "infrahub.app/v1"
14+
15+
16+
class InfrahubFileKind(str, Enum):
17+
MENU = "Menu"
18+
OBJECT = "Object"
19+
20+
21+
class InfrahubFileData(BaseModel):
22+
api_version: InfrahubFileApiVersion = Field(InfrahubFileApiVersion.V1, alias="apiVersion")
23+
kind: InfrahubFileKind
24+
spec: dict
25+
metadata: Optional[dict] = Field(default_factory=dict)
26+
27+
28+
class LocalFile(BaseModel):
929
identifier: Optional[str] = None
1030
location: Path
1131
content: Optional[dict] = None
1232
valid: bool = True
1333
error_message: Optional[str] = None
1434

35+
36+
class YamlFile(LocalFile):
1537
def load_content(self) -> None:
1638
try:
1739
self.content = yaml.safe_load(self.location.read_text())
@@ -23,3 +45,52 @@ def load_content(self) -> None:
2345
if not self.content:
2446
self.error_message = "Empty YAML/JSON file"
2547
self.valid = False
48+
49+
def validate_content(self) -> None:
50+
pass
51+
52+
@classmethod
53+
def load_from_disk(cls, paths: list[Path]) -> list[Self]:
54+
yaml_files: list[Self] = []
55+
for file_path in paths:
56+
if file_path.is_file():
57+
yaml_file = cls(location=file_path)
58+
yaml_file.load_content()
59+
yaml_files.append(yaml_file)
60+
elif file_path.is_dir():
61+
files = find_files(extension=["yaml", "yml", "json"], directory=file_path)
62+
for item in files:
63+
yaml_file = cls(location=item)
64+
yaml_file.load_content()
65+
yaml_files.append(yaml_file)
66+
else:
67+
raise FileNotValidError(name=str(file_path), message=f"{file_path} does not exist!")
68+
69+
return yaml_files
70+
71+
72+
class InfrahubFile(YamlFile):
73+
_data: Optional[InfrahubFileData] = None
74+
75+
@property
76+
def data(self) -> InfrahubFileData:
77+
if not self._data:
78+
raise ValueError("_data hasn't been initialized yet")
79+
return self._data
80+
81+
@property
82+
def version(self) -> InfrahubFileApiVersion:
83+
return self.data.api_version
84+
85+
@property
86+
def kind(self) -> InfrahubFileKind:
87+
return self.data.kind
88+
89+
def validate_content(self) -> None:
90+
if not self.content:
91+
raise ValueError("Content hasn't been loaded yet")
92+
self._data = InfrahubFileData(**self.content)
93+
94+
95+
class SchemaFile(YamlFile):
96+
pass

0 commit comments

Comments
 (0)