2022-09-08 19:07:51 +02:00
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
import click
|
2022-09-20 16:36:58 +02:00
|
|
|
import json
|
2022-09-08 19:07:51 +02:00
|
|
|
import logging
|
2022-09-20 16:36:58 +02:00
|
|
|
import os
|
2022-09-08 19:07:51 +02:00
|
|
|
|
|
|
|
from dataclasses import dataclass
|
|
|
|
from typing import Optional
|
|
|
|
|
|
|
|
from config import config
|
2022-09-20 16:36:58 +02:00
|
|
|
from constants import FLAVOUR_INFO_FILE
|
2022-09-08 19:07:51 +02:00
|
|
|
|
|
|
|
from .pkgbuild import discover_pkgbuilds, get_pkgbuild_by_name, init_pkgbuilds, Pkgbuild
|
|
|
|
|
2022-09-17 19:05:54 +02:00
|
|
|
profile_option = click.option('-p', '--profile', help="name of the profile to use", required=False, default=None)
|
|
|
|
|
2022-09-08 19:07:51 +02:00
|
|
|
|
2022-09-20 16:36:58 +02:00
|
|
|
@dataclass
|
|
|
|
class FlavourInfo:
|
|
|
|
rootfs_size: int # rootfs size in GB
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return f'rootfs_size: {self.rootfs_size}'
|
|
|
|
|
|
|
|
|
2022-09-08 19:07:51 +02:00
|
|
|
@dataclass
|
|
|
|
class Flavour:
|
|
|
|
name: str
|
|
|
|
pkgbuild: Pkgbuild
|
|
|
|
description: str
|
2022-09-20 16:36:58 +02:00
|
|
|
flavour_info: Optional[FlavourInfo]
|
2022-09-08 19:07:51 +02:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def from_pkgbuild(pkgbuild: Pkgbuild) -> Flavour:
|
|
|
|
name = pkgbuild.name
|
|
|
|
if not name.startswith('flavour-'):
|
|
|
|
raise Exception(f'Flavour package "{name}" doesn\'t start with "flavour-": "{name}"')
|
|
|
|
if name.endswith('-common'):
|
|
|
|
raise Exception(f'Flavour package "{name}" ends with "-common": "{name}"')
|
|
|
|
name = name[8:] # split off 'flavour-'
|
2022-09-20 16:36:58 +02:00
|
|
|
return Flavour(name=name, pkgbuild=pkgbuild, description=pkgbuild.description, flavour_info=None)
|
2022-09-08 19:07:51 +02:00
|
|
|
|
|
|
|
def __repr__(self):
|
2022-09-20 16:36:58 +02:00
|
|
|
return f'Flavour "{self.name}": "{self.description}", package: {self.pkgbuild.name if self.pkgbuild else "??? PROBABLY A BUG!"}{f", {self.flavour_info}" if self.flavour_info else ""}'
|
|
|
|
|
|
|
|
def parse_flavourinfo(self, lazy: bool = True):
|
|
|
|
if lazy and self.flavour_info is not None:
|
|
|
|
return self.flavour_info
|
|
|
|
infopath = os.path.join(config.get_path('pkgbuilds'), self.pkgbuild.path, FLAVOUR_INFO_FILE)
|
|
|
|
if not os.path.exists(infopath):
|
|
|
|
raise Exception(f"Error parsing flavour info for flavour {self.name}: file doesn't exist: {infopath}")
|
|
|
|
try:
|
|
|
|
with open(infopath, 'r') as fd:
|
|
|
|
infodict = json.load(fd)
|
|
|
|
i = FlavourInfo(**infodict)
|
|
|
|
except Exception as ex:
|
|
|
|
raise Exception(f"Error parsing {FLAVOUR_INFO_FILE} for flavour {self.name}: {ex}")
|
|
|
|
self.flavour_info = i
|
|
|
|
return i
|
2022-09-08 19:07:51 +02:00
|
|
|
|
|
|
|
|
|
|
|
_flavours_discovered: bool = False
|
|
|
|
_flavours_cache: dict[str, Flavour] = {}
|
|
|
|
|
|
|
|
|
|
|
|
def get_flavours(lazy: bool = True):
|
|
|
|
global _flavours_cache, _flavours_discovered
|
|
|
|
if lazy and _flavours_discovered:
|
|
|
|
return _flavours_cache
|
2022-09-09 01:35:18 +02:00
|
|
|
logging.info("Searching PKGBUILDs for flavour packages")
|
2022-09-08 19:07:51 +02:00
|
|
|
flavours: dict[str, Flavour] = {}
|
|
|
|
pkgbuilds: dict[str, Pkgbuild] = discover_pkgbuilds(lazy=(lazy or not _flavours_discovered))
|
|
|
|
for pkg in pkgbuilds.values():
|
|
|
|
name = pkg.name
|
|
|
|
if not name.startswith('flavour-') or name.endswith('-common'):
|
|
|
|
continue
|
|
|
|
name = name[8:] # split off 'flavour-'
|
|
|
|
logging.info(f"Found flavour package {name}")
|
|
|
|
flavours[name] = Flavour.from_pkgbuild(pkg)
|
|
|
|
_flavours_cache.clear()
|
|
|
|
_flavours_cache.update(flavours)
|
|
|
|
_flavours_discovered = True
|
|
|
|
return flavours
|
|
|
|
|
|
|
|
|
|
|
|
def get_flavour(name: str, lazy: bool = True):
|
|
|
|
global _flavours_cache
|
|
|
|
pkg_name = f'flavour-{name}'
|
|
|
|
if lazy and name in _flavours_cache:
|
|
|
|
return _flavours_cache[name]
|
|
|
|
try:
|
|
|
|
logging.info(f"Trying to find PKGBUILD for flavour {name}")
|
|
|
|
init_pkgbuilds()
|
|
|
|
pkg = get_pkgbuild_by_name(pkg_name)
|
|
|
|
except Exception as ex:
|
|
|
|
raise Exception(f"Error parsing PKGBUILD for flavour package {pkg_name}:\n{ex}")
|
|
|
|
assert pkg and pkg.name == pkg_name
|
|
|
|
flavour = Flavour.from_pkgbuild(pkg)
|
|
|
|
_flavours_cache[name] = flavour
|
|
|
|
return flavour
|
|
|
|
|
|
|
|
|
|
|
|
def get_profile_flavour(profile_name: Optional[str] = None) -> Flavour:
|
|
|
|
profile = config.enforce_profile_flavour_set(profile_name=profile_name)
|
|
|
|
return get_flavour(profile.flavour)
|
|
|
|
|
|
|
|
|
|
|
|
@click.command(name='list')
|
|
|
|
def cmd_flavours_list():
|
|
|
|
'list information about available flavours'
|
|
|
|
flavours = get_flavours()
|
2022-09-14 04:13:40 +02:00
|
|
|
if not flavours:
|
|
|
|
raise Exception("No flavours found!")
|
2022-09-08 19:07:51 +02:00
|
|
|
for f in flavours.values():
|
|
|
|
print(f)
|