Adding debian version 6.12.33-1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
This commit is contained in:
parent
79d69e5050
commit
09ce90cf76
1602 changed files with 165255 additions and 0 deletions
654
debian/lib/python/debian_linux/config_v2.py
vendored
Normal file
654
debian/lib/python/debian_linux/config_v2.py
vendored
Normal file
|
@ -0,0 +1,654 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import dataclasses
|
||||
import functools
|
||||
import re
|
||||
import subprocess
|
||||
import tomllib
|
||||
from collections.abc import (
|
||||
Iterable,
|
||||
)
|
||||
from pathlib import Path
|
||||
from typing import (
|
||||
Optional,
|
||||
Self,
|
||||
TypeVar,
|
||||
)
|
||||
|
||||
import dacite
|
||||
|
||||
from . import dataclasses_extra
|
||||
from .debian import PackageRelationGroup
|
||||
|
||||
|
||||
# Wrapper for regex objects, whose type is not a documented API
|
||||
class _RegexWrapper:
|
||||
def __init__(self, s):
|
||||
self._re = re.compile(s)
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self._re, name)
|
||||
|
||||
|
||||
_dacite_config = dacite.Config(
|
||||
cast=[
|
||||
PackageRelationGroup,
|
||||
Path,
|
||||
_RegexWrapper,
|
||||
],
|
||||
strict=True,
|
||||
)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ConfigBuild:
|
||||
cflags: Optional[str] = None
|
||||
compiler: Optional[str] = None
|
||||
compiler_gnutype: Optional[str] = None
|
||||
compiler_gnutype_compat: Optional[str] = None
|
||||
config: list[Path] = dataclasses.field(default_factory=list)
|
||||
config_default: list[Path] = dataclasses.field(default_factory=list, repr=False)
|
||||
enable_signed: Optional[bool] = None
|
||||
enable_vdso: Optional[bool] = None
|
||||
kernel_file: Optional[str] = None
|
||||
kernel_stem: Optional[str] = None
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ConfigDescription:
|
||||
hardware: Optional[str] = None
|
||||
hardware_long: Optional[str] = None
|
||||
parts: list[str] = dataclasses.field(default_factory=list)
|
||||
short: dict[str, str] = dataclasses.field(default_factory=dict)
|
||||
long: dict[str, str] = dataclasses.field(default_factory=dict)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ConfigPackages:
|
||||
docs: Optional[bool] = dataclasses.field(default=None, metadata={'default': True})
|
||||
installer: Optional[bool] = dataclasses.field(default=None, metadata={'default': False})
|
||||
libc_dev: Optional[bool] = dataclasses.field(default=None, metadata={'default': True})
|
||||
meta: Optional[bool] = dataclasses.field(default=None, metadata={'default': True})
|
||||
source: Optional[bool] = dataclasses.field(default=None, metadata={'default': True})
|
||||
tools_unversioned: Optional[bool] = dataclasses.field(default=None, metadata={'default': True})
|
||||
tools_versioned: Optional[bool] = dataclasses.field(default=None, metadata={'default': True})
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ConfigRelationsSingle:
|
||||
depends: list[PackageRelationGroup] = dataclasses.field(default_factory=list)
|
||||
recommends: list[PackageRelationGroup] = dataclasses.field(default_factory=list)
|
||||
suggests: list[PackageRelationGroup] = dataclasses.field(default_factory=list)
|
||||
breaks: list[PackageRelationGroup] = dataclasses.field(default_factory=list)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ConfigRelations:
|
||||
image: ConfigRelationsSingle = dataclasses.field(default_factory=ConfigRelationsSingle)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ConfigDebianarchDefs:
|
||||
__arch: Optional[str] = dataclasses.field(default=None, init=False)
|
||||
|
||||
def __post_init_defs__(self, parent: ConfigDebianarch) -> None:
|
||||
self.__arch = parent.name
|
||||
|
||||
@staticmethod
|
||||
@functools.cache
|
||||
def __dpkg_architecture(arch: str, query: str) -> str:
|
||||
return subprocess.check_output(
|
||||
[
|
||||
'dpkg-architecture',
|
||||
'-f',
|
||||
'-a', arch,
|
||||
'-q', query,
|
||||
],
|
||||
stderr=subprocess.DEVNULL,
|
||||
encoding='ascii',
|
||||
).strip()
|
||||
|
||||
@property
|
||||
def gnutype(self) -> str:
|
||||
assert self.__arch is not None
|
||||
return self.__dpkg_architecture(self.__arch, 'DEB_HOST_GNU_TYPE')
|
||||
|
||||
@property
|
||||
def gnutype_package(self) -> str:
|
||||
return self.gnutype.replace("_", "-")
|
||||
|
||||
@property
|
||||
def multiarch(self) -> str:
|
||||
assert self.__arch is not None
|
||||
return self.__dpkg_architecture(self.__arch, 'DEB_HOST_MULTIARCH')
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ConfigFlavourDefs:
|
||||
is_default: bool = False
|
||||
is_quick: bool = False
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ConfigDebianrelease:
|
||||
name_regex: _RegexWrapper
|
||||
abi_version_full: bool = True
|
||||
abi_suffix: str = ''
|
||||
revision_regex: _RegexWrapper = _RegexWrapper('.*')
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ConfigBase:
|
||||
name: str
|
||||
enable: bool = True
|
||||
path: Optional[Path] = None
|
||||
|
||||
build: ConfigBuild = dataclasses.field(default_factory=ConfigBuild)
|
||||
description: ConfigDescription = dataclasses.field(default_factory=ConfigDescription)
|
||||
packages: ConfigPackages = dataclasses.field(default_factory=ConfigPackages)
|
||||
relations: ConfigRelations = dataclasses.field(default_factory=ConfigRelations)
|
||||
|
||||
def __post_init_hierarchy__(self, path: Path) -> None:
|
||||
'''
|
||||
Setup path and default config in the complete hierarchy
|
||||
'''
|
||||
self.path = path
|
||||
self.build.config_default = [path / 'config']
|
||||
|
||||
def read_replace(self, bases: Iterable[Path], path: Path) -> Self:
|
||||
'''
|
||||
Read defines.toml at specified path in all bases and merged them
|
||||
'''
|
||||
config = self
|
||||
|
||||
try:
|
||||
for base in bases:
|
||||
if (file := base / path / 'defines.toml').exists():
|
||||
with file.open('rb') as f:
|
||||
data = dataclasses.asdict(self) | tomllib.load(f)
|
||||
|
||||
config = dataclasses_extra.merge(config, dacite.from_dict(
|
||||
data_class=self.__class__,
|
||||
data=data,
|
||||
config=_dacite_config,
|
||||
))
|
||||
except tomllib.TOMLDecodeError as e:
|
||||
raise RuntimeError(f'{file}: {e}') from None
|
||||
|
||||
return config
|
||||
|
||||
|
||||
ConfigT = TypeVar('ConfigT', bound=ConfigBase)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Config(ConfigBase):
|
||||
# Disable basic fields
|
||||
name: str = dataclasses.field(init=False, repr=False, default='')
|
||||
enable: bool = dataclasses.field(init=False, repr=False, default=True)
|
||||
|
||||
featureset: list[ConfigFeatureset] = dataclasses.field(
|
||||
default_factory=list, metadata={'merge': 'assoclist'},
|
||||
)
|
||||
kernelarch: list[ConfigKernelarch] = dataclasses.field(
|
||||
default_factory=list, metadata={'merge': 'assoclist'},
|
||||
)
|
||||
debianrelease: list[ConfigDebianrelease] = dataclasses.field(
|
||||
default_factory=list,
|
||||
)
|
||||
|
||||
def __post_init_hierarchy__(self, path: Path) -> None:
|
||||
super().__post_init_hierarchy__(path)
|
||||
|
||||
for featureset in self.featureset:
|
||||
featureset.__post_init_hierarchy_featureset__(
|
||||
Path(f'featureset-{featureset.name}'),
|
||||
None,
|
||||
)
|
||||
for kernelarch in self.kernelarch:
|
||||
kernelarch.__post_init_hierarchy__(
|
||||
Path(f'kernelarch-{kernelarch.name}'),
|
||||
)
|
||||
|
||||
@property
|
||||
def merged(self) -> ConfigMerged:
|
||||
return ConfigMerged(root=self)
|
||||
|
||||
@classmethod
|
||||
def read_orig(cls, bases: Iterable[Path]) -> Config:
|
||||
'''
|
||||
Read defines.toml at the root in all bases and merge them
|
||||
'''
|
||||
config = cls()
|
||||
found = False
|
||||
|
||||
try:
|
||||
for base in bases:
|
||||
if (file := base / 'defines.toml').exists():
|
||||
with file.open('rb') as f:
|
||||
data = tomllib.load(f)
|
||||
found = True
|
||||
|
||||
config = dataclasses_extra.merge(config, dacite.from_dict(
|
||||
data_class=cls,
|
||||
data=data,
|
||||
config=_dacite_config,
|
||||
))
|
||||
except (tomllib.TOMLDecodeError, dacite.exceptions.UnexpectedDataError) as e:
|
||||
raise RuntimeError(f'{file}: {e}') from None
|
||||
if not found:
|
||||
raise FileNotFoundError('Did not find defines.toml in any directory')
|
||||
|
||||
config.__post_init_hierarchy__(Path())
|
||||
|
||||
config.featureset = list(cls._read_hierarchy(bases, config.featureset))
|
||||
config.kernelarch = list(cls._read_hierarchy(bases, config.kernelarch))
|
||||
for kernelarch in config.kernelarch:
|
||||
kernelarch.debianarch = list(cls._read_hierarchy(bases, kernelarch.debianarch))
|
||||
|
||||
config.__post_init_hierarchy__(Path())
|
||||
|
||||
return config
|
||||
|
||||
@classmethod
|
||||
def _read_hierarchy(
|
||||
cls, bases: Iterable[Path], orig: Iterable[ConfigT],
|
||||
) -> Iterable[ConfigT]:
|
||||
for i in orig:
|
||||
try:
|
||||
assert i.path is not None
|
||||
yield i.read_replace(bases, i.path)
|
||||
except FileNotFoundError:
|
||||
yield i
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ConfigKernelarch(ConfigBase):
|
||||
debianarch: list[ConfigDebianarch] = dataclasses.field(
|
||||
default_factory=list, metadata={'merge': 'assoclist'},
|
||||
)
|
||||
|
||||
def __post_init_hierarchy__(self, path: Path) -> None:
|
||||
super().__post_init_hierarchy__(path)
|
||||
|
||||
for debianarch in self.debianarch:
|
||||
debianarch.__post_init_hierarchy__(
|
||||
Path(debianarch.name),
|
||||
)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ConfigDebianarch(ConfigBase):
|
||||
defs: ConfigDebianarchDefs = dataclasses.field(default_factory=ConfigDebianarchDefs)
|
||||
|
||||
featureset: list[ConfigFeatureset] = dataclasses.field(
|
||||
default_factory=list, metadata={'merge': 'assoclist'},
|
||||
)
|
||||
flavour: list[ConfigFlavour] = dataclasses.field(
|
||||
default_factory=list, metadata={'merge': 'assoclist'},
|
||||
)
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
self.defs.__post_init_defs__(self)
|
||||
|
||||
def __post_init_hierarchy__(self, path: Path) -> None:
|
||||
super().__post_init_hierarchy__(path)
|
||||
|
||||
for featureset in self.featureset:
|
||||
featureset.__post_init_hierarchy_featureset__(
|
||||
Path(path / featureset.name),
|
||||
self,
|
||||
)
|
||||
|
||||
for flavour in self.flavour:
|
||||
flavour.__post_init_hierarchy__(path)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ConfigFeatureset(ConfigBase):
|
||||
flavour: list[ConfigFlavour] = dataclasses.field(default_factory=list)
|
||||
|
||||
def __post_init_hierarchy__(self, path: Path) -> None:
|
||||
super().__post_init_hierarchy__(path)
|
||||
|
||||
for flavour in self.flavour:
|
||||
flavour.__post_init_hierarchy__(path)
|
||||
|
||||
def __post_init_hierarchy_featureset__(
|
||||
self,
|
||||
path: Path,
|
||||
debianarch: Optional[ConfigDebianarch],
|
||||
) -> None:
|
||||
# If we have no flavours defined within a featureset, we copy it from debianarch
|
||||
if not self.flavour and debianarch:
|
||||
self.flavour = [
|
||||
ConfigFlavour(name=flavour.name, defs=flavour.defs)
|
||||
for flavour in debianarch.flavour
|
||||
]
|
||||
|
||||
if self.flavour:
|
||||
# XXX: Remove special case of name
|
||||
if self.name == 'none':
|
||||
flavour_default = [i for i in self.flavour if i.defs.is_default]
|
||||
flavour_quick = [i for i in self.flavour if i.defs.is_quick]
|
||||
|
||||
if not flavour_quick:
|
||||
flavour_quick = flavour_default or self.flavour[0:1]
|
||||
flavour_quick[0].defs.is_quick = True
|
||||
|
||||
# Flavours in other featuresets can never be default or quick
|
||||
else:
|
||||
for flavour in self.flavour:
|
||||
flavour.defs.is_default = False
|
||||
flavour.defs.is_quick = False
|
||||
|
||||
self.__post_init_hierarchy__(path)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ConfigFlavour(ConfigBase):
|
||||
defs: ConfigFlavourDefs = dataclasses.field(default_factory=ConfigFlavourDefs)
|
||||
|
||||
def __post_init_hierarchy__(self, path: Path) -> None:
|
||||
self.path = path
|
||||
self.build.config_default = [path / f'config.{self.name}']
|
||||
|
||||
|
||||
class ConfigMergedBase:
|
||||
_entries: list[ConfigBase]
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._entries = []
|
||||
|
||||
@property
|
||||
def enable(self) -> bool:
|
||||
for entry in self._entries:
|
||||
if not entry.enable:
|
||||
return False
|
||||
return True
|
||||
|
||||
@property
|
||||
def build(self) -> ConfigBuild:
|
||||
return dataclasses_extra.merge_default(
|
||||
ConfigBuild, *(i.build for i in self._entries)
|
||||
)
|
||||
|
||||
@property
|
||||
def config(self) -> list[Path]:
|
||||
ret: list[Path] = []
|
||||
for entry in self._entries:
|
||||
ret += entry.build.config + entry.build.config_default
|
||||
return ret
|
||||
|
||||
@property
|
||||
def description(self) -> ConfigDescription:
|
||||
return dataclasses_extra.merge_default(
|
||||
ConfigDescription, *(i.description for i in self._entries)
|
||||
)
|
||||
|
||||
@property
|
||||
def packages(self) -> ConfigPackages:
|
||||
return dataclasses_extra.merge_default(
|
||||
ConfigPackages, *(i.packages for i in self._entries)
|
||||
)
|
||||
|
||||
@property
|
||||
def relations(self) -> ConfigRelations:
|
||||
return dataclasses_extra.merge_default(
|
||||
ConfigRelations, *(i.relations for i in self._entries)
|
||||
)
|
||||
|
||||
|
||||
class ConfigMerged(ConfigMergedBase):
|
||||
_root: Config
|
||||
|
||||
def __init__(
|
||||
self, *,
|
||||
root: Optional[ConfigBase],
|
||||
**kw: Optional[ConfigBase],
|
||||
) -> None:
|
||||
super().__init__(**kw)
|
||||
|
||||
assert isinstance(root, Config)
|
||||
self._root = root
|
||||
self._entries.append(root)
|
||||
|
||||
@property
|
||||
def root_featuresets(self) -> Iterable[ConfigMergedFeatureset]:
|
||||
for featureset in self._root.featureset:
|
||||
yield ConfigMergedFeatureset(
|
||||
root=self._root,
|
||||
root_featureset=None,
|
||||
kernelarch=None,
|
||||
debianarch=None,
|
||||
debianarch_flavour=None,
|
||||
featureset=featureset,
|
||||
)
|
||||
|
||||
@property
|
||||
def kernelarchs(self) -> Iterable[ConfigMergedKernelarch]:
|
||||
for kernelarch in self._root.kernelarch:
|
||||
yield ConfigMergedKernelarch(
|
||||
root=self._root,
|
||||
kernelarch=kernelarch,
|
||||
)
|
||||
|
||||
@property
|
||||
def debianreleases(self) -> Iterable[ConfigDebianrelease]:
|
||||
return self._root.debianrelease
|
||||
|
||||
|
||||
class ConfigMergedKernelarch(ConfigMerged):
|
||||
_kernelarch: ConfigKernelarch
|
||||
|
||||
def __init__(
|
||||
self, *,
|
||||
kernelarch: Optional[ConfigBase],
|
||||
**kw: Optional[ConfigBase],
|
||||
) -> None:
|
||||
super().__init__(**kw)
|
||||
|
||||
if kernelarch is not None:
|
||||
assert isinstance(kernelarch, ConfigKernelarch)
|
||||
self._kernelarch = kernelarch
|
||||
self._entries.append(kernelarch)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return self._kernelarch.name
|
||||
|
||||
@property
|
||||
def name_kernelarch(self) -> str:
|
||||
return self._kernelarch.name
|
||||
|
||||
@property
|
||||
def debianarchs(self) -> Iterable[ConfigMergedDebianarch]:
|
||||
for debianarch in self._kernelarch.debianarch:
|
||||
yield ConfigMergedDebianarch(
|
||||
root=self._root,
|
||||
kernelarch=self._kernelarch,
|
||||
debianarch=debianarch,
|
||||
)
|
||||
|
||||
|
||||
class ConfigMergedDebianarch(ConfigMergedKernelarch):
|
||||
_debianarch: ConfigDebianarch
|
||||
|
||||
def __init__(
|
||||
self, *,
|
||||
debianarch: Optional[ConfigBase],
|
||||
**kw: Optional[ConfigBase],
|
||||
) -> None:
|
||||
super().__init__(**kw)
|
||||
|
||||
if debianarch is not None:
|
||||
assert isinstance(debianarch, ConfigDebianarch)
|
||||
self._debianarch = debianarch
|
||||
self._entries.append(debianarch)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return self._debianarch.name
|
||||
|
||||
@property
|
||||
def name_debianarch(self) -> str:
|
||||
return self._debianarch.name
|
||||
|
||||
@property
|
||||
def defs_debianarch(self) -> ConfigDebianarchDefs:
|
||||
return self._debianarch.defs
|
||||
|
||||
@property
|
||||
def featuresets(self) -> Iterable[ConfigMergedFeatureset]:
|
||||
root_featureset = {
|
||||
i.name: i
|
||||
for i in self._root.featureset
|
||||
}
|
||||
|
||||
for featureset in self._debianarch.featureset:
|
||||
yield ConfigMergedFeatureset(
|
||||
root=self._root,
|
||||
root_featureset=root_featureset[featureset.name],
|
||||
kernelarch=self._kernelarch,
|
||||
debianarch=self._debianarch,
|
||||
debianarch_flavour=None,
|
||||
featureset=featureset,
|
||||
)
|
||||
|
||||
|
||||
class ConfigMergedFeatureset(ConfigMergedDebianarch):
|
||||
_featureset: ConfigFeatureset
|
||||
_root_featureset: Optional[ConfigFeatureset] = None
|
||||
_debianarch_flavour: Optional[ConfigFlavour] = None
|
||||
|
||||
def __init__(
|
||||
self, *,
|
||||
featureset: Optional[ConfigBase],
|
||||
root_featureset: Optional[ConfigBase],
|
||||
debianarch_flavour: Optional[ConfigBase],
|
||||
**kw: Optional[ConfigBase],
|
||||
) -> None:
|
||||
super().__init__(**kw)
|
||||
|
||||
if debianarch_flavour is not None:
|
||||
assert isinstance(debianarch_flavour, ConfigFlavour)
|
||||
self._debianarch_flavour = debianarch_flavour
|
||||
self._entries.append(debianarch_flavour)
|
||||
|
||||
if root_featureset is not None:
|
||||
assert isinstance(root_featureset, ConfigFeatureset)
|
||||
self._root_featureset = root_featureset
|
||||
self._entries.append(root_featureset)
|
||||
|
||||
if featureset is not None:
|
||||
assert isinstance(featureset, ConfigFeatureset)
|
||||
self._featureset = featureset
|
||||
self._entries.append(featureset)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return self._featureset.name
|
||||
|
||||
@property
|
||||
def name_featureset(self) -> str:
|
||||
return self._featureset.name
|
||||
|
||||
@property
|
||||
def flavours(self) -> Iterable[ConfigMergedFlavour]:
|
||||
debianarch_flavour = {
|
||||
i.name: i
|
||||
for i in self._debianarch.flavour
|
||||
}
|
||||
|
||||
for flavour in self._featureset.flavour:
|
||||
yield ConfigMergedFlavour(
|
||||
root=self._root,
|
||||
root_featureset=self._root_featureset,
|
||||
kernelarch=self._kernelarch,
|
||||
debianarch=self._debianarch,
|
||||
debianarch_flavour=debianarch_flavour[flavour.name],
|
||||
featureset=self._featureset,
|
||||
flavour=flavour,
|
||||
)
|
||||
|
||||
|
||||
class ConfigMergedFlavour(ConfigMergedFeatureset):
|
||||
_flavour: ConfigFlavour
|
||||
|
||||
def __init__(
|
||||
self, *,
|
||||
flavour: Optional[ConfigBase],
|
||||
**kw: Optional[ConfigBase],
|
||||
) -> None:
|
||||
super().__init__(**kw)
|
||||
|
||||
if flavour is not None:
|
||||
assert isinstance(flavour, ConfigFlavour)
|
||||
self._flavour = flavour
|
||||
self._entries.append(flavour)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return self._flavour.name
|
||||
|
||||
@property
|
||||
def name_flavour(self) -> str:
|
||||
return self._flavour.name
|
||||
|
||||
@property
|
||||
def defs_flavour(self) -> ConfigFlavourDefs:
|
||||
return self._flavour.defs
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
'dir',
|
||||
default=[Path('debian/config')],
|
||||
nargs='+',
|
||||
type=Path,
|
||||
)
|
||||
args = parser.parse_args()
|
||||
config = Config.read_orig(args.dir)
|
||||
merged = config.merged
|
||||
|
||||
# from pprint import pprint
|
||||
# pprint(config)
|
||||
|
||||
def print_indent(indent: int, s: str, *args: str) -> None:
|
||||
print(' ' * indent * 4 + s, *args)
|
||||
|
||||
for kernelarch in merged.kernelarchs:
|
||||
print_indent(
|
||||
0,
|
||||
f'Kernelarch: {kernelarch.name}',
|
||||
f'enable={kernelarch.enable}',
|
||||
)
|
||||
|
||||
for debianarch in kernelarch.debianarchs:
|
||||
print_indent(
|
||||
1,
|
||||
f'Debianarch: {debianarch.name}',
|
||||
f'enable={debianarch.enable}',
|
||||
)
|
||||
|
||||
for featureset in debianarch.featuresets:
|
||||
print_indent(
|
||||
2,
|
||||
f'Featureset: {featureset.name}',
|
||||
f'enable={featureset.enable}',
|
||||
)
|
||||
|
||||
for flavour in featureset.flavours:
|
||||
print_indent(
|
||||
3,
|
||||
f'Flavour: {flavour.name}',
|
||||
f'enable={flavour.enable}',
|
||||
f'is_default={flavour.defs_flavour.is_default}',
|
||||
)
|
||||
print_indent(4, f'Config: {" ".join(str(i) for i in flavour.config)}')
|
||||
|
||||
else:
|
||||
print()
|
Loading…
Add table
Add a link
Reference in a new issue