-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathconfig.py
More file actions
108 lines (88 loc) · 3.28 KB
/
config.py
File metadata and controls
108 lines (88 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
from dataclasses import dataclass, field, fields
from enum import Enum
from pathlib import Path
from typing import Any, Required, TypedDict, cast
from jsonschema import ValidationError, validate
COMMENT_FILETYPE = {
"cpp": ["c", "ci", "cpp", "cc", "cxx", "h", "hpp", "hxx", "hh", "ihl"],
"python": ["py"],
"cs": ["cs"],
"yaml": ["yml", "yaml"],
"rust": ["rs"],
}
class CommentType(str, Enum):
python = "python"
cpp = "cpp"
cs = "cs"
yaml = "yaml"
# @Support Rust style comments, IMPL_RUST_1, impl, [FE_RUST];
rust = "rust"
class SourceDiscoverSectionConfigType(TypedDict, total=False):
"""Define typing for loading configuration from TOML files"""
src_dir: Required[str]
exclude: list[str]
include: list[str]
gitignore: bool
follow_links: bool
comment_type: CommentType
class SourceDiscoverConfigType(TypedDict, total=False):
"""Define typing for its API configuration"""
src_dir: Required[Path]
exclude: list[str]
include: list[str]
gitignore: bool
follow_links: bool
comment_type: CommentType
@dataclass
class SourceDiscoverConfig:
@classmethod
def field_names(cls) -> set[str]:
return {item.name for item in fields(cls)}
src_dir: Path = field(
default_factory=lambda: Path("./"), metadata={"schema": {"type": "string"}}
)
"""The root of the source directory."""
exclude: list[str] = field(
default_factory=list,
metadata={"schema": {"type": "array", "items": {"type": "string"}}},
)
"""The glob pattern to exclude files."""
include: list[str] = field(
default_factory=list,
metadata={"schema": {"type": "array", "items": {"type": "string"}}},
)
"""The glob pattern to include files."""
gitignore: bool = field(default=True, metadata={"schema": {"type": "boolean"}})
"""Whether to respect .gitignore to exclude files."""
follow_links: bool = field(default=False, metadata={"schema": {"type": "boolean"}})
"""Whether to follow symbolic links during file discovery."""
comment_type: str = field(
default="cpp",
metadata={
"schema": {
"type": "string",
"enum": sorted(COMMENT_FILETYPE),
}
},
)
"""The file types to discover."""
@classmethod
def get_schema(cls, name: str) -> dict[str, Any] | None: # type: ignore[explicit-any]
_field = next(_field for _field in fields(cls) if _field.name is name)
if _field.metadata and "schema" in _field.metadata:
return cast(dict[str, Any], _field.metadata["schema"]) # type: ignore[explicit-any]
return None
def check_schema(self) -> list[str]:
errors = []
for _field_name in self.field_names():
schema = self.get_schema(_field_name)
value = getattr(self, _field_name)
if isinstance(value, Path): # adapt to json schema restriction
value = str(value)
try:
validate(instance=value, schema=schema) # type: ignore[arg-type] # validate has no type specified
except ValidationError as e:
errors.append(
f"Schema validation error in field '{_field_name}': {e.message}"
)
return errors