#!/usr/bin/env miaou-bash # CONSTANTS REFRESH_SLOT='24 hours' DEBIAN_REPO_DIR='/var/lib/apt/lists/partial' ARCH_REPO_DIR='/var/lib/pacman/sync' # functions function usage { echo "usage: $(basename "$0") " echo 'idempotent package installation : install only if not yet done + smart refresh repositories' } # $1 -> file to compare with REFRESH_SLOT function needs_refresh { [[ $(date --date="-$REFRESH_SLOT" +%s) -gt $(date -d "$(stat -c %y "$1")" +%s) ]] } function debian_update_repo { if needs_refresh "$DEBIAN_REPO_DIR"; then echo "updating repositories..." apt-get update fi } function debian_add { declare -a wanted=("$@") 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 missing+=("${BASH_REMATCH[1]}") elif [[ "$query" =~ $missing_regex ]]; then missing+=("${BASH_REMATCH[1]}") fi done if [[ "${#missing[@]}" -gt 0 ]]; then debian_update_repo echo installing packages: "${missing[@]}" apt-get install -y "${missing[@]}" fi } function arch_update_repo { if needs_refresh "$ARCH_REPO_DIR"; then echo "updating repositories..." pacman -Syyu --noconfirm fi } function arch_add { declare -a wanted=("$@") declare -a missing=() for i in "${wanted[@]}"; do if ! pacman -Ql "$i" &>/dev/null; then missing+=("$i") fi done if [[ "${#missing[@]}" -gt 0 ]]; then arch_update_repo echo installing packages: "${missing[@]}" pacman -S --noconfirm "${missing[@]}" fi } # MAIN [ "$UID" -ne 0 ] && echo 'root privilege required' && builtin exit 1 [[ $# -lt 1 ]] && usage && builtin exit 2 source "$MIAOU_BASH_DIR"/lib/functions.bash DISTRO_LIKE=$(get_distro_like) case "$DISTRO_LIKE" in debian) debian_add "$@" ;; arch) arch_add "$@" ;; esac