Skip to content

Commit 0aca992

Browse files
authored
Migrate UI to textual (archlinux#3997)
* Footer textual * Linting * Revert pre-commit for pylint * Add missing textual * Reinstate example * Linting
1 parent 9a38b73 commit 0aca992

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+2370
-1197
lines changed

.github/workflows/python-build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
pacman --noconfirm -Sy archlinux-keyring
1919
pacman --noconfirm -Syyu
2020
pacman --noconfirm -Sy python-uv python-setuptools python-pip
21-
pacman --noconfirm -Sy python-pyparted python-pydantic
21+
pacman --noconfirm -Sy python-pyparted python-pydantic python-textual
2222
- name: Remove existing archinstall (if any)
2323
run:
2424
uv pip uninstall archinstall --break-system-packages --system

.github/workflows/python-publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
pacman-key --init
2525
pacman --noconfirm -Sy archlinux-keyring
2626
pacman --noconfirm -Syyu
27-
pacman --noconfirm -Sy python python-uv python-setuptools python-pip python-pyparted python-pydantic
27+
pacman --noconfirm -Sy python python-uv python-setuptools python-pip python-pyparted python-pydantic python-textual
2828
- name: Build archinstall
2929
run: |
3030
uv build --no-build-isolation --wheel

.pre-commit-config.yaml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,12 @@ repos:
4343
- pytest
4444
- cryptography
4545
- textual
46-
- repo: https://github.com/pycqa/pylint
47-
rev: v4.0.4
46+
- repo: local
4847
hooks:
49-
- id: pylint
50-
fail_fast: true
51-
require_serial: true
48+
- id: pylint
49+
name: pylint
50+
entry: pylint
51+
language: system
52+
types: [python]
53+
fail_fast: true
54+
require_serial: true

archinstall/__init__.py

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,16 @@
88

99
from archinstall.lib.args import arch_config_handler
1010
from archinstall.lib.disk.utils import disk_layouts
11+
from archinstall.lib.general import running_from_host
1112
from archinstall.lib.network.wifi_handler import wifi_handler
1213
from archinstall.lib.networking import ping
13-
from archinstall.lib.packages.packages import check_package_upgrade
14-
from archinstall.tui.ui.components import tui as ttui
14+
from archinstall.lib.packages.packages import check_version_upgrade
1515

16-
from .lib.general import running_from_host
1716
from .lib.hardware import SysInfo
1817
from .lib.output import FormattedOutput, debug, error, info, log, warn
1918
from .lib.pacman import Pacman
2019
from .lib.plugins import load_plugin, plugins
2120
from .lib.translationhandler import Language, tr, translation_handler
22-
from .tui.curses_menu import Tui
2321

2422

2523
# @archinstall.plugin decorator hook to programmatically add
@@ -66,21 +64,6 @@ def _fetch_arch_db() -> None:
6664
sys.exit(1)
6765

6866

69-
def check_version_upgrade() -> str | None:
70-
info('Checking version...')
71-
upgrade = None
72-
73-
upgrade = check_package_upgrade('archinstall')
74-
75-
if upgrade is None:
76-
debug('No archinstall upgrades found')
77-
return None
78-
79-
text = tr('New version available') + f': {upgrade}'
80-
info(text)
81-
return text
82-
83-
8467
def main() -> int:
8568
"""
8669
This can either be run as the compiled and installed application: python setup.py install
@@ -97,18 +80,16 @@ def main() -> int:
9780

9881
_log_sys_info()
9982

100-
ttui.global_header = 'Archinstall'
101-
10283
if not arch_config_handler.args.offline:
10384
_check_online()
10485
_fetch_arch_db()
10586

10687
if not arch_config_handler.args.skip_version_check:
107-
new_version = check_version_upgrade()
88+
upgrade = check_version_upgrade()
10889

109-
if new_version:
110-
ttui.global_header = f'{ttui.global_header} {new_version}'
111-
info(new_version)
90+
if upgrade:
91+
text = tr('New version available') + f': {upgrade}'
92+
info(text)
11293
time.sleep(3)
11394

11495
if running_from_host():
@@ -135,9 +116,6 @@ def run_as_a_module() -> None:
135116
except Exception as e:
136117
exc = e
137118
finally:
138-
# restore the terminal to the original state
139-
Tui.shutdown()
140-
141119
if exc:
142120
err = ''.join(traceback.format_exception(exc))
143121
error(err)
@@ -159,7 +137,6 @@ def run_as_a_module() -> None:
159137
'Language',
160138
'Pacman',
161139
'SysInfo',
162-
'Tui',
163140
'arch_config_handler',
164141
'debug',
165142
'disk_layouts',

archinstall/default_profiles/desktop.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33
from typing import TYPE_CHECKING, Self, override
44

55
from archinstall.default_profiles.profile import GreeterType, Profile, ProfileType, SelectResult
6+
from archinstall.lib.menu.helpers import Selection
67
from archinstall.lib.output import info
78
from archinstall.lib.profile.profiles_handler import profile_handler
8-
from archinstall.tui.curses_menu import SelectMenu
9-
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
10-
from archinstall.tui.result import ResultType
11-
from archinstall.tui.types import FrameProperties, PreviewStyle
9+
from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
10+
from archinstall.tui.ui.result import ResultType
1211

1312
if TYPE_CHECKING:
1413
from archinstall.lib.installer import Installer
@@ -62,23 +61,21 @@ def do_on_select(self) -> SelectResult:
6261
MenuItem(
6362
p.name,
6463
value=p,
65-
preview_action=lambda x: x.value.preview_text(),
64+
preview_action=lambda x: x.value.preview_text() if x.value else None,
6665
)
6766
for p in profile_handler.get_desktop_profiles()
6867
]
6968

7069
group = MenuItemGroup(items, sort_items=True, sort_case_sensitive=False)
7170
group.set_selected_by_value(self.current_selection)
7271

73-
result = SelectMenu[Self](
72+
result = Selection[Self](
7473
group,
7574
multi=True,
7675
allow_reset=True,
7776
allow_skip=True,
78-
preview_style=PreviewStyle.RIGHT,
79-
preview_size='auto',
80-
preview_frame=FrameProperties.max('Info'),
81-
).run()
77+
preview_location='right',
78+
).show()
8279

8380
match result.type_:
8481
case ResultType.Selection:

archinstall/default_profiles/desktops/hyprland.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
from archinstall.default_profiles.desktops import SeatAccess
44
from archinstall.default_profiles.profile import GreeterType, ProfileType
55
from archinstall.default_profiles.xorg import XorgProfile
6+
from archinstall.lib.menu.helpers import Selection
67
from archinstall.lib.translationhandler import tr
7-
from archinstall.tui.curses_menu import SelectMenu
8-
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
9-
from archinstall.tui.result import ResultType
10-
from archinstall.tui.types import Alignment, FrameProperties
8+
from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
9+
from archinstall.tui.ui.result import ResultType
1110

1211

1312
class HyprlandProfile(XorgProfile):
@@ -57,13 +56,11 @@ def _ask_seat_access(self) -> None:
5756
default = self.custom_settings.get('seat_access', None)
5857
group.set_default_by_value(default)
5958

60-
result = SelectMenu[SeatAccess](
59+
result = Selection[SeatAccess](
6160
group,
6261
header=header,
6362
allow_skip=False,
64-
frame=FrameProperties.min(tr('Seat access')),
65-
alignment=Alignment.CENTER,
66-
).run()
63+
).show()
6764

6865
if result.type_ == ResultType.Selection:
6966
self.custom_settings['seat_access'] = result.get_value().value

archinstall/default_profiles/desktops/labwc.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
from archinstall.default_profiles.desktops import SeatAccess
44
from archinstall.default_profiles.profile import GreeterType, ProfileType
55
from archinstall.default_profiles.xorg import XorgProfile
6+
from archinstall.lib.menu.helpers import Selection
67
from archinstall.lib.translationhandler import tr
7-
from archinstall.tui.curses_menu import SelectMenu
8-
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
9-
from archinstall.tui.result import ResultType
10-
from archinstall.tui.types import Alignment, FrameProperties
8+
from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
9+
from archinstall.tui.ui.result import ResultType
1110

1211

1312
class LabwcProfile(XorgProfile):
@@ -54,13 +53,11 @@ def _ask_seat_access(self) -> None:
5453
default = self.custom_settings.get('seat_access', None)
5554
group.set_default_by_value(default)
5655

57-
result = SelectMenu[SeatAccess](
56+
result = Selection[SeatAccess](
5857
group,
5958
header=header,
6059
allow_skip=False,
61-
frame=FrameProperties.min(tr('Seat access')),
62-
alignment=Alignment.CENTER,
63-
).run()
60+
).show()
6461

6562
if result.type_ == ResultType.Selection:
6663
self.custom_settings['seat_access'] = result.get_value().value

archinstall/default_profiles/desktops/niri.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
from archinstall.default_profiles.desktops import SeatAccess
44
from archinstall.default_profiles.profile import GreeterType, ProfileType
55
from archinstall.default_profiles.xorg import XorgProfile
6+
from archinstall.lib.menu.helpers import Selection
67
from archinstall.lib.translationhandler import tr
7-
from archinstall.tui.curses_menu import SelectMenu
8-
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
9-
from archinstall.tui.result import ResultType
10-
from archinstall.tui.types import Alignment, FrameProperties
8+
from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
9+
from archinstall.tui.ui.result import ResultType
1110

1211

1312
class NiriProfile(XorgProfile):
@@ -62,13 +61,11 @@ def _ask_seat_access(self) -> None:
6261
default = self.custom_settings.get('seat_access', None)
6362
group.set_default_by_value(default)
6463

65-
result = SelectMenu[SeatAccess](
64+
result = Selection[SeatAccess](
6665
group,
6766
header=header,
6867
allow_skip=False,
69-
frame=FrameProperties.min(tr('Seat access')),
70-
alignment=Alignment.CENTER,
71-
).run()
68+
).show()
7269

7370
if result.type_ == ResultType.Selection:
7471
self.custom_settings['seat_access'] = result.get_value().value

archinstall/default_profiles/desktops/sway.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
from archinstall.default_profiles.desktops import SeatAccess
44
from archinstall.default_profiles.profile import GreeterType, ProfileType
55
from archinstall.default_profiles.xorg import XorgProfile
6+
from archinstall.lib.menu.helpers import Selection
67
from archinstall.lib.translationhandler import tr
7-
from archinstall.tui.curses_menu import SelectMenu
8-
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
9-
from archinstall.tui.result import ResultType
10-
from archinstall.tui.types import Alignment, FrameProperties
8+
from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
9+
from archinstall.tui.ui.result import ResultType
1110

1211

1312
class SwayProfile(XorgProfile):
@@ -64,13 +63,11 @@ def _ask_seat_access(self) -> None:
6463
default = self.custom_settings.get('seat_access', None)
6564
group.set_default_by_value(default)
6665

67-
result = SelectMenu[SeatAccess](
66+
result = Selection[SeatAccess](
6867
group,
6968
header=header,
7069
allow_skip=False,
71-
frame=FrameProperties.min(tr('Seat access')),
72-
alignment=Alignment.CENTER,
73-
).run()
70+
).show()
7471

7572
if result.type_ == ResultType.Selection:
7673
self.custom_settings['seat_access'] = result.get_value().value

archinstall/default_profiles/server.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33
from typing import TYPE_CHECKING, Self, override
44

55
from archinstall.default_profiles.profile import Profile, ProfileType, SelectResult
6+
from archinstall.lib.menu.helpers import Selection
67
from archinstall.lib.output import info
78
from archinstall.lib.profile.profiles_handler import profile_handler
8-
from archinstall.tui.curses_menu import SelectMenu
9-
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
10-
from archinstall.tui.result import ResultType
11-
from archinstall.tui.types import FrameProperties, PreviewStyle
9+
from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup
10+
from archinstall.tui.ui.result import ResultType
1211

1312
if TYPE_CHECKING:
1413
from archinstall.lib.installer import Installer
@@ -28,23 +27,21 @@ def do_on_select(self) -> SelectResult:
2827
MenuItem(
2928
p.name,
3029
value=p,
31-
preview_action=lambda x: x.value.preview_text(),
30+
preview_action=lambda x: x.value.preview_text() if x.value else None,
3231
)
3332
for p in profile_handler.get_server_profiles()
3433
]
3534

3635
group = MenuItemGroup(items, sort_items=True)
3736
group.set_selected_by_value(self.current_selection)
3837

39-
result = SelectMenu[Self](
38+
result = Selection[Self](
4039
group,
4140
allow_reset=True,
4241
allow_skip=True,
43-
preview_style=PreviewStyle.RIGHT,
44-
preview_size='auto',
45-
preview_frame=FrameProperties.max('Info'),
4642
multi=True,
47-
).run()
43+
preview_location='right',
44+
).show()
4845

4946
match result.type_:
5047
case ResultType.Selection:

0 commit comments

Comments
 (0)