diff --git a/lib/functions.bash b/lib/functions.bash index 9bfac9e..8c30f07 100644 --- a/lib/functions.bash +++ b/lib/functions.bash @@ -32,7 +32,6 @@ function _array_subtract { declare -A exclude for item in "${arr2[@]}"; do exclude["$item"]=1; done - result=() for item in "${arr1[@]}"; do [[ -z ${exclude["$item"]} ]] && result+=("$item"); done } @@ -89,6 +88,25 @@ function _flatten_short_options { args=("${result[@]}") } +# DISTRO + +function get_distro_like { + mapfile -t release " + echo 'idempotent package installation : update if necessary, install only if not yet done' +} + +function debian_update_repo { + if [ "$(date --date='-12 hours' +%s)" -gt "$(date -d "$(stat -c %y /var/lib/apt/lists/partial)" +%s)" ]; then + echo "updating repositoring..." + apt-get update + fi +} + +function debian_add { + debian_update_repo + declare -a wanted=("$@") + declare -a unrecognized=() + declare -a missing=() + mapfile -t queries < <(dpkg-query -W -f='${Package}: ${Status}\n' "${wanted[@]}" 2>&1 || true) + + local unrecognized_regex='^dpkg-query: no packages found matching (.*)$' + local missing_regex='(.*): .* not-installed$' + for query in "${queries[@]}"; do + if [[ "$query" =~ $unrecognized_regex ]]; then + unrecognized+=("${BASH_REMATCH[1]}") + elif [[ "$query" =~ $missing_regex ]]; then + missing+=("${BASH_REMATCH[1]}") + fi + done + + if [[ ${#unrecognized[@]} -gt 0 ]]; then + >&2 echo "$(basename "$0") error: unrecognized packages: ${unrecognized[*]}" && return 2 + elif [[ "${#missing[@]}" -gt 0 ]]; then + echo installing packages: "${missing[@]}" + apt-get install -y "${missing[@]}" + fi +} + +function arch_add { + pacman -Syyu --noconfirm + for i in "$@"; do + if ! pacman -Ql "$i" &>/dev/null; then + pacman -S --noconfirm "$i" + elif [ -n "${VERBOSE+x}" ] && $VERBOSE; then + echo "pacman package <$i> already installed!" + fi + done +} + +# MAIN + +[ "$UID" -ne 0 ] && echo 'root privilege required' && exit 2 +[[ $# -lt 1 ]] && usage && builtin exit 1 + +source "$MIAOU_BASH_DIR"/lib/functions.bash +DISTRO_LIKE=$(get_distro_like) +case "$DISTRO_LIKE" in +debian) debian_add "$@" ;; +arch) arch_add "$@" ;; +esac