Compare commits

...

22 Commits

Author SHA1 Message Date
dw-0
a58288e7e3 Release v6.0.0-alpha.13
Merge develop into master (Release v6.0.0-alpha.13)
2025-01-03 22:13:12 +01:00
dw-0
3852464ab7 fix: use raw strings for regex parameter in get_string_input (#612)
fixes #602

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2025-01-03 22:10:39 +01:00
dw-0
d9626adc98 Release v6.0.0-alpha.12
Merge develop into master (Release v6.0.0-alpha.12)
2024-11-28 19:38:23 +01:00
dw-0
4ae5a37ec6 fix: most recent tag not shown correctly in main menu
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-11-24 21:43:10 +01:00
dw-0
935f81aab6 fix: backup fails in case of dangling symlink
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-11-24 21:26:12 +01:00
dw-0
b02df9a1e0 Release v6.0.0-alpha.11
Merge develop into master (Release v6.0.0-alpha.11)
2024-11-24 15:55:04 +01:00
nlef
dbbc87f18e fix: use correct telegram bot config path (#600)
* fix telegram bot config path

* use _post)init_value

---------

Co-authored-by: dw-0 <th33xitus@gmail.com>
Co-authored-by: dw-0 <domwil1091+github@gmail.com>
2024-11-24 15:53:49 +01:00
dw-0
243ea6582a Release v6.0.0-alpha.10
Merge develop into master (Release v6.0.0-alpha.10)
2024-11-23 21:17:51 +01:00
dw-0
91cba3637e readme: update README.md
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-11-23 21:12:35 +01:00
dw-0
3fc190ff25 fix: actually raise exception on empty config value
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-11-10 21:15:08 +01:00
dw-0
6ff45aab41 refactor: implement basic input validation for repo switch feature
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-11-10 20:58:37 +01:00
dw-0
b9c9feef3c refactor: clone repo in repo switch routine only if there is already a repo present
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-11-10 20:14:47 +01:00
dw-0
d37d047aaa refactor: fallback to config settings for repos in settings menu
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-11-10 19:56:47 +01:00
dw-0
a3fb57aee3 refactor: return - if branch cannot be read
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-11-10 19:54:26 +01:00
dw-0
a63cf8c9d9 Release v6.0.0-alpha.9
Merge develop into master (Release v6.0.0-alpha.9)
2024-10-24 12:29:24 +02:00
dw-0
425d86a12f Release v6.0.0-alpha.8
Merge develop into master (Release v6.0.0-alpha.8)
2024-10-21 19:45:55 +02:00
dw-0
1b5691f2f5 Release v6.0.0-alpha.7
Merge develop into master (v6.0.0-alpha.7)

fixes #561
fixes #564
fixes #565
2024-10-13 11:51:19 +02:00
dw-0
dc026a7a2b Release v6.0.0-alpha.6
Merge develop into master (v6.0.0-alpha.6)

fixes #545
fixes #553
fixes #557
2024-10-05 08:29:40 +02:00
dw-0
a8a73249a5 Release v6.0.0-alpha.5
Merge develop into master (v6.0.0-alpha.5)
2024-09-26 20:55:22 +02:00
dw-0
ec3f93eeda Release v6.0.0-alpha.4
Merge develop into master (v6.0.0-alpha.4)
2024-09-22 09:43:04 +02:00
dw-0
4cf523a758 Merge pull request #524 from dw-0/develop
Merge develop into master
2024-09-08 19:04:19 +02:00
dw-0
1d06bf76f3 Merge pull request #511 from dw-0/develop
Merge develop into master
2024-09-01 19:02:48 +02:00
12 changed files with 149 additions and 97 deletions

110
README.md
View File

@@ -101,77 +101,83 @@ prompt and confirm by hitting ENTER.
<h2 align="center">🌐 Sources & Further Information</h2> <h2 align="center">🌐 Sources & Further Information</h2>
<table> <table align="center">
<tr> <tr>
<th><h3><a href="https://github.com/Klipper3d/klipper">Klipper</a></h3></th> <th><h3><a href="https://github.com/Klipper3d/klipper">Klipper</a></h3></th>
<th><h3><a href="https://github.com/Arksine/moonraker">Moonraker</a></h3></th> <th><h3><a href="https://github.com/Arksine/moonraker">Moonraker</a></h3></th>
<th><h3><a href="https://github.com/mainsail-crew/mainsail">Mainsail</a></h3></th> <th><h3><a href="https://github.com/mainsail-crew/mainsail">Mainsail</a></h3></th>
</tr> </tr>
<tr> <tr>
<th><img src="https://raw.githubusercontent.com/Klipper3d/klipper/master/docs/img/klipper-logo.png" alt="Klipper Logo" height="64"></th> <th><img src="https://raw.githubusercontent.com/Klipper3d/klipper/master/docs/img/klipper-logo.png" alt="Klipper Logo" height="64"></th>
<th><img src="https://avatars.githubusercontent.com/u/9563098?v=4" alt="Arksine avatar" height="64"></th> <th><img src="https://avatars.githubusercontent.com/u/9563098?v=4" alt="Arksine avatar" height="64"></th>
<th><img src="https://raw.githubusercontent.com/mainsail-crew/docs/master/assets/img/logo.png" alt="Mainsail Logo" height="64"></th> <th><img src="https://raw.githubusercontent.com/mainsail-crew/docs/master/assets/img/logo.png" alt="Mainsail Logo" height="64"></th>
</tr> </tr>
<tr> <tr>
<th>by <a href="https://github.com/KevinOConnor">KevinOConnor</a></th> <th>by <a href="https://github.com/KevinOConnor">KevinOConnor</a></th>
<th>by <a href="https://github.com/Arksine">Arksine</a></th> <th>by <a href="https://github.com/Arksine">Arksine</a></th>
<th>by <a href="https://github.com/mainsail-crew">mainsail-crew</a></th> <th>by <a href="https://github.com/mainsail-crew">mainsail-crew</a></th>
</tr>
<tr>
<th><h3><a href="https://github.com/fluidd-core/fluidd">Fluidd</a></h3></th>
<th><h3><a href="https://github.com/jordanruthe/KlipperScreen">KlipperScreen</a></h3></th>
<th><h3><a href="https://github.com/OctoPrint/OctoPrint">OctoPrint</a></h3></th>
</tr>
<tr>
<th><img src="https://raw.githubusercontent.com/fluidd-core/fluidd/master/docs/assets/images/logo.svg" alt="Fluidd Logo" height="64"></th>
<th><img src="https://avatars.githubusercontent.com/u/31575189?v=4" alt="jordanruthe avatar" height="64"></th>
<th><img src="https://raw.githubusercontent.com/OctoPrint/OctoPrint/master/docs/images/octoprint-logo.png" alt="OctoPrint Logo" height="64"></th>
</tr>
<tr>
<th>by <a href="https://github.com/fluidd-core">fluidd-core</a></th>
<th>by <a href="https://github.com/jordanruthe">jordanruthe</a></th>
<th>by <a href="https://github.com/OctoPrint">OctoPrint</a></th>
</tr> </tr>
<tr> <tr>
<th><h3><a href="https://github.com/nlef/moonraker-telegram-bot">Moonraker-Telegram-Bot</a></h3></th> <th><h3><a href="https://github.com/fluidd-core/fluidd">Fluidd</a></h3></th>
<th><h3><a href="https://github.com/Kragrathea/pgcode">PrettyGCode for Klipper</a></h3></th> <th><h3><a href="https://github.com/jordanruthe/KlipperScreen">KlipperScreen</a></h3></th>
<th><h3><a href="https://github.com/TheSpaghettiDetective/moonraker-obico">Obico for Klipper</a></h3></th> <th><h3><a href="https://github.com/OctoPrint/OctoPrint">OctoPrint</a></h3></th>
</tr>
<tr>
<th><img src="https://raw.githubusercontent.com/fluidd-core/fluidd/master/docs/assets/images/logo.svg" alt="Fluidd Logo" height="64"></th>
<th><img src="https://avatars.githubusercontent.com/u/31575189?v=4" alt="jordanruthe avatar" height="64"></th>
<th><img src="https://raw.githubusercontent.com/OctoPrint/OctoPrint/master/docs/images/octoprint-logo.png" alt="OctoPrint Logo" height="64"></th>
</tr>
<tr>
<th>by <a href="https://github.com/fluidd-core">fluidd-core</a></th>
<th>by <a href="https://github.com/jordanruthe">jordanruthe</a></th>
<th>by <a href="https://github.com/OctoPrint">OctoPrint</a></th>
</tr> </tr>
<tr> <tr>
<th><img src="https://avatars.githubusercontent.com/u/52351624?v=4" alt="nlef avatar" height="64"></th> <th><h3><a href="https://github.com/nlef/moonraker-telegram-bot">Moonraker-Telegram-Bot</a></h3></th>
<th><img src="https://avatars.githubusercontent.com/u/5917231?v=4" alt="Kragrathea avatar" height="64"></th> <th><h3><a href="https://github.com/Kragrathea/pgcode">PrettyGCode for Klipper</a></h3></th>
<th><img src="https://avatars.githubusercontent.com/u/46323662?s=200&v=4" alt="Obico logo" height="64"></th> <th><h3><a href="https://github.com/TheSpaghettiDetective/moonraker-obico">Obico for Klipper</a></h3></th>
</tr>
<tr>
<th><img src="https://avatars.githubusercontent.com/u/52351624?v=4" alt="nlef avatar" height="64"></th>
<th><img src="https://avatars.githubusercontent.com/u/5917231?v=4" alt="Kragrathea avatar" height="64"></th>
<th><img src="https://avatars.githubusercontent.com/u/46323662?s=200&v=4" alt="Obico logo" height="64"></th>
</tr>
<tr>
<th>by <a href="https://github.com/nlef">nlef</a></th>
<th>by <a href="https://github.com/Kragrathea">Kragrathea</a></th>
<th>by <a href="https://github.com/TheSpaghettiDetective">Obico</a></th>
</tr> </tr>
<tr> <tr>
<th>by <a href="https://github.com/nlef">nlef</a></th> <th><h3><a href="https://github.com/Clon1998/mobileraker_companion">Mobileraker's Companion</a></h3></th>
<th>by <a href="https://github.com/Kragrathea">Kragrathea</a></th> <th><h3><a href="https://octoeverywhere.com/?source=kiauh_readme">OctoEverywhere For Klipper</a></h3></th>
<th>by <a href="https://github.com/TheSpaghettiDetective">Obico</a></th> <th><h3><a href="https://github.com/crysxd/OctoApp-Plugin">OctoApp For Klipper</a></h3></th>
</tr>
<tr>
<th><a href="https://github.com/Clon1998/mobileraker_companion"><img src="https://raw.githubusercontent.com/Clon1998/mobileraker/master/assets/icon/mr_appicon.png" alt="Mobileraker Logo" height="64"></a></th>
<th><a href="https://octoeverywhere.com/?source=kiauh_readme"><img src="https://octoeverywhere.com/img/logo.svg" alt="OctoEverywhere Logo" height="64"></a></th>
<th><a href="https://octoapp.eu/?source=kiauh_readme"><img src="https://octoapp.eu/octoapp.webp" alt="OctoApp Logo" height="64"></a></th>
</tr>
<tr>
<th>by <a href="https://github.com/Clon1998">Patrick Schmidt</a></th>
<th>by <a href="https://github.com/QuinnDamerell">Quinn Damerell</a></th>
<th>by <a href="https://github.com/crysxd">Christian Würthner</a></th>
</tr> </tr>
<tr> <tr>
<th><h3><a href="https://github.com/Clon1998/mobileraker_companion">Mobileraker's Companion</a></h3></th> <th><h3><a href="https://github.com/staubgeborener/klipper-backup">Klipper-Backup</a></h3></th>
<th><h3><a href="https://octoeverywhere.com/?source=kiauh_readme">OctoEverywhere For Klipper</a></h3></th> <th><h3><a href="https://simplyprint.io/">SimplyPrint for Klipper</a></h3></th>
<th><h3><a href="https://github.com/crysxd/OctoApp-Plugin">OctoApp For Klipper</a></h3></th>
<th><h3></h3></th>
</tr> </tr>
<tr> <tr>
<th><a href="https://github.com/Clon1998/mobileraker_companion"><img src="https://raw.githubusercontent.com/Clon1998/mobileraker/master/assets/icon/mr_appicon.png" alt="OctoEverywhere Logo" height="64"></a></th> <th><a href="https://github.com/staubgeborener/klipper-backup"><img src="https://avatars.githubusercontent.com/u/28908603?v=4" alt="Staubgeroner Avatar" height="64"></a></th>
<th><a href="https://octoeverywhere.com/?source=kiauh_readme"><img src="https://octoeverywhere.com/img/logo.svg" alt="OctoEverywhere Logo" height="64"></a></th> <th><a href="https://github.com/SimplyPrint"><img src="https://avatars.githubusercontent.com/u/64896552?s=200&v=4" alt="" height="64"></a></th>
<th><a href="https://octoapp.eu/?source=kiauh_readme"><img src="https://octoapp.eu/octoapp.webp" alt="OctoApp Logo" height="64"></a></th>
</tr> </tr>
<tr> <tr>
<th>by <a href="https://github.com/Clon1998">Patrick Schmidt</a></th> <th>by <a href="https://github.com/Staubgeborener">Staubgeborener</a></th>
<th>by <a href="https://github.com/QuinnDamerell">Quinn Damerell</a></th> <th>by <a href="https://github.com/SimplyPrint">SimplyPrint</a></th>
<th>by <a href="https://github.com/crysxd">Christian Würthner</a></th>
<th></th>
</tr> </tr>
</table> </table>
<hr> <hr>
@@ -186,6 +192,12 @@ prompt and confirm by hitting ENTER.
<hr> <hr>
<div align="center">
<img src="https://repobeats.axiom.co/api/embed/a1afbda9190c04a90cf4bd3061e5573bc836cb05.svg" alt="Repobeats analytics image"/>
</div>
<hr>
<h2 align="center">✨ Credits ✨</h2> <h2 align="center">✨ Credits ✨</h2>
* A big thank you to [lixxbox](https://github.com/lixxbox) for that awesome KIAUH-Logo! * A big thank you to [lixxbox](https://github.com/lixxbox) for that awesome KIAUH-Logo!

View File

@@ -13,6 +13,8 @@ from core.backup_manager import BACKUP_ROOT_DIR
MODULE_PATH = Path(__file__).resolve().parent MODULE_PATH = Path(__file__).resolve().parent
KLIPPER_REPO_URL = "https://github.com/Klipper3d/klipper.git"
# names # names
KLIPPER_LOG_NAME = "klippy.log" KLIPPER_LOG_NAME = "klippy.log"
KLIPPER_CFG_NAME = "printer.cfg" KLIPPER_CFG_NAME = "printer.cfg"

View File

@@ -13,6 +13,8 @@ from core.backup_manager import BACKUP_ROOT_DIR
MODULE_PATH = Path(__file__).resolve().parent MODULE_PATH = Path(__file__).resolve().parent
MOONRAKER_REPO_URL = "https://github.com/Arksine/moonraker.git"
# names # names
MOONRAKER_CFG_NAME = "moonraker.conf" MOONRAKER_CFG_NAME = "moonraker.conf"
MOONRAKER_LOG_NAME = "moonraker.log" MOONRAKER_LOG_NAME = "moonraker.log"

View File

@@ -79,14 +79,14 @@ class BackupManager:
if source is None or not Path(source).exists(): if source is None or not Path(source).exists():
Logger.print_info("Source directory does not exist! Skipping ...") Logger.print_info("Source directory does not exist! Skipping ...")
return return None
target = self.backup_root_dir if target is None else target target = self.backup_root_dir if target is None else target
try: try:
date = get_current_date().get("date") date = get_current_date().get("date")
time = get_current_date().get("time") time = get_current_date().get("time")
backup_target = target.joinpath(f"{name.lower()}-{date}-{time}") backup_target = target.joinpath(f"{name.lower()}-{date}-{time}")
shutil.copytree(source, backup_target, ignore=self.ignore_folders_func) shutil.copytree(source, backup_target, ignore=self.ignore_folders_func, ignore_dangling_symlinks=True)
Logger.print_ok("Backup successful!") Logger.print_ok("Backup successful!")
return backup_target return backup_target

View File

@@ -9,9 +9,12 @@
from __future__ import annotations from __future__ import annotations
import textwrap import textwrap
from pathlib import Path
from typing import Literal, Tuple, Type from typing import Literal, Tuple, Type
from components.klipper import KLIPPER_DIR, KLIPPER_REPO_URL
from components.klipper.klipper_utils import get_klipper_status from components.klipper.klipper_utils import get_klipper_status
from components.moonraker import MOONRAKER_DIR, MOONRAKER_REPO_URL
from components.moonraker.moonraker_utils import get_moonraker_status from components.moonraker.moonraker_utils import get_moonraker_status
from core.logger import DialogType, Logger from core.logger import DialogType, Logger
from core.menus import Option from core.menus import Option
@@ -30,12 +33,13 @@ class SettingsMenu(BaseMenu):
self.title = "Settings Menu" self.title = "Settings Menu"
self.title_color = Color.CYAN self.title_color = Color.CYAN
self.previous_menu: Type[BaseMenu] | None = previous_menu self.previous_menu: Type[BaseMenu] | None = previous_menu
self.klipper_status = get_klipper_status()
self.moonraker_status = get_moonraker_status()
self.mainsail_unstable: bool | None = None self.mainsail_unstable: bool | None = None
self.fluidd_unstable: bool | None = None self.fluidd_unstable: bool | None = None
self.auto_backups_enabled: bool | None = None self.auto_backups_enabled: bool | None = None
self._load_settings() self._load_settings()
print(self.klipper_status)
def set_previous_menu(self, previous_menu: Type[BaseMenu] | None) -> None: def set_previous_menu(self, previous_menu: Type[BaseMenu] | None) -> None:
from core.menus.main_menu import MainMenu from core.menus.main_menu import MainMenu
@@ -103,32 +107,51 @@ class SettingsMenu(BaseMenu):
self.mainsail_unstable = self.settings.mainsail.unstable_releases self.mainsail_unstable = self.settings.mainsail.unstable_releases
self.fluidd_unstable = self.settings.fluidd.unstable_releases self.fluidd_unstable = self.settings.fluidd.unstable_releases
def _gather_input(self) -> Tuple[str, str]: # by default, we show the status of the installed repositories
Logger.print_dialog( self.klipper_status = get_klipper_status()
DialogType.ATTENTION, self.moonraker_status = get_moonraker_status()
[ # if the repository is not installed, we show the status of the settings from the config file
"There is no input validation in place! Make sure your the input is " if self.klipper_status.repo == "-":
"valid and has no typos or invalid characters! For the change to take " url_parts = self.settings.klipper.repo_url.split("/")
"effect, the new repository will be cloned. A backup of the old " self.klipper_status.repo = url_parts[-1]
"repository will be created.", self.klipper_status.owner = url_parts[-2]
self.klipper_status.branch = self.settings.klipper.branch
if self.moonraker_status.repo == "-":
url_parts = self.settings.moonraker.repo_url.split("/")
self.moonraker_status.repo = url_parts[-1]
self.moonraker_status.owner = url_parts[-2]
self.moonraker_status.branch = self.settings.moonraker.branch
def _gather_input(self, repo_name: Literal["klipper", "moonraker"], repo_dir: Path) -> Tuple[str, str]:
warn_msg = [
"There is only basic input validation in place! "
"Make sure your the input is valid and has no typos or invalid characters!"]
if repo_dir.exists():
warn_msg.extend([
"For the change to take effect, the new repository will be cloned. "
"A backup of the old repository will be created.",
"\n\n", "\n\n",
"Make sure you don't have any ongoing prints running, as the services " "Make sure you don't have any ongoing prints running, as the services "
"will be restarted during this process! You will loose any ongoing print!", "will be restarted during this process! You will loose any ongoing print!"])
],
) Logger.print_dialog(DialogType.ATTENTION, warn_msg)
repo = get_string_input( repo = get_string_input(
"Enter new repository URL", "Enter new repository URL",
allow_special_chars=True, regex=r"^[\w/.:-]+$",
default=KLIPPER_REPO_URL if repo_name == "klipper" else MOONRAKER_REPO_URL,
) )
branch = get_string_input( branch = get_string_input(
"Enter new branch name", "Enter new branch name",
allow_special_chars=True, regex=r"^.+$",
default="master"
) )
return repo, branch return repo, branch
def _set_repo(self, repo_name: Literal["klipper", "moonraker"]) -> None: def _set_repo(self, repo_name: Literal["klipper", "moonraker"], repo_dir: Path) -> None:
repo_url, branch = self._gather_input() repo_url, branch = self._gather_input(repo_name, repo_dir)
display_name = repo_name.capitalize() display_name = repo_name.capitalize()
Logger.print_dialog( Logger.print_dialog(
DialogType.CUSTOM, DialogType.CUSTOM,
@@ -151,22 +174,26 @@ class SettingsMenu(BaseMenu):
Logger.print_ok("Changes saved!") Logger.print_ok("Changes saved!")
else: else:
Logger.print_info( Logger.print_info(
f"Skipping change of {display_name} source repository ..." f"Changing of {display_name} source repository canceled ..."
) )
return return
Logger.print_status(f"Switching to {display_name}'s new source repository ...") self._switch_repo(repo_name, repo_dir)
self._switch_repo(repo_name)
def _switch_repo(self, name: Literal["klipper", "moonraker"], repo_dir: Path ) -> None:
if not repo_dir.exists():
return
Logger.print_status(f"Switching to {name.capitalize()}'s new source repository ...")
def _switch_repo(self, name: Literal["klipper", "moonraker"]) -> None:
repo: RepoSettings = self.settings[name] repo: RepoSettings = self.settings[name]
run_switch_repo_routine(name, repo) run_switch_repo_routine(name, repo)
def set_klipper_repo(self, **kwargs) -> None: def set_klipper_repo(self, **kwargs) -> None:
self._set_repo("klipper") self._set_repo("klipper", KLIPPER_DIR)
def set_moonraker_repo(self, **kwargs) -> None: def set_moonraker_repo(self, **kwargs) -> None:
self._set_repo("moonraker") self._set_repo("moonraker", MOONRAKER_DIR)
def toggle_mainsail_release(self, **kwargs) -> None: def toggle_mainsail_release(self, **kwargs) -> None:
self.mainsail_unstable = not self.mainsail_unstable self.mainsail_unstable = not self.mainsail_unstable

View File

@@ -145,7 +145,8 @@ class KiauhSettings:
def _validate_str(self, section: str, option: str) -> None: def _validate_str(self, section: str, option: str) -> None:
self._v_section, self._v_option = (section, option) self._v_section, self._v_option = (section, option)
v = self.config.getval(section, option) v = self.config.getval(section, option)
if v.isdigit() or v.lower() == "true" or v.lower() == "false":
if not v:
raise ValueError raise ValueError
def _apply_settings_from_file(self) -> None: def _apply_settings_from_file(self) -> None:

View File

@@ -118,7 +118,7 @@ class MoonrakerTelegramBot:
) )
env_file_content = env_file_content.replace( env_file_content = env_file_content.replace(
"%CFG%", "%CFG%",
f"{self.base.cfg_dir}/printer.cfg", self.cfg_file.as_posix()
) )
env_file_content = env_file_content.replace( env_file_content = env_file_content.replace(
"%LOG%", "%LOG%",

View File

@@ -64,7 +64,7 @@ def run_switch_repo_routine(
try: try:
# step 2: backup old repo and env # step 2: backup old repo and env
org, repo = get_repo_name(repo_dir) org, _ = get_repo_name(repo_dir)
backup_dir = backup_dir.joinpath(org) backup_dir = backup_dir.joinpath(org)
bm = BackupManager() bm = BackupManager()
repo_dir_backup_path = bm.backup_directory( repo_dir_backup_path = bm.backup_directory(

View File

@@ -51,7 +51,7 @@ def change_system_hostname() -> None:
) )
hostname = get_string_input( hostname = get_string_input(
"Enter the new hostname", "Enter the new hostname",
regex="^[a-z0-9]+([a-z0-9-]*[a-z0-9])?$", regex=r"^[a-z0-9]+([a-z0-9-]*[a-z0-9])?$",
) )
if not get_confirm(f"Change the hostname to '{hostname}'?", default_choice=False): if not get_confirm(f"Change the hostname to '{hostname}'?", default_choice=False):
Logger.print_info("Aborting hostname change ...") Logger.print_info("Aborting hostname change ...")

View File

@@ -43,7 +43,8 @@ def get_kiauh_version() -> str:
Helper method to get the current KIAUH version by reading the latest tag Helper method to get the current KIAUH version by reading the latest tag
:return: string of the latest tag :return: string of the latest tag
""" """
return get_local_tags(Path(__file__).parent.parent)[-1] lastest_tag: str = get_local_tags(Path(__file__).parent.parent)[-1]
return lastest_tag
def convert_camelcase_to_kebabcase(name: str) -> str: def convert_camelcase_to_kebabcase(name: str) -> str:

View File

@@ -1,6 +1,7 @@
from __future__ import annotations from __future__ import annotations
import json import json
import re
import shutil import shutil
import urllib.request import urllib.request
from http.client import HTTPResponse from http.client import HTTPResponse
@@ -104,10 +105,10 @@ def get_current_branch(repo: Path) -> str:
result: str = check_output(cmd, stderr=DEVNULL, cwd=repo).decode( result: str = check_output(cmd, stderr=DEVNULL, cwd=repo).decode(
encoding="utf-8" encoding="utf-8"
) )
return result.strip() return result.strip() if result else "-"
except CalledProcessError: except CalledProcessError:
return "" return "-"
def get_local_tags(repo_path: Path, _filter: str | None = None) -> List[str]: def get_local_tags(repo_path: Path, _filter: str | None = None) -> List[str]:
@@ -118,7 +119,7 @@ def get_local_tags(repo_path: Path, _filter: str | None = None) -> List[str]:
:return: List of tags :return: List of tags
""" """
try: try:
cmd = ["git", "tag", "-l"] cmd: List[str] = ["git", "tag", "-l"]
if _filter is not None: if _filter is not None:
cmd.append(f"'${_filter}'") cmd.append(f"'${_filter}'")
@@ -129,8 +130,10 @@ def get_local_tags(repo_path: Path, _filter: str | None = None) -> List[str]:
cwd=repo_path.as_posix(), cwd=repo_path.as_posix(),
).decode(encoding="utf-8") ).decode(encoding="utf-8")
tags = result.split("\n") tags: List[str] = result.split("\n")[:-1]
return tags[:-1]
return sorted(tags, key=lambda x: [int(i) if i.isdigit() else i for i in
re.split(r'(\d+)', x)])
except CalledProcessError: except CalledProcessError:
return [] return []

View File

@@ -86,6 +86,7 @@ def get_string_input(
question: str, question: str,
regex: str | None = None, regex: str | None = None,
exclude: List[str] | None = None, exclude: List[str] | None = None,
allow_empty: bool = False,
allow_special_chars: bool = False, allow_special_chars: bool = False,
default: str | None = None, default: str | None = None,
) -> str: ) -> str:
@@ -94,6 +95,7 @@ def get_string_input(
:param question: The question to display :param question: The question to display
:param regex: An optional regex pattern to validate the input against :param regex: An optional regex pattern to validate the input against
:param exclude: List of strings which are not allowed :param exclude: List of strings which are not allowed
:param allow_empty: Whether to allow empty input
:param allow_special_chars: Wheter to allow special characters in the input :param allow_special_chars: Wheter to allow special characters in the input
:param default: Optional default value :param default: Optional default value
:return: The validated string value :return: The validated string value
@@ -104,12 +106,14 @@ def get_string_input(
while True: while True:
_input = input(_question) _input = input(_question)
if _input.lower() in _exclude: if default is not None and _input == "":
Logger.print_error("This value is already in use/reserved.")
elif default is not None and _input == "":
return default return default
elif _input == "" and not allow_empty:
Logger.print_error("Input must not be empty!")
elif _pattern is not None and _pattern.match(_input): elif _pattern is not None and _pattern.match(_input):
return _input return _input
elif _input.lower() in _exclude:
Logger.print_error("This value is already in use/reserved.")
elif allow_special_chars: elif allow_special_chars:
return _input return _input
elif not allow_special_chars and _input.isalnum(): elif not allow_special_chars and _input.isalnum():