flavours/cli: colorise output, add -j/--json arg

This commit is contained in:
InsanePrawn 2023-01-05 19:17:10 +01:00
parent 69c73e41dd
commit f140fa36ce
2 changed files with 64 additions and 11 deletions

View file

@ -1,20 +1,54 @@
import click import click
import logging
from .flavour import get_flavours from json import dumps
from config.state import config
from utils import colors_supported, color_str
from .flavour import get_flavours, get_profile_flavour
profile_option = click.option('-p', '--profile', help="name of the profile to use", required=False, default=None) profile_option = click.option('-p', '--profile', help="name of the profile to use", required=False, default=None)
@click.command(name='flavours') @click.command(name='flavours')
def cmd_flavours(): @click.option('-j', '--json', is_flag=True, help='output machine-parsable JSON format')
def cmd_flavours(json: bool = False):
'list information about available flavours' 'list information about available flavours'
results = []
profile_flavour = None
flavours = get_flavours() flavours = get_flavours()
use_colors = colors_supported(config.runtime.colors)
if not flavours: if not flavours:
raise Exception("No flavours found!") raise Exception("No flavours found!")
if not json:
try:
profile_flavour = get_profile_flavour()
except Exception as ex:
logging.debug(f"Failed to get profile flavour for marking as currently selected, continuing anyway. Exception: {ex}")
for name in sorted(flavours.keys()): for name in sorted(flavours.keys()):
f = flavours[name] f = flavours[name]
try: try:
f.parse_flavourinfo() f.parse_flavourinfo()
except: except Exception as ex:
pass logging.debug(f"A problem happened while parsing flavourinfo for {name}, continuing anyway. Exception: {ex}")
print(f) if not json:
block = [*f.nice_str(newlines=True, colors=use_colors).split('\n'), '']
if profile_flavour == f:
prefix = color_str('>>> ', bold=True, fg='bright_green', use_colors=use_colors)
block += [
color_str("Currently selected by profile ", bold=True, use_colors=use_colors) +
color_str(f'"{config.file.profiles.current}"\n', bold=True, fg="bright_green")
]
block = [prefix + line for line in block]
results += block
else:
f.pkgbuild = f.pkgbuild.name if f.pkgbuild else None
d = dict(f)
results += [d]
print()
if json:
print(dumps({r['name']: r for r in results}, indent=4))
else:
for r in results:
print(r)

View file

@ -4,16 +4,16 @@ import json
import logging import logging
import os import os
from dataclasses import dataclass
from typing import Optional from typing import Optional
from config.state import config from config.state import config
from constants import FLAVOUR_DESCRIPTION_PREFIX, FLAVOUR_INFO_FILE from constants import FLAVOUR_DESCRIPTION_PREFIX, FLAVOUR_INFO_FILE
from dataclass import DataClass
from packages.pkgbuild import discover_pkgbuilds, get_pkgbuild_by_name, init_pkgbuilds, Pkgbuild from packages.pkgbuild import discover_pkgbuilds, get_pkgbuild_by_name, init_pkgbuilds, Pkgbuild
from utils import color_str
@dataclass class FlavourInfo(DataClass):
class FlavourInfo:
rootfs_size: int # rootfs size in GB rootfs_size: int # rootfs size in GB
description: Optional[str] description: Optional[str]
@ -21,8 +21,7 @@ class FlavourInfo:
return f'rootfs_size: {self.rootfs_size}' return f'rootfs_size: {self.rootfs_size}'
@dataclass class Flavour(DataClass):
class Flavour:
name: str name: str
pkgbuild: Pkgbuild pkgbuild: Pkgbuild
description: str description: str
@ -43,7 +42,27 @@ class Flavour:
return Flavour(name=name, pkgbuild=pkgbuild, description=description.strip(), flavour_info=None) return Flavour(name=name, pkgbuild=pkgbuild, description=description.strip(), flavour_info=None)
def __repr__(self): def __repr__(self):
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 ""}' 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 __str__(self):
return self.nice_str()
def nice_str(self, newlines: bool = False, colors: bool = False) -> str:
separator = '\n' if newlines else ', '
def get_lines(k, v, key_prefix=''):
results = []
full_k = f'{key_prefix}.{k}' if key_prefix else k
if not isinstance(v, (dict, DataClass)):
results = [f'{color_str(full_k, bold=True)}: {v}']
else:
for _k, _v in v.items():
if _k.startswith('_'):
continue
results += get_lines(_k, _v, key_prefix=full_k)
return results
return separator.join(get_lines(None, self))
def parse_flavourinfo(self, lazy: bool = True): def parse_flavourinfo(self, lazy: bool = True):
if lazy and self.flavour_info is not None: if lazy and self.flavour_info is not None: