From ba5a190100ee05c62ee1b9df3110683a4a92d909 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Tue, 7 Apr 2026 22:38:45 +1000 Subject: [PATCH 1/5] Flexible plasma profile selection --- .../default_profiles/desktops/hyprland.py | 10 +-- .../default_profiles/desktops/labwc.py | 12 +-- archinstall/default_profiles/desktops/niri.py | 12 +-- .../default_profiles/desktops/plasma.py | 74 ++++++++++++++++--- archinstall/default_profiles/desktops/sway.py | 12 +-- archinstall/default_profiles/profile.py | 11 ++- archinstall/lib/profile/profiles_handler.py | 42 +++++------ 7 files changed, 115 insertions(+), 58 deletions(-) diff --git a/archinstall/default_profiles/desktops/hyprland.py b/archinstall/default_profiles/desktops/hyprland.py index 84b94aa0bf..fa0bc5810b 100644 --- a/archinstall/default_profiles/desktops/hyprland.py +++ b/archinstall/default_profiles/desktops/hyprland.py @@ -1,7 +1,7 @@ from typing import override from archinstall.default_profiles.desktops import SeatAccess -from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType +from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType from archinstall.lib.menu.helpers import Selection from archinstall.lib.translationhandler import tr from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup @@ -17,7 +17,7 @@ def __init__(self) -> None: display_server=DisplayServerType.Wayland, ) - self.custom_settings = {'seat_access': None} + self.custom_settings = {CustomSetting.SeatAccess: None} @property @override @@ -45,7 +45,7 @@ def default_greeter_type(self) -> GreeterType: @property @override def services(self) -> list[str]: - if pref := self.custom_settings.get('seat_access', None): + if pref := self.custom_settings.get(CustomSetting.SeatAccess, None): return [pref] return [] @@ -57,7 +57,7 @@ async def _select_seat_access(self) -> None: items = [MenuItem(s.value, value=s) for s in SeatAccess] group = MenuItemGroup(items, sort_items=True) - default = self.custom_settings.get('seat_access', None) + default = self.custom_settings.get(CustomSetting.SeatAccess, None) group.set_default_by_value(default) result = await Selection[SeatAccess]( @@ -67,7 +67,7 @@ async def _select_seat_access(self) -> None: ).show() if result.type_ == ResultType.Selection: - self.custom_settings['seat_access'] = result.get_value().value + self.custom_settings[CustomSetting.SeatAccess] = result.get_value().value @override async def do_on_select(self) -> None: diff --git a/archinstall/default_profiles/desktops/labwc.py b/archinstall/default_profiles/desktops/labwc.py index d109ef13eb..bf4a32975c 100644 --- a/archinstall/default_profiles/desktops/labwc.py +++ b/archinstall/default_profiles/desktops/labwc.py @@ -1,7 +1,7 @@ from typing import override from archinstall.default_profiles.desktops import SeatAccess -from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType +from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType from archinstall.lib.menu.helpers import Selection from archinstall.lib.translationhandler import tr from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup @@ -17,13 +17,13 @@ def __init__(self) -> None: display_server=DisplayServerType.Wayland, ) - self.custom_settings = {'seat_access': None} + self.custom_settings = {CustomSetting.SeatAccess: None} @property @override def packages(self) -> list[str]: additional = [] - if seat := self.custom_settings.get('seat_access', None): + if seat := self.custom_settings.get(CustomSetting.SeatAccess, None): additional = [seat] return [ @@ -39,7 +39,7 @@ def default_greeter_type(self) -> GreeterType: @property @override def services(self) -> list[str]: - if pref := self.custom_settings.get('seat_access', None): + if pref := self.custom_settings.get(CustomSetting.SeatAccess, None): return [pref] return [] @@ -51,7 +51,7 @@ async def _select_seat_access(self) -> None: items = [MenuItem(s.value, value=s) for s in SeatAccess] group = MenuItemGroup(items, sort_items=True) - default = self.custom_settings.get('seat_access', None) + default = self.custom_settings.get(CustomSetting.SeatAccess, None) group.set_default_by_value(default) result = await Selection[SeatAccess]( @@ -61,7 +61,7 @@ async def _select_seat_access(self) -> None: ).show() if result.type_ == ResultType.Selection: - self.custom_settings['seat_access'] = result.get_value().value + self.custom_settings[CustomSetting.SeatAccess] = result.get_value().value @override async def do_on_select(self) -> None: diff --git a/archinstall/default_profiles/desktops/niri.py b/archinstall/default_profiles/desktops/niri.py index b05f306821..347290fed0 100644 --- a/archinstall/default_profiles/desktops/niri.py +++ b/archinstall/default_profiles/desktops/niri.py @@ -1,7 +1,7 @@ from typing import override from archinstall.default_profiles.desktops import SeatAccess -from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType +from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType from archinstall.lib.menu.helpers import Selection from archinstall.lib.translationhandler import tr from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup @@ -17,13 +17,13 @@ def __init__(self) -> None: display_server=DisplayServerType.Wayland, ) - self.custom_settings = {'seat_access': None} + self.custom_settings = {CustomSetting.SeatAccess: None} @property @override def packages(self) -> list[str]: additional = [] - if seat := self.custom_settings.get('seat_access', None): + if seat := self.custom_settings.get(CustomSetting.SeatAccess, None): additional = [seat] return [ @@ -47,7 +47,7 @@ def default_greeter_type(self) -> GreeterType: @property @override def services(self) -> list[str]: - if pref := self.custom_settings.get('seat_access', None): + if pref := self.custom_settings.get(CustomSetting.SeatAccess, None): return [pref] return [] @@ -59,7 +59,7 @@ async def _select_seat_access(self) -> None: items = [MenuItem(s.value, value=s) for s in SeatAccess] group = MenuItemGroup(items, sort_items=True) - default = self.custom_settings.get('seat_access', None) + default = self.custom_settings.get(CustomSetting.SeatAccess, None) group.set_default_by_value(default) result = await Selection[SeatAccess]( @@ -69,7 +69,7 @@ async def _select_seat_access(self) -> None: ).show() if result.type_ == ResultType.Selection: - self.custom_settings['seat_access'] = result.get_value().value + self.custom_settings[CustomSetting.SeatAccess] = result.get_value().value @override async def do_on_select(self) -> None: diff --git a/archinstall/default_profiles/desktops/plasma.py b/archinstall/default_profiles/desktops/plasma.py index 81f9fa785b..ec9cc9498f 100644 --- a/archinstall/default_profiles/desktops/plasma.py +++ b/archinstall/default_profiles/desktops/plasma.py @@ -1,6 +1,30 @@ +from enum import Enum from typing import override -from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType +from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType +from archinstall.lib.menu.helpers import Selection +from archinstall.lib.translationhandler import tr +from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.ui.result import ResultType + + +class PlasmaFlavor(Enum): + Plasma = 'plasma' + Meta = 'plasma-meta' + Desktop = 'plasma-desktop' + + def show(self) -> str: + match self: + case PlasmaFlavor.Plasma: + desc = tr('Extensive KDE Plasma installation') + case PlasmaFlavor.Meta: + desc = tr('Curated selection of KDE Plasma packages') + case PlasmaFlavor.Desktop: + desc = tr('Minimal KDE Plasma installation') + case _: + raise ValueError(f'Unknown Plasma flavor: {self}') + + return f'{self.value}: {desc}' class PlasmaProfile(Profile): @@ -15,18 +39,46 @@ def __init__(self) -> None: @property @override def packages(self) -> list[str]: - return [ - 'plasma-desktop', - 'kscreen', - 'plasma-pa', - 'konsole', - 'kate', - 'dolphin', - 'ark', - 'plasma-workspace', - ] + flavor_str = self.custom_settings.get(CustomSetting.PlasmaFlavor, PlasmaFlavor.Plasma.value) + flavor = PlasmaFlavor(flavor_str) + + match flavor: + case PlasmaFlavor.Plasma: + return [ + 'plasma', + ] + case PlasmaFlavor.Meta: + return [ + 'plasma-meta', + ] + case PlasmaFlavor.Desktop: + return [ + 'plasma-desktop', + ] @property @override def default_greeter_type(self) -> GreeterType: return GreeterType.PlasmaLoginManager + + async def _select_flavor(self) -> None: + header = tr('Select a flavor of KDE Plasma to install') + '\n' + + items = [MenuItem(s.show(), value=s) for s in PlasmaFlavor] + group = MenuItemGroup(items, sort_items=False) + + default = self.custom_settings.get(CustomSetting.PlasmaFlavor, None) + group.set_default_by_value(default) + + result = await Selection[PlasmaFlavor]( + group, + header=header, + allow_skip=False, + ).show() + + if result.type_ == ResultType.Selection: + self.custom_settings[CustomSetting.PlasmaFlavor] = result.get_value().value + + @override + async def do_on_select(self) -> None: + await self._select_flavor() diff --git a/archinstall/default_profiles/desktops/sway.py b/archinstall/default_profiles/desktops/sway.py index 09a8e7fd29..5d22230762 100644 --- a/archinstall/default_profiles/desktops/sway.py +++ b/archinstall/default_profiles/desktops/sway.py @@ -1,7 +1,7 @@ from typing import override from archinstall.default_profiles.desktops import SeatAccess -from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType +from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType from archinstall.lib.menu.helpers import Selection from archinstall.lib.translationhandler import tr from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup @@ -17,13 +17,13 @@ def __init__(self) -> None: display_server=DisplayServerType.Wayland, ) - self.custom_settings = {'seat_access': None} + self.custom_settings = {CustomSetting.SeatAccess: None} @property @override def packages(self) -> list[str]: additional = [] - if seat := self.custom_settings.get('seat_access', None): + if seat := self.custom_settings.get(CustomSetting.SeatAccess, None): additional = [seat] return [ @@ -49,7 +49,7 @@ def default_greeter_type(self) -> GreeterType: @property @override def services(self) -> list[str]: - if pref := self.custom_settings.get('seat_access', None): + if pref := self.custom_settings.get(CustomSetting.SeatAccess, None): return [pref] return [] @@ -61,7 +61,7 @@ async def _select_seat_access(self) -> None: items = [MenuItem(s.value, value=s) for s in SeatAccess] group = MenuItemGroup(items, sort_items=True) - default = self.custom_settings.get('seat_access', None) + default = self.custom_settings.get(CustomSetting.SeatAccess, None) group.set_default_by_value(default) result = await Selection[SeatAccess]( @@ -71,7 +71,7 @@ async def _select_seat_access(self) -> None: ).show() if result.type_ == ResultType.Selection: - self.custom_settings['seat_access'] = result.get_value().value + self.custom_settings[CustomSetting.SeatAccess] = result.get_value().value @override async def do_on_select(self) -> None: diff --git a/archinstall/default_profiles/profile.py b/archinstall/default_profiles/profile.py index d7a4326096..bced68cf3a 100644 --- a/archinstall/default_profiles/profile.py +++ b/archinstall/default_profiles/profile.py @@ -1,6 +1,6 @@ from __future__ import annotations -from enum import Enum, auto +from enum import Enum, StrEnum, auto from typing import TYPE_CHECKING, Self from archinstall.lib.translationhandler import tr @@ -47,6 +47,11 @@ class SelectResult(Enum): ResetCurrent = auto() +class CustomSetting(StrEnum): + SeatAccess = 'seat_access' + PlasmaFlavor = 'plasma_flavor' + + class Profile: def __init__( self, @@ -61,7 +66,7 @@ def __init__( ) -> None: self.name = name self.profile_type = profile_type - self.custom_settings: dict[str, str | None] = {} + self.custom_settings: dict[CustomSetting, str | None] = {} self._support_gfx_driver = support_gfx_driver self._support_greeter = support_greeter @@ -130,7 +135,7 @@ async def do_on_select(self) -> SelectResult | None: """ return SelectResult.NewSelection - def set_custom_settings(self, settings: dict[str, str | None]) -> None: + def set_custom_settings(self, settings: dict[CustomSetting, str | None]) -> None: """ Set the custom settings for the profile. This is also called when the settings are parsed from the config diff --git a/archinstall/lib/profile/profiles_handler.py b/archinstall/lib/profile/profiles_handler.py index 47e358aaa7..1e193475b5 100644 --- a/archinstall/lib/profile/profiles_handler.py +++ b/archinstall/lib/profile/profiles_handler.py @@ -9,7 +9,7 @@ from types import ModuleType from typing import TYPE_CHECKING, NotRequired, TypedDict -from archinstall.default_profiles.profile import GreeterType, Profile +from archinstall.default_profiles.profile import CustomSetting, GreeterType, Profile from archinstall.lib.hardware import GfxDriver, GfxPackage from archinstall.lib.models.profile import ProfileConfiguration from archinstall.lib.networking import fetch_data_from_url @@ -23,7 +23,7 @@ class ProfileSerialization(TypedDict): main: NotRequired[str] details: NotRequired[list[str]] - custom_settings: NotRequired[dict[str, dict[str, str | None]]] + custom_settings: NotRequired[dict[str, dict[CustomSetting, str | None]]] path: NotRequired[str] @@ -76,27 +76,27 @@ def parse_profile_config(self, profile_config: ProfileSerialization) -> Profile self._import_profile_from_url(url_path) # if custom := profile_config.get('custom', None): - # from archinstall.default_profiles.custom import CustomTypeProfile - # custom_types = [] + # from archinstall.default_profiles.custom import CustomTypeProfile + # custom_types = [] # - # for entry in custom: - # custom_types.append( - # CustomTypeProfile( - # entry['name'], - # entry['enabled'], - # entry.get('packages', []), - # entry.get('services', []) - # ) - # ) + # for entry in custom: + # custom_types.append( + # CustomTypeProfile( + # entry['name'], + # entry['enabled'], + # entry.get('packages', []), + # entry.get('services', []) + # ) + # ) # - # self.remove_custom_profiles(custom_types) - # self.add_custom_profiles(custom_types) + # self.remove_custom_profiles(custom_types) + # self.add_custom_profiles(custom_types) # - # # this doesn't mean it's actual going to be set as a selection - # # but we are simply populating the custom profile with all - # # possible custom definitions - # if custom_profile := self.get_profile_by_name('Custom'): - # custom_profile.set_current_selection(custom_types) + # # this doesn't mean it's actual going to be set as a selection + # # but we are simply populating the custom profile with all + # # possible custom definitions + # if custom_profile := self.get_profile_by_name('Custom'): + # custom_profile.set_current_selection(custom_types) if main := profile_config.get('main', None): profile = self.get_profile_by_name(main) if main else None @@ -111,7 +111,7 @@ def parse_profile_config(self, profile_config: ProfileSerialization) -> Profile if details: for detail in filter(None, details): # [2024-04-19] TODO: Backwards compatibility after naming change: https://github.com/archlinux/archinstall/pull/2421 - # 'Kde' is deprecated, remove this block in a future version + # 'Kde' is deprecated, remove this block in a future version if detail == 'Kde': detail = 'KDE Plasma' From a172799d7c6de87b36bc997988336a8e16b8daf8 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Tue, 7 Apr 2026 22:39:42 +1000 Subject: [PATCH 2/5] Update --- archinstall/lib/profile/profiles_handler.py | 23 --------------------- 1 file changed, 23 deletions(-) diff --git a/archinstall/lib/profile/profiles_handler.py b/archinstall/lib/profile/profiles_handler.py index 1e193475b5..0cf8e2723c 100644 --- a/archinstall/lib/profile/profiles_handler.py +++ b/archinstall/lib/profile/profiles_handler.py @@ -75,29 +75,6 @@ def parse_profile_config(self, profile_config: ProfileSerialization) -> Profile else: self._import_profile_from_url(url_path) - # if custom := profile_config.get('custom', None): - # from archinstall.default_profiles.custom import CustomTypeProfile - # custom_types = [] - # - # for entry in custom: - # custom_types.append( - # CustomTypeProfile( - # entry['name'], - # entry['enabled'], - # entry.get('packages', []), - # entry.get('services', []) - # ) - # ) - # - # self.remove_custom_profiles(custom_types) - # self.add_custom_profiles(custom_types) - # - # # this doesn't mean it's actual going to be set as a selection - # # but we are simply populating the custom profile with all - # # possible custom definitions - # if custom_profile := self.get_profile_by_name('Custom'): - # custom_profile.set_current_selection(custom_types) - if main := profile_config.get('main', None): profile = self.get_profile_by_name(main) if main else None From d906ba7b04370d30a02d2f27dd5bf5da0da228ab Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Thu, 9 Apr 2026 21:35:32 +1000 Subject: [PATCH 3/5] Update --- .../default_profiles/desktops/plasma.py | 84 +++++++++++++------ archinstall/lib/models/packages.py | 14 ++++ archinstall/lib/packages/packages.py | 42 +++++++++- 3 files changed, 112 insertions(+), 28 deletions(-) diff --git a/archinstall/default_profiles/desktops/plasma.py b/archinstall/default_profiles/desktops/plasma.py index ec9cc9498f..f1357199f2 100644 --- a/archinstall/default_profiles/desktops/plasma.py +++ b/archinstall/default_profiles/desktops/plasma.py @@ -1,30 +1,67 @@ -from enum import Enum +from enum import StrEnum from typing import override from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType from archinstall.lib.menu.helpers import Selection +from archinstall.lib.packages.packages import available_package, package_group_info from archinstall.lib.translationhandler import tr from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup from archinstall.tui.ui.result import ResultType -class PlasmaFlavor(Enum): - Plasma = 'plasma' +class PlasmaFlavor(StrEnum): Meta = 'plasma-meta' + Plasma = 'plasma' Desktop = 'plasma-desktop' def show(self) -> str: match self: - case PlasmaFlavor.Plasma: - desc = tr('Extensive KDE Plasma installation') case PlasmaFlavor.Meta: + return f'({tr("Recommended")}) {self.value}' + case PlasmaFlavor.Plasma | PlasmaFlavor.Desktop: + return self.value + + def package_details(self) -> str: + ty = '' + details = '' + desc = '' + + match self: + case PlasmaFlavor.Meta: + ty = tr('Package') desc = tr('Curated selection of KDE Plasma packages') + info = available_package(self.value) + + if info is not None: + details = tr('Dependencies') + '\n' + details += '\n'.join(f'- {entry}' for entry in info.get_depends_on) + case PlasmaFlavor.Plasma: + ty = tr('Package group') + desc = tr('Extensive KDE Plasma installation') + group = package_group_info(self.value) + + if group is not None: + details = tr('Packages in group') + '\n' + details += '\n'.join(f'- {entry}' for entry in group.packages) case PlasmaFlavor.Desktop: + ty = tr('Package group') desc = tr('Minimal KDE Plasma installation') - case _: - raise ValueError(f'Unknown Plasma flavor: {self}') + info = available_package(self.value) - return f'{self.value}: {desc}' + if info is not None: + details = tr('Dependencies') + '\n' + details += '\n'.join(f'- {entry}' for entry in info.get_depends_on) + + return f'{tr("Type")}: {ty}\n{tr("Description")}: {desc}\n\n{details}' + + def packages(self) -> list[str]: + match self: + case PlasmaFlavor.Meta: + return ['plasma-meta'] + case PlasmaFlavor.Plasma: + return ['plasma'] + case PlasmaFlavor.Desktop: + return ['plasma-desktop'] class PlasmaProfile(Profile): @@ -39,22 +76,13 @@ def __init__(self) -> None: @property @override def packages(self) -> list[str]: - flavor_str = self.custom_settings.get(CustomSetting.PlasmaFlavor, PlasmaFlavor.Plasma.value) - flavor = PlasmaFlavor(flavor_str) + flavor_str = self.custom_settings.get(CustomSetting.PlasmaFlavor) - match flavor: - case PlasmaFlavor.Plasma: - return [ - 'plasma', - ] - case PlasmaFlavor.Meta: - return [ - 'plasma-meta', - ] - case PlasmaFlavor.Desktop: - return [ - 'plasma-desktop', - ] + if flavor_str is not None: + flavor = PlasmaFlavor(flavor_str) + return flavor.packages() + else: + return PlasmaFlavor.Meta.packages() # use plasma-meta as the recommended default @property @override @@ -64,7 +92,14 @@ def default_greeter_type(self) -> GreeterType: async def _select_flavor(self) -> None: header = tr('Select a flavor of KDE Plasma to install') + '\n' - items = [MenuItem(s.show(), value=s) for s in PlasmaFlavor] + items = [ + MenuItem( + s.show(), + value=s, + preview_action=lambda x: x.value.package_details() if x.value else None, + ) + for s in PlasmaFlavor + ] group = MenuItemGroup(items, sort_items=False) default = self.custom_settings.get(CustomSetting.PlasmaFlavor, None) @@ -74,6 +109,7 @@ async def _select_flavor(self) -> None: group, header=header, allow_skip=False, + preview_location='right', ).show() if result.type_ == ResultType.Selection: diff --git a/archinstall/lib/models/packages.py b/archinstall/lib/models/packages.py index f08cbfe1e8..6ba6e1348a 100644 --- a/archinstall/lib/models/packages.py +++ b/archinstall/lib/models/packages.py @@ -142,12 +142,26 @@ def info(self) -> str: return output + @cached_property + def get_depends_on(self) -> list[str]: + return [entry.strip() for entry in self.depends_on.split(' ') if entry.strip()] + + @cached_property + def get_optional_deps(self) -> list[str]: + return [entry.strip() for entry in self.optional_deps.split(' ') if entry.strip()] + @dataclass class PackageGroup: name: str packages: list[str] = field(default_factory=list) + @classmethod + def from_package_group_output(cls, data: list[str]) -> Self: + name = data[0].split()[0].strip() + packages = [line.split()[1].strip() for line in data if line.strip()] + return cls(name, packages) + @classmethod def from_available_packages( cls, diff --git a/archinstall/lib/packages/packages.py b/archinstall/lib/packages/packages.py index 28e90bc02c..3572c6c445 100644 --- a/archinstall/lib/packages/packages.py +++ b/archinstall/lib/packages/packages.py @@ -34,6 +34,34 @@ def check_package_upgrade(package: str) -> str | None: return None +@lru_cache +def package_group_info(package: str) -> PackageGroup | None: + try: + package_info: list[str] = [] + for line in Pacman.run(f'-Sg {package}'): + package_info.append(line.decode().strip()) + group = PackageGroup.from_package_group_output(package_info) + return group + except SysCallError: + debug(f'Failed to get package info: {package}') + + return None + + +@lru_cache +def available_package(package: str) -> AvailablePackage | None: + try: + package_info: list[str] = [] + for line in Pacman.run(f'-S --info {package}'): + package_info.append(line.decode().strip()) + + return _parse_package_output(package_info, AvailablePackage) + except SysCallError: + pass + + return None + + @lru_cache def list_available_packages( repositories: tuple[Repository, ...], @@ -74,12 +102,18 @@ def _parse_package_output[PackageType: (AvailablePackage, LocalPackage)]( cls: type[PackageType], ) -> PackageType: package = {} + current_key = None for line in package_meta: - if ':' in line: - key, value = line.split(':', 1) - key = _normalize_key_name(key) - package[key] = value.strip() + if not line.strip(): + continue + + if ':' in line and not line.startswith(' '): + key_raw, value = line.split(':', 1) + current_key = _normalize_key_name(key_raw) + package[current_key] = value.strip() + elif current_key: + package[current_key] += ' ' + line.strip() return cls.model_validate(package) From 7c7cd8bddd403a2a1d013f11b693dfa138ad5b43 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Thu, 9 Apr 2026 21:42:01 +1000 Subject: [PATCH 4/5] Update --- archinstall/default_profiles/desktops/plasma.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archinstall/default_profiles/desktops/plasma.py b/archinstall/default_profiles/desktops/plasma.py index f1357199f2..e90f8a27e2 100644 --- a/archinstall/default_profiles/desktops/plasma.py +++ b/archinstall/default_profiles/desktops/plasma.py @@ -17,7 +17,7 @@ class PlasmaFlavor(StrEnum): def show(self) -> str: match self: case PlasmaFlavor.Meta: - return f'({tr("Recommended")}) {self.value}' + return f'{self.value} ({tr("Recommended")})' case PlasmaFlavor.Plasma | PlasmaFlavor.Desktop: return self.value From cf963f8468ff700433e3049e8e49e9517e2a7549 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Thu, 9 Apr 2026 21:45:24 +1000 Subject: [PATCH 5/5] Update --- tests/test_args.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/test_args.py b/tests/test_args.py index 275ffd86f0..1b052ec0a1 100644 --- a/tests/test_args.py +++ b/tests/test_args.py @@ -4,7 +4,7 @@ from pytest import MonkeyPatch -from archinstall.default_profiles.profile import GreeterType +from archinstall.default_profiles.profile import CustomSetting, GreeterType from archinstall.lib.args import ArchConfig, ArchConfigHandler, Arguments from archinstall.lib.hardware import GfxDriver from archinstall.lib.models.application import ( @@ -173,10 +173,13 @@ def test_config_file_parsing( { 'custom_settings': { 'Hyprland': { - 'seat_access': 'polkit', + CustomSetting.SeatAccess: 'polkit', }, 'Sway': { - 'seat_access': 'seatd', + CustomSetting.SeatAccess: 'seatd', + }, + 'KDE Plasma': { + CustomSetting.PlasmaFlavor: 'plasma-meta', }, }, 'details': [