mirror of
https://gitlab.com/kupfer/kupferbootstrap.git
synced 2025-02-23 05:35:44 -05:00
159 lines
3.9 KiB
Python
159 lines
3.9 KiB
Python
from __future__ import annotations
|
|
|
|
from munch import Munch
|
|
from typing import Any, Optional, Mapping, Union
|
|
|
|
from dataclass import DataClass, munchclass
|
|
from constants import Arch
|
|
|
|
|
|
@munchclass()
|
|
class SparseProfile(DataClass):
|
|
parent: Optional[str]
|
|
device: Optional[str]
|
|
flavour: Optional[str]
|
|
pkgs_include: Optional[list[str]]
|
|
pkgs_exclude: Optional[list[str]]
|
|
hostname: Optional[str]
|
|
username: Optional[str]
|
|
password: Optional[str]
|
|
size_extra_mb: Optional[Union[str, int]]
|
|
|
|
def __repr__(self):
|
|
return f'{type(self)}{dict.__repr__(self.toDict())}'
|
|
|
|
|
|
@munchclass()
|
|
class Profile(SparseProfile):
|
|
parent: Optional[str]
|
|
device: str
|
|
flavour: str
|
|
pkgs_include: list[str]
|
|
pkgs_exclude: list[str]
|
|
hostname: str
|
|
username: str
|
|
password: Optional[str]
|
|
size_extra_mb: Union[str, int]
|
|
|
|
|
|
@munchclass()
|
|
class WrapperSection(DataClass):
|
|
type: str # NOTE: rename to 'wrapper_type' if this causes problems
|
|
|
|
|
|
@munchclass()
|
|
class BuildSection(DataClass):
|
|
ccache: bool
|
|
clean_mode: bool
|
|
crosscompile: bool
|
|
crossdirect: bool
|
|
threads: int
|
|
|
|
|
|
@munchclass()
|
|
class PkgbuildsSection(DataClass):
|
|
git_repo: str
|
|
git_branch: str
|
|
|
|
|
|
@munchclass()
|
|
class PacmanSection(DataClass):
|
|
parallel_downloads: int
|
|
check_space: bool
|
|
repo_branch: str
|
|
|
|
|
|
@munchclass()
|
|
class PathsSection(DataClass):
|
|
cache_dir: str
|
|
chroots: str
|
|
pacman: str
|
|
packages: str
|
|
pkgbuilds: str
|
|
jumpdrive: str
|
|
images: str
|
|
ccache: str
|
|
rust: str
|
|
|
|
|
|
class ProfilesSection(DataClass):
|
|
current: str
|
|
default: SparseProfile
|
|
|
|
@classmethod
|
|
def transform(cls, values: Mapping[str, Any], validate: bool = True, allow_extra: bool = True):
|
|
results = {}
|
|
for k, v in values.items():
|
|
if k == 'current':
|
|
results[k] = v
|
|
continue
|
|
if not allow_extra and k != 'default':
|
|
raise Exception(f'Unknown key {k} in profiles section (Hint: extra_keys not allowed for some reason)')
|
|
if not isinstance(v, dict):
|
|
raise Exception(f'profile {v} is not a dict!')
|
|
results[k] = SparseProfile.fromDict(v, validate=True)
|
|
return results
|
|
|
|
def update(self, d, validate: bool = True):
|
|
Munch.update(self, self.transform(values=d, validate=validate))
|
|
|
|
def __repr__(self):
|
|
return f'{type(self)}{dict.__repr__(self.toDict())}'
|
|
|
|
|
|
@munchclass()
|
|
class Config(DataClass):
|
|
wrapper: WrapperSection
|
|
build: BuildSection
|
|
pkgbuilds: PkgbuildsSection
|
|
pacman: PacmanSection
|
|
paths: PathsSection
|
|
profiles: ProfilesSection
|
|
|
|
@classmethod
|
|
def fromDict(
|
|
cls,
|
|
values: Mapping[str, Any],
|
|
validate: bool = True,
|
|
allow_extra: bool = False,
|
|
allow_incomplete: bool = False,
|
|
):
|
|
values = dict(values) # copy for later modification
|
|
_vals = {}
|
|
for name, _class in cls._type_hints.items():
|
|
if name not in values:
|
|
if not allow_incomplete:
|
|
raise Exception(f'Config key "{name}" not in input dictionary')
|
|
continue
|
|
value = values.pop(name)
|
|
if not isinstance(value, _class):
|
|
value = _class.fromDict(value, validate=validate)
|
|
_vals[name] = value
|
|
|
|
if values:
|
|
if validate:
|
|
raise Exception(f'values contained unknown keys: {list(values.keys())}')
|
|
_vals |= values
|
|
|
|
return Config(**_vals, validate=validate)
|
|
|
|
|
|
@munchclass()
|
|
class RuntimeConfiguration(DataClass):
|
|
verbose: bool
|
|
no_wrap: bool
|
|
error_shell: bool
|
|
config_file: Optional[str]
|
|
script_source_dir: Optional[str]
|
|
arch: Optional[Arch]
|
|
uid: Optional[int]
|
|
|
|
|
|
class ConfigLoadState(DataClass):
|
|
load_finished: bool
|
|
exception: Optional[Exception]
|
|
|
|
def __init__(self, d: dict = {}):
|
|
self.load_finished = False
|
|
self.exception = None
|
|
self.update(d)
|