dots

git clone git://mattcarlson.org/repos/dots.git
Log | Files | Refs

pkgs.sh (6225B)


      1 #!/bin/sh
      2 #
      3 # pkgs
      4 
      5 ICON=''
      6 UPGRADE_ICON=''
      7 UPGRADE_TMP='/tmp/upgrade-pkgs'
      8 AUR_HELPER='paru'
      9 PKGS="${XDG_CACHE_HOME:-${HOME}/.cache}/dots/bar/pkgs"
     10 GET_TMP='/tmp/get-pkgs'
     11 GET_ICON=''
     12 
     13 get_os() {
     14     # oses defined by their pkg managers
     15     command -v pacman >/dev/null                          && os='arch'
     16     { command -v apt || command -v apt-get ; } >/dev/null && os='debian'
     17     command -v emerge >/dev/null                          && os='gentoo'
     18     command -v xbps-install >/dev/null                    && os='void'
     19 }
     20 
     21 upgrade_pkgs() {
     22     # remove the temp icon when the process is suddenly stopped/killed
     23     trap 'rm -f ${UPGRADE_TMP}; exit 1' INT TERM
     24 
     25     # for arch-based systems
     26     upgrade_arch_pkgs() {
     27         # arch has both pacman and AUR repos; handle them
     28         upgrade_repo_pkgs() {
     29             while :; do
     30                 get_pkgs silent
     31 
     32                 case "${1}" in
     33                     # official repos
     34                     'pacman') repo_type='Official'
     35                               # grep -c is more accurate than wc -l
     36                               available_upgrades=$(printf '%s' "${pacman_pkgs}" | grep -c '^')
     37                               cmd='doas pacman'
     38                               ;;
     39                     # aur repo
     40                     'aur')    repo_type='AUR'
     41                               available_upgrades=$(printf '%s' "${aur_pkgs}" | grep -c '^')
     42                               cmd="${AUR_HELPER} -a"
     43                               ;;
     44                     *)        return 1 ;;
     45                 esac
     46 
     47                 # no available upgrades at the moment
     48                 if [ "${available_upgrades}" -eq 0 ]; then
     49                     [ "${repo_type}" = 'Official' ] && repo_type="$(printf '%s\n' "${repo_type}" | tr '[:upper:]' '[:lower:]')"
     50                     printf '%s\n' "No ${repo_type} packages available for upgrade at the moment. Press any key to continue."
     51                     read -r input
     52                     return
     53                 else
     54                     # try the command; pacman and AUR helper will use similar flags
     55                     # if it fails ask the user to retry
     56                     if ! ${cmd} -Syu; then
     57                         printf '%s\n' "${repo_type} packages failed to upgrade. Retry? [Y/n] "
     58                         read -r input
     59                         input="$(printf '%s\n' "${input}" | tr '[:upper:]' '[:lower:]')"
     60                         if [ "${input}" = 'y' ]; then continue
     61                         else return 1
     62                         fi
     63                     else return
     64                     fi
     65                 fi
     66             done
     67         }
     68 
     69         upgrade_repo_pkgs 'pacman'
     70         upgrade_repo_pkgs 'aur'
     71     }
     72 
     73     touch "${UPGRADE_TMP}"
     74 
     75     # print pretty banner
     76     # for some reason printing codes doesn't work in new terminal, so just use tput
     77     theme=$(tput setaf 2)
     78     reset=$(tput sgr0)
     79     printf '%s\n\n' "${theme}██████╗ ██╗  ██╗ ██████╗ ███████╗
     80 ██╔══██╗██║ ██╔╝██╔════╝ ██╔════╝
     81 ██████╔╝█████╔╝ ██║  ███╗███████╗
     82 ██╔═══╝ ██╔═██╗ ██║   ██║╚════██║
     83 ██║     ██║  ██╗╚██████╔╝███████║
     84 ╚═╝     ╚═╝  ╚═╝ ╚═════╝ ╚══════╝${reset}"
     85 
     86     # upgrade pkgs depending on os
     87     get_os
     88     case "${os}" in 'arch') upgrade_arch_pkgs ;; esac
     89 
     90     rm -f "${UPGRADE_TMP}"
     91 
     92     # update counter immediately after upgrade
     93     get_pkgs &
     94 }
     95 
     96 get_pkgs() {
     97     [ "${1}" = 'silent' ] || touch "${GET_TMP}"
     98 
     99     get_os
    100     case "${os}" in
    101         'arch') # user will not need to input pass if set up correctly
    102                 # -Sy simply syncs the databases
    103                 doas pacman -Sy >/dev/null 2>&1
    104                 # -Qu will print out the actual upgrades
    105                 pacman_pkgs="$(pacman -Qu 2>/dev/null | grep -v '^.*\[ignored\]$')"
    106                 if command -v "${AUR_HELPER}" >/dev/null; then
    107                     # print just AUR upgrades with AUR helper
    108                     aur_pkgs="$("${AUR_HELPER}" -Qum --devel 2>/dev/null)"
    109                 fi
    110 
    111                 pkgs="$(printf '%s\n' "${pacman_pkgs}")"
    112 
    113                 # if there are no pacman pkgs we do not need a newline
    114                 # but we do need a newline if there are
    115                 [ ! "${pkgs}" ] && pkgs="${pkgs}$(printf '%s\n' "${aur_pkgs}")"   \
    116                                 || pkgs="${pkgs}$(printf '\n%s\n' "${aur_pkgs}")"
    117                 ;;
    118     esac
    119 
    120     # print pkgs to cache
    121     # cache is useful in case of internet loss, etc.
    122     # do NOT use newline with printf here or else count will be messed up
    123     if [ -f "${PKGS}" ]; then
    124         printf '%s' "${pkgs}" > "${PKGS}"
    125     else touch "${PKGS}"
    126     fi
    127 
    128     [ -f "${GET_TMP}" ] && rm -f "${GET_TMP}"
    129 }
    130 
    131 bar() {
    132     # get count from cache, will be updated whenever get_pkgs is called, either manually or from cron, etc.
    133     [ -f "${PKGS}" ] && pkgs=$(grep -c '^' < "${PKGS}")
    134 
    135     # get icon
    136     [ -f "${GET_TMP}" ] && printf '%s\n' "${GET_ICON}" && return
    137 
    138     # upgrade icon
    139     #shellcheck disable=SC2009
    140     if ps -ef | grep -i '\<upgrade_pkgs\>'| grep -iqv '\<grep\>'; then printf '%s\n' "${UPGRADE_ICON}"
    141     # icon and count
    142     else printf '%s\n' "${ICON} ${pkgs}"
    143     fi
    144 }
    145 
    146 open() {
    147     "${TERMINAL}" -c "${TERMINAL}" -e pkgs.sh upgrade_pkgs
    148     get_pkgs &
    149 }
    150 
    151 main() {
    152     # called from bar
    153     [ ${#} -eq 0 ] && bar
    154 
    155     # upgrade_pkgs is argument so function can be run in new terminal
    156     case "${1}" in upgrade_pkgs) upgrade_pkgs && return 0 ;; esac
    157 
    158     # bar usage
    159     case ${BLOCK_BUTTON} in
    160         # pass upgrade_pkgs to new terminal
    161         1) open     ;;
    162         2) get_pkgs ;;
    163     esac
    164 
    165     while getopts 'gou' opt; do
    166         case "${opt}" in
    167             # get upgradable pkgs
    168             g) get_pkgs     ;;
    169             # upgrade pkgs in new terminal
    170             o) open         ;;
    171             # upgrade if called with u flag
    172             u) upgrade_pkgs ;;
    173             *) return       ;;
    174         esac
    175     done
    176 }
    177 
    178 main "${@}"