Add new version indicator in the title of the main menu (#3587)

* Add new version indicator in the title of the main menu

* Update
This commit is contained in:
Daniel Girtler 2025-06-12 07:14:30 +10:00 committed by GitHub
parent 7b3b7c9ebf
commit 063b9643b4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 73 additions and 35 deletions

View File

@ -8,6 +8,7 @@ import traceback
from archinstall.lib.args import arch_config_handler
from archinstall.lib.disk.utils import disk_layouts
from archinstall.lib.packages.packages import check_package_upgrade
from .lib.hardware import SysInfo
from .lib.output import FormattedOutput, debug, error, info, log, warn
@ -53,15 +54,15 @@ def _check_new_version() -> None:
info('Checking version...')
upgrade = None
try:
upgrade = Pacman.run('-Qu archinstall').decode()
except Exception as e:
debug(f'Failed determine pacman version: {e}')
upgrade = check_package_upgrade('archinstall')
if upgrade:
text = f'New version available: {upgrade}'
info(text)
time.sleep(3)
if upgrade is None:
debug('No archinstall upgrades found')
return None
text = tr('New version available') + f': {upgrade}'
info(text)
time.sleep(3)
def main() -> int:

View File

@ -94,8 +94,8 @@ class DiskLayoutConfigurationMenu(AbstractSubMenu[DiskLayoutConfiguration]):
]
@override
def run(self) -> DiskLayoutConfiguration | None:
super().run()
def run(self, additional_title: str | None = None) -> DiskLayoutConfiguration | None:
super().run(additional_title=additional_title)
if self._disk_menu_config.disk_config:
self._disk_menu_config.disk_config.lvm_config = self._disk_menu_config.lvm_config

View File

@ -115,8 +115,8 @@ class DiskEncryptionMenu(AbstractSubMenu[DiskEncryption]):
return False
@override
def run(self) -> DiskEncryption | None:
super().run()
def run(self, additional_title: str | None = None) -> DiskEncryption | None:
super().run(additional_title=additional_title)
enc_type: EncryptionType | None = self._item_group.find_by_key('encryption_type').value
enc_password: Password | None = self._item_group.find_by_key('encryption_password').value

View File

@ -60,8 +60,11 @@ class LocaleMenu(AbstractSubMenu[LocaleConfiguration]):
return temp_locale.preview()
@override
def run(self) -> LocaleConfiguration:
super().run()
def run(
self,
additional_title: str | None = None,
) -> LocaleConfiguration:
super().run(additional_title=additional_title)
return self._locale_conf
def _select_kb_layout(self, preset: str | None) -> str | None:

View File

@ -94,7 +94,10 @@ class AbstractMenu[ValueT]:
def _is_config_valid(self) -> bool:
return True
def run(self) -> ValueT | None:
def run(
self,
additional_title: str | None = None,
) -> ValueT | None:
self._sync_from_config()
while True:
@ -106,6 +109,7 @@ class AbstractMenu[ValueT]:
preview_style=PreviewStyle.RIGHT,
preview_size='auto',
preview_frame=FrameProperties('Info', FrameStyle.MAX),
additional_title=additional_title,
).run()
match result.type_:

View File

@ -296,8 +296,8 @@ class MirrorMenu(AbstractSubMenu[MirrorConfiguration]):
return output.strip()
@override
def run(self) -> MirrorConfiguration:
super().run()
def run(self, additional_title: str | None = None) -> MirrorConfiguration:
super().run(additional_title=additional_title)
return self._mirror_config

View File

@ -105,7 +105,6 @@ def validate_package_list(packages: list[str]) -> tuple[list[str], list[str]]:
def installed_package(package: str) -> LocalPackage | None:
package_info = []
try:
package_info = Pacman.run(f'-Q --info {package}').decode().split('\n')
return _parse_package_output(package_info, LocalPackage)
@ -115,6 +114,17 @@ def installed_package(package: str) -> LocalPackage | None:
return None
@lru_cache
def check_package_upgrade(package: str) -> str | None:
try:
upgrade = Pacman.run(f'-Qu {package}').decode()
return upgrade
except SysCallError:
debug(f'Failed to check for package upgrades: {package}')
return None
@lru_cache
def list_available_packages(
repositories: tuple[Repository],

View File

@ -64,8 +64,8 @@ class ProfileMenu(AbstractSubMenu[ProfileConfiguration]):
]
@override
def run(self) -> ProfileConfiguration | None:
super().run()
def run(self, additional_title: str | None = None) -> ProfileConfiguration | None:
super().run(additional_title=additional_title)
return self._profile_config
def _select_profile(self, preset: Profile | None) -> Profile | None:

View File

