Skip to content

Commit d906ba7

Browse files
committed
Update
1 parent a172799 commit d906ba7

3 files changed

Lines changed: 112 additions & 28 deletions

File tree

archinstall/default_profiles/desktops/plasma.py

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,67 @@
1-
from enum import Enum
1+
from enum import StrEnum
22
from typing import override
33

44
from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType
55
from archinstall.lib.menu.helpers import Selection
6+
from archinstall.lib.packages.packages import available_package, package_group_info
67
from archinstall.lib.translationhandler import tr
78
from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
89
from archinstall.tui.ui.result import ResultType
910

1011

11-
class PlasmaFlavor(Enum):
12-
Plasma = 'plasma'
12+
class PlasmaFlavor(StrEnum):
1313
Meta = 'plasma-meta'
14+
Plasma = 'plasma'
1415
Desktop = 'plasma-desktop'
1516

1617
def show(self) -> str:
1718
match self:
18-
case PlasmaFlavor.Plasma:
19-
desc = tr('Extensive KDE Plasma installation')
2019
case PlasmaFlavor.Meta:
20+
return f'({tr("Recommended")}) {self.value}'
21+
case PlasmaFlavor.Plasma | PlasmaFlavor.Desktop:
22+
return self.value
23+
24+
def package_details(self) -> str:
25+
ty = ''
26+
details = ''
27+
desc = ''
28+
29+
match self:
30+
case PlasmaFlavor.Meta:
31+
ty = tr('Package')
2132
desc = tr('Curated selection of KDE Plasma packages')
33+
info = available_package(self.value)
34+
35+
if info is not None:
36+
details = tr('Dependencies') + '\n'
37+
details += '\n'.join(f'- {entry}' for entry in info.get_depends_on)
38+
case PlasmaFlavor.Plasma:
39+
ty = tr('Package group')
40+
desc = tr('Extensive KDE Plasma installation')
41+
group = package_group_info(self.value)
42+
43+
if group is not None:
44+
details = tr('Packages in group') + '\n'
45+
details += '\n'.join(f'- {entry}' for entry in group.packages)
2246
case PlasmaFlavor.Desktop:
47+
ty = tr('Package group')
2348
desc = tr('Minimal KDE Plasma installation')
24-
case _:
25-
raise ValueError(f'Unknown Plasma flavor: {self}')
49+
info = available_package(self.value)
2650

27-
return f'{self.value}: {desc}'
51+
if info is not None:
52+
details = tr('Dependencies') + '\n'
53+
details += '\n'.join(f'- {entry}' for entry in info.get_depends_on)
54+
55+
return f'{tr("Type")}: {ty}\n{tr("Description")}: {desc}\n\n{details}'
56+
57+
def packages(self) -> list[str]:
58+
match self:
59+
case PlasmaFlavor.Meta:
60+
return ['plasma-meta']
61+
case PlasmaFlavor.Plasma:
62+
return ['plasma']
63+
case PlasmaFlavor.Desktop:
64+
return ['plasma-desktop']
2865

2966

3067
class PlasmaProfile(Profile):
@@ -39,22 +76,13 @@ def __init__(self) -> None:
3976
@property
4077
@override
4178
def packages(self) -> list[str]:
42-
flavor_str = self.custom_settings.get(CustomSetting.PlasmaFlavor, PlasmaFlavor.Plasma.value)
43-
flavor = PlasmaFlavor(flavor_str)
79+
flavor_str = self.custom_settings.get(CustomSetting.PlasmaFlavor)
4480

45-
match flavor:
46-
case PlasmaFlavor.Plasma:
47-
return [
48-
'plasma',
49-
]
50-
case PlasmaFlavor.Meta:
51-
return [
52-
'plasma-meta',
53-
]
54-
case PlasmaFlavor.Desktop:
55-
return [
56-
'plasma-desktop',
57-
]
81+
if flavor_str is not None:
82+
flavor = PlasmaFlavor(flavor_str)
83+
return flavor.packages()
84+
else:
85+
return PlasmaFlavor.Meta.packages() # use plasma-meta as the recommended default
5886

