From 8fc12ad2079cc72e083795427cedb69714334a34 Mon Sep 17 00:00:00 2001 From: JesseBot Date: Sat, 26 Nov 2022 14:01:35 +0100 Subject: [PATCH] 91 brew packages being installed even if they are already installed (#97) * changing to proper package names instead of aliases for rich-cli, the_silver_searcher, and node * better logging * update to openssl v3 * remove alfred, move imagemagick to linuxbrew + macbrew section, and add back karabiner-elements * refactor to make more maintainable * adding more debug lines for pkg installation and changing when nvidia drivers are installed --- onboardme/config/packages.yml | 28 ++++---- onboardme/pkg_management.py | 126 +++++++++++++++++++--------------- pyproject.toml | 2 +- 3 files changed, 87 insertions(+), 69 deletions(-) diff --git a/onboardme/config/packages.yml b/onboardme/config/packages.yml index d180c809..599a4a76 100644 --- a/onboardme/config/packages.yml +++ b/onboardme/config/packages.yml @@ -29,13 +29,17 @@ brew: # A cat(1) clone with syntax highlighting and Git integration. - bat # pretty formatting and syntax highlighting - - rich + - rich-cli # file TUI: https://www.geeksforgeeks.org/ranger-a-cli-file-manager/ - ranger # preview videos in the terminal - ffmpegthumbnailer - # like grep or ack, but more modern, for searching file text - - ag + # cat images in the terminal (e.g. img2sixel imagename.png) + - libsixel + # for working with images and making lsimg work + - imagemagick + # ag command: like grep or ack, but more modern, for searching file text + - the_silver_searcher # diff, but with colors - colordiff - htop @@ -63,7 +67,7 @@ brew: # programming languages and their package managers - python@3.11 - go - - npm + - node # linter for YAML - yamllint # linter for html5 @@ -77,7 +81,7 @@ brew: # get the quick, short text of how to use various commands - tldr # generating SSL certs and random strings - - openssl + - openssl@3 # password management - bitwarden-cli # anti virus @@ -91,25 +95,21 @@ brew: # this lets us resize windows - "--cask rectangle" # productivity search and command bar - - "--cask alfred" + # - "--cask alfred" # Default browser - "--cask firefox" # Default email client - "--cask thunderbird" # File server - - "--cask nextcloud" + # - "--cask nextcloud" # Default terminal used by most macOS users, standard - "--cask iterm2" # backup terminal written in javascript :shrug: - "--cask hyper" # gives us the default gnu/linux sed we all know and love - "gnu-sed" - # cat images in the terminal (e.g. img2sixel imagename.png) - - libsixel - # for working with images and making lsimg work - - imagemagick - # remap keys... not working yet though :< - # - "--cask karabiner-elements" + # remap keys on macOS + - "--cask karabiner-elements" # This should be docker desktop - "--cask docker" # primary media player @@ -191,9 +191,9 @@ apt: - gufw gaming: # helpful for gaming on linux + - "nvidia-driver-libs:i386" - lutris - "steam:i386" - - "nvidia-driver-libs:i386" # to format disks to exFAT; FAT is too thin for modern windows 10 ISOs # - exfat-utils diff --git a/onboardme/pkg_management.py b/onboardme/pkg_management.py index 8db8cc1e..c8a56bad 100755 --- a/onboardme/pkg_management.py +++ b/onboardme/pkg_management.py @@ -1,13 +1,36 @@ import logging as log from os import path -# custom libs from .env_config import OS, PWD, HOME_DIR, load_cfg from .console_logging import print_header from .console_logging import print_sub_header as sub_header from .subproc import subproc +def run_preinstall_cmds(cmd_list=[], pkg_groups=[]): + """ + takes a list of package manager pre-install commands and runs them + if second list of package groups contains gaming, runs additional commands + returns True + """ + if 'gaming' in pkg_groups and 'apt' in cmd_list['update']: + log.debug("Run gaming specific commands to update /etc/apt/sources") + cmds = ["sudo dpkg --add-architecture i386", + f"sudo {PWD}/scripts/update_apt_sources.sh"] + subproc(cmds, spinner=False) + + for pre_cmd in ['setup', 'update', 'upgrade']: + if pre_cmd in cmd_list: + SPINNER = True + if 'sudo' in cmd_list[pre_cmd]: + SPINNER = False + + subproc([cmd_list[pre_cmd]], spinner=SPINNER) + sub_header(f"[b]{pre_cmd.title()}[/b] completed.") + + return True + + def run_pkg_mngrs(pkg_mngrs=[], pkg_groups=[]): """ Installs brew and pip3.11 packages. Also apt, snap, and flatpak on Linux. @@ -24,8 +47,8 @@ def run_pkg_mngrs(pkg_mngrs=[], pkg_groups=[]): default_config = path.join(PWD, 'config/packages.yml') pkg_mngrs_list_of_dicts = load_cfg(default_config) - log.debug(f"pkg_mngrs: {pkg_mngrs}") - log.debug(f"pkg_groups: {pkg_groups}") + log.debug(f"passed in pkg_mngrs: {pkg_mngrs}") + log.debug(f"passed in pkg_groups: {pkg_groups}") # we iterate through pkg_mngrs which should already be sorted for pkg_mngr in pkg_mngrs: @@ -38,81 +61,76 @@ def run_pkg_mngrs(pkg_mngrs=[], pkg_groups=[]): if 'Darwin' in OS: pkg_groups.append("macOS") - debug_line = f"pkg groups for {pkg_mngr} are {available_pkg_groups}" - log.debug(debug_line) + log.debug(f"pkg groups for {pkg_mngr} are {available_pkg_groups}") - # make sure that the package manage has any groups that were passed in + # make sure that the package manager has any groups that were passed in if any(check in pkg_groups for check in available_pkg_groups): pkg_emoji = pkg_mngr_dict['emoji'] msg = f'{pkg_emoji} [green][b]{pkg_mngr}[/b][/] app Installs' print_header(msg) + # commands for listing, installing, updating, upgrading, & cleanup pkg_cmds = pkg_mngr_dict['commands'] - log.debug(f"{pkg_mngr} pre-install commands are: {pkg_cmds}") - - # gaming has a special flow that needs to be done before updates - if "gaming" in pkg_groups and pkg_mngr == "apt": - run_gaming_specific_cmds() - # run package manager specific setup if needed, & updates/upgrades - for pre_cmd in ['setup', 'update', 'upgrade']: - if pre_cmd in pkg_cmds: - SPINNER = True - if 'sudo' in pkg_cmds[pre_cmd]: - SPINNER = False - subproc([pkg_cmds[pre_cmd]], spinner=SPINNER) - sub_header(f"[b]{pre_cmd.title()}[/b] completed.") + # run package manager specific setup if needed e.g. update/upgrade + run_preinstall_cmds(pkg_cmds, pkg_groups) - # list of actually installed packages - installed_pkgs = subproc([pkg_cmds['list']]) + # run the list command for the given package manager + list_pkgs = subproc([pkg_cmds['list']], quiet=True) + # create list of installed packages to iterate on + installed_pkgs = list_pkgs.split() + # iterate through package groups for a given package manager for pkg_group in pkg_groups: + # if package group is in the packages.yml file if pkg_group in available_pkg_groups: - - install_pkg_group(installed_pkgs, + install_pkg_group(pkg_cmds['install'], available_pkg_groups[pkg_group], - pkg_cmds['install']) + installed_pkgs) sub_header(f'{pkg_group.title()} packages installed.') + # run final cleanup commands, if any if 'cleanup' in pkg_cmds: subproc([pkg_cmds['cleanup']]) sub_header("[b]Cleanup[/b] step Completed.") - return + return True -def install_pkg_group(installed_pkgs=[], pkgs_to_install=[], install_cmd=""): +def install_pkg_group(install_cmd="", pkgs_to_install=[], installed_pkgs=[]): """ - installs packages if they are not already intalled with intall_cmd + Installs packages if they are not already installed. + provided install command string. Returns True. """ - SPINNER = True - install_pkg = False - # the spinner status thing rich provides breaks with input - if 'sudo' in install_cmd: - SPINNER = False - - if 'upgrade' in install_cmd or not installed_pkgs: - install_pkg = True - - log.debug(f"pkgs_to_install are {pkgs_to_install}") + log.debug(f"Currently installed packages: {installed_pkgs}") + log.info(f"Packages to install are: {pkgs_to_install}") for pkg in pkgs_to_install: - if installed_pkgs: - if pkg not in installed_pkgs: - log.info(f"{pkg} not in installed packages. Installing...") - install_pkg = True - if install_pkg: - subproc([install_cmd + pkg], quiet=True, spinner=SPINNER) - return True - - -def run_gaming_specific_cmds(): - """ - run commands specific to gaming package group: - add i386 architecture, add contrib/non-free to sources.list, and update - """ - cmds = ["sudo dpkg --add-architecture i386", - f"sudo {PWD}/scripts/update_apt_sources.sh"] - subproc(cmds, spinner=False) + if not installed_pkgs: + log.info(f"{pkg} isn't installed. Installing now...") + else: + # this variable defaults to pkg unless it has special strings in it + pkg_short_name = pkg + + # for things like steam:i386 for apt + if ":" in pkg: + pkg_short_name = pkg.split(':')[0] + + # this covers things like "--cask iterm2" for brew + if "--cask" in pkg: + pkg_short_name = pkg.split(' ')[1] + + log.debug(f"Checking if {pkg_short_name} is installed...") + if pkg_short_name in installed_pkgs: + if 'upgrade' not in install_cmd: + log.info(f"{pkg} already installed. Moving on.") + # continues to the next pkg in the pkgs_to_install list + continue + # if the install command has upgrade in it, we always run it + else: + log.info(f"Upgrading {pkg} now...") + + # Actual installation + subproc([install_cmd + pkg], quiet=True) return True diff --git a/pyproject.toml b/pyproject.toml index 46c0ed2f..e46c5c55 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "onboardme" -version = "0.15.6" +version = "0.15.7" description = "An onboarding tool to install dot files and packages including a default mode with sensible defaults to run on most Debian/macOS machines." authors = ["Jesse Hitch "] license = "AGPL-3.0-or-later"