@ -16,7 +16,9 @@ from archinstall.lib.models.device_model import (
)
from archinstall.lib.models.users import User
from archinstall.lib.output import debug, error, info
from archinstall.lib.packages.packages import check_package_upgrade
from archinstall.lib.profile.profiles_handler import profile_handler
from archinstall.lib.translationhandler import tr
from archinstall.tui import Tui
@ -27,13 +29,20 @@ def ask_user_questions() -> None:
will we continue with the actual installation steps.
"""
title_text = None
upgrade = check_package_upgrade('archinstall')
if upgrade:
text = tr('New version available') + f': {upgrade}'
title_text = f' ({text})'
with Tui():
global_menu = GlobalMenu(arch_config_handler.config)
if not arch_config_handler.args.advanced:
global_menu.set_enabled('parallel_downloads', False)
global_menu.run()
global_menu.run(additional_title=title_text)
def perform_installation(mountpoint: Path) -> None:

View File

@ -82,8 +82,8 @@ class AbstractCurses[ValueT](metaclass=ABCMeta):
return False
def help_entry(self) -> ViewportEntry:
return ViewportEntry(tr('Press Ctrl+h for help'), 0, 0, STYLE.NORMAL)
def help_text(self) -> str:
return tr('Press Ctrl+h for help')
def _show_help(self) -> None:
help_text = Help.get_help_text()
@ -488,7 +488,7 @@ class EditMenu(AbstractCurses[str]):
title = f'* {title}' if not self._allow_skip else title
self._frame = FrameProperties(title, FrameStyle.MAX)
self._help_vp: Viewport | None = None
self._title_vp: Viewport | None = None
self._header_vp: Viewport | None = None
self._input_vp: EditViewport | None = None
self._info_vp: Viewport | None = None
@ -507,7 +507,7 @@ class EditMenu(AbstractCurses[str]):
def _init_viewports(self) -> None:
y_offset = 0
self._help_vp = Viewport(self._max_width, 2, 0, y_offset)
self._title_vp = Viewport(self._max_width, 2, 0, y_offset)
y_offset += 2
if self._header_entries:
@ -543,8 +543,8 @@ class EditMenu(AbstractCurses[str]):
self._draw()
def _clear_all(self) -> None:
if self._help_vp:
self._help_vp.erase()
if self._title_vp:
self._title_vp.erase()
if self._header_vp:
self._header_vp.erase()
if self._input_vp:
@ -572,8 +572,10 @@ class EditMenu(AbstractCurses[str]):
return text
def _draw(self) -> None:
if self._help_vp:
self._help_vp.update([self.help_entry()], 0)
if self._title_vp:
help_text = self.help_text()
help_entry = ViewportEntry(help_text, 0, 0, STYLE.NORMAL)
self._title_vp.update([help_entry], 0)
if self._header_entries and self._header_vp:
self._header_vp.update(self._header_entries, 0)
@ -692,6 +694,7 @@ class SelectMenu[ValueT](AbstractCurses[ValueT]):
preview_style: PreviewStyle = PreviewStyle.NONE,
preview_size: float | Literal['auto'] = 0.2,
preview_frame: FrameProperties | None = None,
additional_title: str | None = None,
):
super().__init__()
@ -712,6 +715,7 @@ class SelectMenu[ValueT](AbstractCurses[ValueT]):
self._frame = frame
self._interrupt_warning = reset_warning_msg
self._header = header
self._additional_title = additional_title
self._header_entries = []
if header:
@ -730,7 +734,7 @@ class SelectMenu[ValueT](AbstractCurses[ValueT]):
self._visible_entries: list[ViewportEntry] = []
self._max_height, self._max_width = Tui.t().max_yx
self._help_vp: Viewport | None = None
self._title_vp: Viewport | None = None
self._header_vp: Viewport | None = None
self._footer_vp: Viewport | None = None
self._menu_vp: Viewport | None = None
@ -787,8 +791,8 @@ class SelectMenu[ValueT](AbstractCurses[ValueT]):
self._preview_vp.erase()
if self._footer_vp:
self._footer_vp.erase()
if self._help_vp:
self._help_vp.erase()
if self._title_vp:
self._title_vp.erase()
def _footer_entries(self) -> list[ViewportEntry]:
if self._active_search:
@ -801,7 +805,7 @@ class SelectMenu[ValueT](AbstractCurses[ValueT]):
footer_height = 2 # possible filter at the bottom
y_offset = 0
self._help_vp = Viewport(self._max_width, 2, 0, y_offset)
self._title_vp = Viewport(self._max_width, 2, 0, y_offset)
y_offset += 2
if self._header_entries:
@ -933,8 +937,15 @@ class SelectMenu[ValueT](AbstractCurses[ValueT]):
items = self._items_state.get_view_items()
vp_entries = self._item_to_vp_entry(items)
if self._help_vp:
self._update_viewport(self._help_vp, [self.help_entry()])
if self._title_vp:
title_text = self.help_text()
if self._additional_title is not None:
title_text += f' {self._additional_title}'
title_vp_entry = ViewportEntry(title_text, 0, 0, STYLE.NORMAL)
self._update_viewport(self._title_vp, [title_vp_entry])
if self._header_vp:
self._update_viewport(self._header_vp, self._header_entries)