5987
@property
6088
@override
@@ -64,7 +92,14 @@ def default_greeter_type(self) -> GreeterType:
6492
async def _select_flavor(self) -> None:
6593
header = tr('Select a flavor of KDE Plasma to install') + '\n'
6694

67-
items = [MenuItem(s.show(), value=s) for s in PlasmaFlavor]
95+
items = [
96+
MenuItem(
97+
s.show(),
98+
value=s,
99+
preview_action=lambda x: x.value.package_details() if x.value else None,
100+
)
101+
for s in PlasmaFlavor
102+
]
68103
group = MenuItemGroup(items, sort_items=False)
69104

70105
default = self.custom_settings.get(CustomSetting.PlasmaFlavor, None)
@@ -74,6 +109,7 @@ async def _select_flavor(self) -> None:
74109
group,
75110
header=header,
76111
allow_skip=False,
112+
preview_location='right',
77113
).show()
78114

79115
if result.type_ == ResultType.Selection:

archinstall/lib/models/packages.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,26 @@ def info(self) -> str:
142142

143143
return output
144144

145+
@cached_property
146+
def get_depends_on(self) -> list[str]:
147+
return [entry.strip() for entry in self.depends_on.split(' ') if entry.strip()]
148+
149+
@cached_property
150+
def get_optional_deps(self) -> list[str]:
151+
return [entry.strip() for entry in self.optional_deps.split(' ') if entry.strip()]
152+
145153

146154
@dataclass
147155
class PackageGroup:
148156
name: str
149157
packages: list[str] = field(default_factory=list)
150158

159+
@classmethod
160+
def from_package_group_output(cls, data: list[str]) -> Self:
161+
name = data[0].split()[0].strip()
162+
packages = [line.split()[1].strip() for line in data if line.strip()]
163+
return cls(name, packages)
164+
151165
@classmethod
152166
def from_available_packages(
153167
cls,

archinstall/lib/packages/packages.py

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,34 @@ def check_package_upgrade(package: str) -> str | None:
3434
return None
3535

3636

37+
@lru_cache
38+
def package_group_info(package: str) -> PackageGroup | None:
39+
try:
40+
package_info: list[str] = []
41+
for line in Pacman.run(f'-Sg {package}'):
42+
package_info.append(line.decode().strip())
43+
group = PackageGroup.from_package_group_output(package_info)
44+
return group
45+
except SysCallError:
46+
debug(f'Failed to get package info: {package}')
47+
48+
return None
49+
50+
51+
@lru_cache
52+
def available_package(package: str) -> AvailablePackage | None:
53+
try:
54+
package_info: list[str] = []
55+
for line in Pacman.run(f'-S --info {package}'):
56+
package_info.append(line.decode().strip())
57+
58+
return _parse_package_output(package_info, AvailablePackage)
59+
except SysCallError:
60+
pass
61+
62+
return None
63+
64+
3765
@lru_cache
3866
def list_available_packages(
3967
repositories: tuple[Repository, ...],
@@ -74,12 +102,18 @@ def _parse_package_output[PackageType: (AvailablePackage, LocalPackage)](
74102
cls: type[PackageType],
75103
) -> PackageType:
76104
package = {}
105+
current_key = None
77106

78107
for line in package_meta:
79-
if ':' in line:
80-
key, value = line.split(':', 1)
81-
key = _normalize_key_name(key)
82-
package[key] = value.strip()
108+
if not line.strip():
109+
continue
110+
111+
if ':' in line and not line.startswith(' '):
112+
key_raw, value = line.split(':', 1)
113+
current_key = _normalize_key_name(key_raw)
114+
package[current_key] = value.strip()
115+
elif current_key:
116+
package[current_key] += ' ' + line.strip()
83117

84118
return cls.model_validate(package)
85119

0 commit comments

Comments
 (0)