From a513187d4842758e63fda6abd90c86d4f9d19928 Mon Sep 17 00:00:00 2001
From: V3n3RiX <venerix@koprulu.sector>
Date: Sat, 20 Jan 2024 18:49:09 +0000
Subject: rewrite help menus

---
 src/frontend/cli/sisyphus-cli.py | 356 +++++++++++++++++++--------------------
 1 file changed, 175 insertions(+), 181 deletions(-)

diff --git a/src/frontend/cli/sisyphus-cli.py b/src/frontend/cli/sisyphus-cli.py
index 253e192..93928c4 100755
--- a/src/frontend/cli/sisyphus-cli.py
+++ b/src/frontend/cli/sisyphus-cli.py
@@ -14,9 +14,10 @@ app.add_typer(mirrorSetup, name="mirror",
 
 @app.callback()
 def app_callback(ctx: typer.Context):
-    """Sisyphus is a simple python wrapper around portage, gentoolkit, and portage-utils
-    which provides an apt-get/yum-alike interface to these commands,
-    to assist newcomer people transitioning from Debian/RedHat-based systems to Gentoo.
+    """
+    Sisyphus is a simple python wrapper around portage, gentoolkit, and portage-utils\n
+    which provides an apt-get/yum-alike interface to these commands, to assist newcomers\n
+    transitioning from Debian/RedHat-based systems to Gentoo.\n
 
     Use 'sisyphus COMMAND --help' for detailed usage.
     """
@@ -40,64 +41,48 @@ def search(package: List[str] = typer.Argument(...),
            quiet: bool = typer.Option(
                False, '-q', help='Short (one line) output.'),
            ebuild: bool = typer.Option(False, "--ebuild", "-e", help='Search in ebuilds (slower).')):
-    """Search for binary and/or ebuild (source) packages.
-
-    By default will search for binary packages, using internal database.
-    The search term can be provided also in the category/name format, e.g:
-
-        sisyphus search openbox
-
-            OR
-
-        sisyphus search x11-wm/openbox
-
-    Using * and ? wildcards is supported. An empty string will match everything (similar to *).
-
-    * Examples:
-
-    to search for all packages belonging to a category, use '*' or leave the name empty:
-
-        sisyphus search x11-wm/
-
-        sisyphus search x11-wm/*
-
-    In addition, search can be performed by package description, using the -d (--description) option:
-
-        sisyphus search x11/open -d 'window manager'
-
-    (use single or double quotes when the description contains spaces)
-
-    Use the -f (--filter) option to select only packages of interest. Possible values:
-
-        all (default) - search the entire database
-
-        alien - search for installed packages but not available
-        (this filter can match packages installed from e-builds or packages no longer maintained as binaries)
-
-        installed - search in all installed packages
-
-        available - search for available packages but not installed
-
-        upgradable - search for installed packages where installed version is different from available version
-
-    !!! NOTE !!!:
-
-    bash will expand a single * character as current folder listing.
-    To search for all matching '--filter' packages escape it, or surround it with quotes, or use an empty string:
-
-        sisyphus search * -f installed          # this is not valid!
-
-        sisyphus search \* -f alien             # OK
-
-        sisyphus search '*' -f available        # OK
-
-        sisyphus search '' -f upgradable       # OK
-
-
-    To search for all (including source) packages, use the --ebuild option.
-    This is slower since will perform an emerge --search actually.
-    With this option, more than one package can be provided as search term.
-    '-d', '-f' and '-q' (quiet) options are ignored in this mode.
+    """Search for binary and/or ebuild (source) packages.\n
+    By default will search for binary packages, using internal database.\n
+    The search term can be provided also in the category/name format.\n
+    \n
+    * Examples:\n
+        sisyphus search openbox\n
+        sisyphus search x11-wm/openbox\n
+    \n
+    Using * and ? wildcards is supported. An empty string will match everything (similar to *).\n
+    \n
+    * Examples:\n
+        sisyphus search x11-wm/     # search all packages in the x11-wm category\n
+        sisyphus search x11-wm/*    # search all packages in the x11-wm category\n
+    \n
+    In addition, search can be performed by package description, using the -d (--description) option:\n
+    \n
+    * Examples:\n
+        sisyphus search x11/open -d 'window manager'    # use single or double quotes when the description contains spaces\n
+    \n
+    Use the -f (--filter) option to select only packages of interest. Possible values:\n
+    \n
+        all (default)   - search the entire database\n
+        alien           - search for installed packages but not available     # (this filter can match packages installed from ebuilds or packages no longer maintained as binaries)\n
+        installed       - search in all installed packages\n
+        available       - search for available packages but not installed\n
+        upgradable      - search for installed packages where installed version is different from available version\n
+    \n
+    !!! NOTE !!!\n
+    \n
+    Bash will expand a single * character as current folder listing.\n
+    To search for all matching '--filter' packages you need to escape it, surround it with quotes, or just use an empty string.\n
+    \n
+    * Examples:\n
+        sisyphus search * -f installed          # not valid\n
+        sisyphus search \* -f alien             # valid\n
+        sisyphus search '*' -f available        # valid\n
+        sisyphus search '' -f upgradable        # valid\n
+    \n
+    To search for all (including source) packages, use the --ebuild option.\n
+    This is slower since will perform an 'emerge --search' actually.\n
+    With this option, more than one package can be provided as search term.\n
+    '-d', '-f' and '-q' (quiet) options are ignored in this mode.\n
     """
     if not ebuild:
         if '/' in package[0]:
@@ -116,28 +101,26 @@ def search(package: List[str] = typer.Argument(...),
 @app.command("install")
 def install(pkgname: List[str],
             ebuild: bool = typer.Option(
-                False, "--ebuild", "-e", help='Install ebuild (source) package if binary package is not found (slower)'),
-            oneshot: bool = typer.Option(False, "--oneshot", "-1", help='Do not mark the package as explicitly installed, and do not add it to world set')):
-    """Install binary and/or ebuild(source) packages.
-    By default, only binary packages will be installed.
-    Use the --ebuild option to install ebuild(source) packages.
-
-    * Examples:
-
-        sisyphus install pidgin
-
-    will install pidgin binary package (if available); if there is none, but the ebuild(source) package for pidgin is found, it will stop and suggest the --ebuild option.
-
-        sisyphus install pidgin --ebuild
-
-    will compile pidgin from source
-
-    The --ebuild option will preffer to reuse binary packages(if available) to satisfy the dependencies for the ebuild(source) package, speeding up the installation.
-    You can use the --ebuild option even if you don't want to install any ebuild(source) packages; It will fall back to binary packages only.
-
-    The --oneshot option will install the packages as described above, however it will not add them to the 'world' set, which means they will not be marked as
-    explicitly installed. As a result, they will be treated as orphans and they will be uninstalled with 'sisyphus autoremove' if no other package needs them as
-    a depencency, unless they are explicitly added to the 'world' set using 'emerge --noreplace pkgname'.
+                False, "--ebuild", "-e", help='Install ebuild(source) package if binary package is not found (slower)'),
+            oneshot: bool = typer.Option(False, "--oneshot", "-1", help='Do not mark the package as explicitly installed')):
+    """
+    Install binary and/or ebuild(source) packages.\n
+    Binary packages are default, however the --ebuild option can be used to install ebuild(source) packages.\n
+    The --ebuild option will be automatically suggested if a binary package is not found, but an ebuild(source) package is found.\n
+    The --ebuild option will fall back to binary packages if installation from ebuild(source) package is not required. (Can be used at all times, *SAFELY*).\n
+    The --ebuild option will prefer to use binary packages (if available) to satisfy dependencies for the ebuild(source) package, speeding up the installation.\n
+    The --oneshot option follows the above rules, however it will not mark the package as explicitly installed. (In Gentoo Linux terms: not added to world set).\n
+    The --ebuild and the --oneshot options can be used both independently of each other and/or combined with each other.\n
+    \n
+    * Examples:\n
+        sisyphus install firefox\n
+        sisyphus install pidgin --ebuild\n
+        sisyphus install xonotic -e\n
+        sisyphus install filezilla --oneshot\n
+        sisyphus install thunderbird -1\n
+        sisyphus install falkon -e -1\n
+        sisyphus install opera --ebuild --oneshot\n
+        sisyphus install vivaldi --oneshot --ebuild\n
     """
     if ebuild:
         sisyphus.install.start(pkgname, ebuild=True,
@@ -148,36 +131,20 @@ def install(pkgname: List[str],
 
 
 @app.command("uninstall")
-def uninstall(pkgname: List[str], force: bool = typer.Option(False, "--force", "-f")):
-    """Uninstall packages *SAFELY* by checking for reverse dependencies.
-    If reverse dependencies exist, the package(s) will NOT be uninstalled to prevent the possible breakage of the system.
-    If you really want to uninstall the package, make sure you uninstall all reverse dependencies as well.
-    This will not allways be possible, as the reverse dependency chain may be way to long and require you to uninstall critical system packages.
-
-    * Examples:
-
-        sisyphus uninstall firefox
-
-    will succeed, nothing depends on it
-
-        sisyphus uninstall pulseaudio
-
-    will fail, many packages depend on it
-
-    With --force option, packages are uninstalled *UNSAFELY* by ignoring reverse dependencies.
-    This may break your system if you uninstall critical packages.
-    It will try the best it can to preserve the libraries required by other packages to prevent such a breakage.
-    Upgrading the system may pull the packages back in, to fix the reverse dependency chain.
-
-    * Examples :
-
-        sisyphus uninstall pulseaudio --force
-
-    will succeed, but you may no longer have audio
-
-        sisyphus uninstall openrc --force
-
-    will succeed, but the system will be broken
+def uninstall(pkgname: List[str], force: bool = typer.Option(False, "--force", "-f", help='Ignore the reverse dependencies and force uninstall the package (DANGEROUS)')):
+    """
+    Uninstall packages *SAFELY* by checking for reverse dependencies.\n
+    If there are any reverse dependencies, the package or packages will NOT be uninstalled to prevent the system from breaking.\n
+    If you are serious about uninstalling the package, it is recommended you uninstall all the reverse dependencies of it as well.\n
+    This will not always be possible because the reverse dependency tree may be too long and you may need to uninstall important system packages.\n
+    DANGEROUS : The --force option will ignore the reverse dependencies and uninstall the package *UNSAFELY*, without safeguards.\n
+    WARNING   : The --force option will break your system if you uninstall important system packages (bootloader, kernel, init).\n
+    \n
+    * Examples:\n
+        sisyphus uninstall firefox              # this will succeed, no package depends on firefox\n
+        sisyphus uninstall pulseaudio           # this will fail, many packages depend on pulseaudio\n
+        sisyphus uninstall pulseaudio --force   # this will succeed, but the sound may no longer work\n
+        sisyphus uninstall openrc -f            # this will succeed, but the system will no longer boot\n
     """
     if force:
         sisyphus.uninstall.start(
@@ -189,17 +156,27 @@ def uninstall(pkgname: List[str], force: bool = typer.Option(False, "--force", "
 
 @app.command("autoremove")
 def autoremove():
-    """Uninstall packages that are no longer needed.
-    When you uninstall a package without it's reverse dependencies, those dependencies will become orphans if nothing else requires them.
-    In addition, a package may no longer depend on another one, so that other package becomes orphan as well if nothing else requires it.
-    Use this option to check the whole dependency chain for such packages, and uninstall them.
+    """
+    Uninstall packages which become orphans and which are no longer needed.\n
+    Uninstalling a package will usually leave it's dependencies behind. Those dependencies become orphans if no other package requires them.\n
+    A package may also gain extra dependencies, or loose some dependencies. The lost dependencies become orphans if no other package requires them.\n
+    In both cases, the orphan packages are no longer needed and can be safely removed.\n
+    Use this option to check the whole dependency tree for orphan packages, and remove them.\n
+    \n
+    * Examples:\n
+        sisyphus autoremove\n
     """
     sisyphus.autoremove.start(gfx_ui=False)
 
 
 @app.command("autoclean")
 def autoclean():
-    """Clean the binary package cache and the source tarball cache"""
+    """
+    Clean the binary package cache and the source tarball cache.\n
+    \n
+    * Examples:\n
+        sisyphus autoclean\n
+    """
     if sisyphus.checkenv.root():
         sisyphus.purgeenv.cache()
     else:
@@ -208,7 +185,12 @@ def autoclean():
 
 @app.command("update")
 def update():
-    """Update the Portage tree, the Redcore Overlay(s), Portage configs and Sisyphus's package database."""
+    """
+    Update the source trees, package configs (USE flags, keywords, masks, etc) and the binary package database.\n
+    \n
+    * Examples:\n
+        sisyphus update\n
+    """
     if sisyphus.checkenv.root():
         sisyphus.update.start(gfx_ui=False)
     else:
@@ -217,24 +199,18 @@ def update():
 
 @app.command("upgrade")
 def upgrade(
-        ebuild: bool = typer.Option(False, "--ebuild", "-e", help='Upgrade all packages, including ebuild (source) packages previously installed (slower)')):
-    """Upgrade the system using binary and/or ebuild (source) packages.
-    By default, only binary packages will be upgraded.
-    However, if you installed any ebuild(source) packages with the '--ebuild' option, it would make sense to upgrade them too.
-    Use the --ebuild option to upgrade **EVERYTHING**, binary and/or ebuild(source) packages.
-
-    * Examples:
-
-        sisyphus upgrade
-
-    will upgrade the system using binary packages; if any ebuild(source) package upgrade is detected, it will stop and suggest the --ebuild option
-
-        sisyphus upgrade --ebuild
-
-    will upgrade the system using both binary and/or ebuild(source) packages
-
-    The --ebuild option will preffer to reuse binary packages(if available) to satisfy the dependencies for the ebuild(source) packages, speeding up the upgrade.
-    You can use the --ebuild option even if you don't have any ebuild(source) packages installed; It will fall back to binary packages only.
+        ebuild: bool = typer.Option(False, "--ebuild", "-e", help='Upgrade all packages, including ebuild(source) packages (slower)')):
+    """
+    Upgrade the system using binary and/or ebuild(source) packages.\n
+    Binary packages are default, however the --ebuild option can be used to upgrade the ebuild(source) packages as well, alongside the binary packages.\n
+    The --ebuild option will be automatically suggested if the ebuild(source) packages need to be upgraded as well, alongside the binary packages.\n
+    The --ebuild option will fall back to binary packages if the ebuild(source) packages don't require any upgrade. (Can be used at all times, *SAFELY*).\n
+    The --ebuild option will prefer to use binary packages (if available) to satisfy dependencies for the ebuild(source) packages, speeding up the upgrade.\n
+    \n
+    * Examples:\n
+        sisyphus upgrade\n
+        sisyphus upgrade --ebuild\n
+        sisyphus upgrade -e\n
     """
     if ebuild:
         sisyphus.upgrade.start(ebuild=True, gfx_ui=False)
@@ -244,19 +220,27 @@ def upgrade(
 
 @app.command("spmsync")
 def spmsync():
-    """Sync Sisyphus's package database with Portage's package database.
-    When you install something with Portage directly (emerge), Sisyphus is not aware of that package, and it doesn't track it in it's database.
-    Use this command to synchronize Sisyphus's package database with Portage's package database.
+    """
+    Sync Sisyphus's package database with Portage's package database.\n
+    Sisyphus does not track packages installed directly via Portage in it's package database.\n
+    Use this command to synchronize Sisyphus's package database with Portage's package database.\n
+    \n
+    * Examples:\n
+        sisyphus spmsync\n
     """
     sisyphus.syncspm.start()
 
 
 @app.command("rescue")
 def rescue():
-    """Resurrect Sisyphus's package database if lost or corrupted.
-    If for some reason Sisyphus's package database is lost or corrupted, it can be resurrected using Portage's package database.
-    If Portage's package database is corrupted (in this case you're screwed anyway :D), only a partial resurrection will be possible.
-    If Portage's package database is intact, full resurrection will be possible.
+    """
+    Resurrect Sisyphus's package database if lost or corrupted.\n
+    If for some reason Sisyphus's package database is lost or corrupted, it can be resurrected using Portage's package database.\n
+    If Portage's package database is corrupted (in this case you're screwed anyway :D), only a partial resurrection will be possible.\n
+    If Portage's package database is intact, full resurrection will be possible.\n
+    \n
+    * Examples:\n
+        sisyphus rescue\n
     """
     sisyphus.recoverdb.start()
 
@@ -274,59 +258,69 @@ class Remote(str, Enum):
 
 @app.command("branch")
 def branch(branch: Branch = typer.Argument(...), remote: Remote = typer.Option(Remote.gitlab, "--remote", "-r")):
-    """Pull the selected branch of the Portage tree, Redcore overlay and Portage configs.
-    The remote can be selected by using the --remote option.
-
-    'BRANCH' can be one of the following : master, next
-
-    'REMOTE' can be one of the following : github, gitlab, pagure (default is gitlab)
-
-    * Examples:
-
-        branch next --remote=github     # pull the branch 'next' from github.com
-
-        branch master --remote=gitlab   # pull the branch 'master' from gitlab.com
-
-        branch next --remote=pagure     # pull the branch 'next' from pagure.io
-
-    !!! WARNING !!!
-
-    Once you changed the branch, you must pair it with the correct binhost (binary repository).
-
-    Branch 'master' must be paired with the stable binhost (binary repository) (odd numbers in 'sisyphus mirror list').
-
-    * Examples:
-
-        sisyphus mirror set 1
-
-        sisyphus mirror set 5
-
-    Branch 'next' must be paired with the testing binhost (binary repository) (even numbers in 'sisyphus mirror list').
-
-    * Examples:
-
-        sisyphus mirror set 2
-
-        sisyphus mirror set 8
+    """
+    Switch between the branches of Redcore Linux : 'master' (stable) or 'next' (testing), default branch is 'master' (stable)\n
+    Reconfigure the source trees, package configs (USE flags, keywords, masks, etc) and the binhost (binary repository)\n
+    Selection of a remote is optional (default is gitlab), but it can be accomplished by using the --remote option.\n
+    'BRANCH' can be one of the following : master, next\n
+    'REMOTE' can be one of the following : github, gitlab, pagure (default is gitlab)\n
+    \n
+    * Examples:\n
+        sisyphus branch master                  # switch to branch 'master', use default remote (gitlab)\n
+        sisyphus branch next                    # switch to branch 'next', use default remote (gitlab)\n
+        sisyphus branch master --remote=github  # switch to branch 'master', use github remote\n
+        sisyphus branch next --remote=pagure    # switch to branch 'next', use pagure remote\n
+    \n
+    Sisyphus will automatically pair the selected branch with the correct binhost (binary repository).\n
+    However, since no geolocation is ever used, it may select one which is geographically far from you.\n
+    If that is inconvenient, you can manually select a binhost (binary repository) closer to your location,\n
+    \n
+    !!! WARNING !!!\n
+    \n
+    Branch 'master' must be paired with the stable binhost (binary repository) (odd numbers in 'sisyphus mirror list').\n
+    * Examples:\n
+        sisyphus mirror set 1\n
+        sisyphus mirror set 5\n
+    \n
+    Branch 'next' must be paired with the testing binhost (binary repository) (even numbers in 'sisyphus mirror list').\n
+    * Examples:\n
+        sisyphus mirror set 2\n
+        sisyphus mirror set 8\n
     """
     sisyphus.setbranch.start(branch.value, remote.value)
 
 
 @app.command("sysinfo")
 def sysinfo():
-    """Display information about installed core packages and portage configuration."""
+    """
+    Display information about installed core packages and portage configuration.\n
+    \n
+    * Examples:\n
+        sisyphus sysinfo\n
+    """
     sisyphus.sysinfo.show()
 
 
 @mirrorSetup.command("list")
 def mirrorlist():
-    """List available binary package repository mirrors (the active one is marked with *)."""
+    """
+    List available binary package repository mirrors (the active one is marked with *).\n
+    \n
+    * Examples:\n
+        sisyphus mirror list\n
+    """
     sisyphus.mirrors.printList()
 
 
 @mirrorSetup.command("set")
 def mirrorset(index: int):
-    """Change the binary package repository to the selected mirror."""
+    """
+    Change the binary package repository to the selected mirror.\n
+    \n
+    * Examples:\n
+        sisyphus mirror set 2\n
+        sisyphus mirror set 5\n
+    """
     sisyphus.mirrors.setActive(index)
 
 
-- 
cgit v1.2.3