diff --git a/archinstall/lib/disk/partitioning_menu.py b/archinstall/lib/disk/partitioning_menu.py index 6e784a3045..716b2e1c0a 100644 --- a/archinstall/lib/disk/partitioning_menu.py +++ b/archinstall/lib/disk/partitioning_menu.py @@ -464,7 +464,10 @@ def _validate_value( return size def _prompt_size(self, free_space: FreeSpace) -> Size: - def validate(value: str) -> str | None: + def validate(value: str | None) -> str | None: + if not value: + return None + size = self._validate_value(sector_size, max_size, value) if not size: return tr('Invalid size') diff --git a/archinstall/lib/disk/subvolume_menu.py b/archinstall/lib/disk/subvolume_menu.py index 5b307b8d1e..af448a30e3 100644 --- a/archinstall/lib/disk/subvolume_menu.py +++ b/archinstall/lib/disk/subvolume_menu.py @@ -35,11 +35,17 @@ def selected_action_display(self, selection: SubvolumeModification) -> str: return str(selection.name) def _add_subvolume(self, preset: SubvolumeModification | None = None) -> SubvolumeModification | None: + def validate(value: str | None) -> str | None: + if value: + return None + return tr('Value cannot be empty') + result = EditMenu( tr('Subvolume name'), alignment=Alignment.CENTER, allow_skip=True, default_text=str(preset.name) if preset else None, + validator=validate, ).input() match result.type_: @@ -58,11 +64,12 @@ def _add_subvolume(self, preset: SubvolumeModification | None = None) -> Subvolu tr('Subvolume mountpoint'), header=header, allow_skip=True, - validate=False, + validate=True, + must_exist=False, ) if not path: - return None + return preset return SubvolumeModification(Path(name), path) @@ -81,7 +88,7 @@ def handle_action( # was created we'll replace the existing one data = [d for d in data if d.name != new_subvolume.name] data += [new_subvolume] - elif entry is not None: + elif entry is not None: # edit if action == self._actions[1]: # edit subvolume new_subvolume = self._add_subvolume(entry) diff --git a/archinstall/lib/interactions/general_conf.py b/archinstall/lib/interactions/general_conf.py index a5e92fa119..8f360702f0 100644 --- a/archinstall/lib/interactions/general_conf.py +++ b/archinstall/lib/interactions/general_conf.py @@ -247,13 +247,14 @@ def add_number_of_parallel_downloads(preset: int | None = None) -> int | None: header += tr(' - Maximum recommended value : {} ( Allows {} parallel downloads at a time )').format(max_recommended, max_recommended) + '\n' header += tr(' - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )\n') - def validator(s: str) -> str | None: - try: - value = int(s) - if value >= 0: - return None - except Exception: - pass + def validator(s: str | None) -> str | None: + if s is not None: + try: + value = int(s) + if value >= 0: + return None + except Exception: + pass return tr('Invalid download number') diff --git a/archinstall/lib/interactions/manage_users_conf.py b/archinstall/lib/interactions/manage_users_conf.py index a8b867056d..e6e22db136 100644 --- a/archinstall/lib/interactions/manage_users_conf.py +++ b/archinstall/lib/interactions/manage_users_conf.py @@ -58,9 +58,10 @@ def handle_action(self, action: str, entry: User | None, data: list[User]) -> li return data - def _check_for_correct_username(self, username: str) -> str | None: - if re.match(r'^[a-z_][a-z0-9_-]*\$?$', username) and len(username) <= 32: - return None + def _check_for_correct_username(self, username: str | None) -> str | None: + if username is not None: + if re.match(r'^[a-z_][a-z0-9_-]*\$?$', username) and len(username) <= 32: + return None return tr('The username you entered is invalid') def _add_user(self) -> User | None: diff --git a/archinstall/lib/interactions/network_menu.py b/archinstall/lib/interactions/network_menu.py index 405da5c8d8..3508020353 100644 --- a/archinstall/lib/interactions/network_menu.py +++ b/archinstall/lib/interactions/network_menu.py @@ -87,7 +87,12 @@ def _get_ip_address( multi: bool, preset: str | None = None, ) -> str | None: - def validator(ip: str) -> str | None: + def validator(ip: str | None) -> str | None: + failure = tr('You need to enter a valid IP in IP-config mode') + + if not ip: + return failure + if multi: ips = ip.split(' ') else: @@ -98,7 +103,7 @@ def validator(ip: str) -> str | None: ipaddress.ip_interface(ip) return None except ValueError: - return tr('You need to enter a valid IP in IP-config mode') + return failure result = EditMenu( title, diff --git a/archinstall/lib/utils/util.py b/archinstall/lib/utils/util.py index 4fed4358d7..9d91af5a65 100644 --- a/archinstall/lib/utils/util.py +++ b/archinstall/lib/utils/util.py @@ -2,6 +2,7 @@ from archinstall.lib.translationhandler import tr from archinstall.tui.curses_menu import EditMenu +from archinstall.tui.result import ResultType from archinstall.tui.types import Alignment from ..models.users import Password @@ -64,14 +65,19 @@ def prompt_dir( text: str, header: str | None = None, validate: bool = True, + must_exist: bool = True, allow_skip: bool = False, preset: str | None = None, ) -> Path | None: - def validate_path(path: str) -> str | None: - dest_path = Path(path) + def validate_path(path: str | None) -> str | None: + if path: + dest_path = Path(path) - if dest_path.exists() and dest_path.is_dir(): - return None + if must_exist: + if dest_path.exists() and dest_path.is_dir(): + return None + else: + return None return tr('Not a valid directory') @@ -89,10 +95,15 @@ def validate_path(path: str) -> str | None: default_text=preset, ).input() - if allow_skip and not result.has_item(): - return None + match result.type_: + case ResultType.Skip: + return None + case ResultType.Selection: + if not result.text(): + return None + return Path(result.text()) - return Path(result.text()) + return None def is_subpath(first: Path, second: Path) -> bool: diff --git a/archinstall/tui/curses_menu.py b/archinstall/tui/curses_menu.py index ea46deab2f..60ab7fdaa2 100644 --- a/archinstall/tui/curses_menu.py +++ b/archinstall/tui/curses_menu.py @@ -458,7 +458,7 @@ def __init__( title: str, edit_width: int = 50, header: str | None = None, - validator: Callable[[str], str | None] | None = None, + validator: Callable[[str | None], str | None] | None = None, allow_skip: bool = False, allow_reset: bool = False, reset_warning_msg: str | None = None, @@ -561,7 +561,7 @@ def _get_input_text(self) -> str | None: self.clear_all() - if text and self._validator: + if self._validator: if (err := self._validator(text)) is not None: self.clear_all() entry = ViewportEntry(err, 0, 0, STYLE.ERROR)