diff --git a/commands/commit.py b/commands/commit.py index b2b0d8a..c18ff3f 100644 --- a/commands/commit.py +++ b/commands/commit.py @@ -1,75 +1,21 @@ -from typing import List from commands.util import pacman +from commands.util.diff import pkg_diff from commands.util.input_mgr import confirm, password -import colorama as cl -from commands.util.printer import print_list +from commands.util.printing.diff import print_diff def commit(force: bool = False, no_render: bool = False): - print("Commit, force:", force) + """Commit the changes to the system + + Args: + force: Apply, overriding any changes since the last commit without confirming + no_render: Don't rerender the templates (use cached version). + Will be ignored if cache is unavailable (and prompt the user) + """ # TODO: Make sure we don't uninstall critical system packages by accident (i.e. prompt user) # Probably do that check in the pacman util lib tho - print_diff(pacman.list_explicitly_installed(), []) + add, remove = pkg_diff([], pacman.list_explicitly_installed()) + print_diff(add, remove) if confirm(True, "Do you really want to proceed?"): pw = password() - - -def print_diff(add: List[str], remove: List[str]): - if len(add) == 0 and len(remove) == 0: - print( - cl.Fore.BLUE - + "-->" - + cl.Style.DIM - + cl.Fore.GREEN - + " No packages changes" - + cl.Style.RESET_ALL, - ) - # Packages to be installed - if len(add) == 0: - print( - cl.Fore.BLUE - + "-->" - + cl.Style.DIM - + cl.Fore.GREEN - + " No packages to be installed" - + cl.Style.RESET_ALL, - ) - else: - print( - cl.Fore.GREEN + "==>", - cl.Style.RESET_ALL + "Packages that will be", - cl.Fore.GREEN + "installed" + cl.Style.RESET_ALL, - ) - print_list(add) - print() - - # Packages to be removed - if len(remove) == 0: - print( - cl.Fore.BLUE - + "-->" - + cl.Style.DIM - + cl.Fore.GREEN - + " No packages to be uninstalled" - + cl.Style.RESET_ALL, - ) - else: - print( - cl.Fore.GREEN + "==>", - cl.Style.RESET_ALL + "Packages that will be", - cl.Fore.RED + "uninstalled" + cl.Style.RESET_ALL, - ) - print_list(remove) - print() - - # Ask user to confirm - print( - cl.Fore.GREEN + "==>", - cl.Style.RESET_ALL - + f"Transaction (packages): {cl.Fore.BLUE + str(len(add)) + cl.Style.RESET_ALL}", - cl.Fore.GREEN + "installed", - cl.Style.RESET_ALL - + f"and {cl.Fore.BLUE + str(len(remove)) + cl.Style.RESET_ALL}", - cl.Fore.RED + "uninstalled" + cl.Style.RESET_ALL, - ) diff --git a/commands/util/diff.py b/commands/util/diff.py new file mode 100644 index 0000000..9e34b32 --- /dev/null +++ b/commands/util/diff.py @@ -0,0 +1,22 @@ +from typing import List + + +def pkg_diff(target: List[str], actual: List[str]) -> tuple[List[str], List[str]]: + """Compute a diff between target packages and installed packages + + Args: + target: The target packages + actual: The actually installed packages + + Returns: + A tuple with first the missing (not installed) packages + and second the extraneous (to be uninstalled) packages + """ + for i, pkg in enumerate(actual): + try: + idx = target.index(pkg) + target.pop(idx) + actual.pop(i) + except Exception: + pass + return (target, actual) diff --git a/commands/util/pacman.py b/commands/util/pacman.py index 4395acf..eea9087 100644 --- a/commands/util/pacman.py +++ b/commands/util/pacman.py @@ -1,6 +1,8 @@ import subprocess as sp from typing import List +from commands.util.input_mgr import password + pkg_manager = ["yay", "--noconfirm"] @@ -19,7 +21,13 @@ def remove_orphans() -> bool: Returns: True if successful, False otherwise """ - return sp.run("pacman -Qdtq | sudo pacman -Rns --noconfirm -", capture_output=True).returncode == 0 + return ( + sp.run( + ["pacman", "-Qdtq", "|", "sudo", "pacman", "-Rns", "--noconfirm", "-"], + capture_output=True, + ).returncode + == 0 + ) def uninstall_package_list(pkgs: List[str]) -> bool: @@ -31,7 +39,7 @@ def uninstall_package_list(pkgs: List[str]) -> bool: Returns: True if successful, False otherwise """ - # TODO: Add guard to protect against uninstalling archmgr + # TODO: Add guard to protect against uninstalling archmgr and confirm uninstalling crucial pkgs # pkgs.index("archmgr") # TODO: Consider if we want to print out stdout and stderr on err return run_pkg_manager_cmd(["-Rs", *pkgs], True).returncode == 0 @@ -49,9 +57,8 @@ def install_package_list(pkgs: List[str]) -> bool: def run_pkg_manager_cmd( args: List[str], use_sudo: bool = False ) -> sp.CompletedProcess[str]: - # TODO: Get password - pw = "" if use_sudo: + pw = password() return sp.run([*pkg_manager, *args], capture_output=True, text=True, input=pw) else: return sp.run([*pkg_manager, *args], capture_output=True, text=True)