diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/archroot.sh | 67 | ||||
-rw-r--r-- | lib/common.sh | 129 | ||||
-rw-r--r-- | lib/valid-tags.sh | 4 |
3 files changed, 163 insertions, 37 deletions
diff --git a/lib/archroot.sh b/lib/archroot.sh new file mode 100644 index 0000000..98fd2cf --- /dev/null +++ b/lib/archroot.sh @@ -0,0 +1,67 @@ +#!/hint/bash +# License: Unspecified +: + +# shellcheck disable=2034 +CHROOT_VERSION='v4' + +## +# usage : check_root +## +orig_argv=("$0" "$@") +check_root() { + (( EUID == 0 )) && return + if type -P sudo >/dev/null; then + exec sudo -- "${orig_argv[@]}" + else + exec su root -c "$(printf ' %q' "${orig_argv[@]}")" + fi +} + +## +# usage : is_btrfs( $path ) +# return : whether $path is on a btrfs +## +is_btrfs() { + [[ -e "$1" && "$(stat -f -c %T "$1")" == btrfs ]] +} + +## +# usage : is_subvolume( $path ) +# return : whether $path is a the root of a btrfs subvolume (including +# the top-level subvolume). +## +is_subvolume() { + [[ -e "$1" && "$(stat -f -c %T "$1")" == btrfs && "$(stat -c %i "$1")" == 256 ]] +} + +## +# usage : is_same_fs( $path_a, $path_b ) +# return : whether $path_a and $path_b are on the same filesystem +## +is_same_fs() { + [[ "$(stat -c %d "$1")" == "$(stat -c %d "$1")" ]] +} + +## +# usage : subvolume_delete_recursive( $path ) +# +# Find all btrfs subvolumes under and including $path and delete them. +## +subvolume_delete_recursive() { + local subvol + + is_subvolume "$1" || return 0 + + while IFS= read -d $'\0' -r subvol; do + if ! subvolume_delete_recursive "$subvol"; then + return 1 + fi + done < <(find "$1" -mindepth 1 -xdev -depth -inum 256 -print0) + if ! btrfs subvolume delete "$1" &>/dev/null; then + error "Unable to delete subvolume %s" "$subvol" + return 1 + fi + + return 0 +} diff --git a/lib/common.sh b/lib/common.sh index 68b001d..118a06c 100644 --- a/lib/common.sh +++ b/lib/common.sh @@ -25,7 +25,7 @@ _l() { shopt -s extglob # check if messages are to be printed using color -declare ALL_OFF= BOLD= BLUE= GREEN= RED= YELLOW= +declare ALL_OFF='' BOLD='' BLUE='' GREEN='' RED='' YELLOW='' if [[ -t 2 ]]; then # prefer terminal safe colored and bold text when tput is supported if tput setaf 0 &>/dev/null; then @@ -47,36 +47,43 @@ fi readonly ALL_OFF BOLD BLUE GREEN RED YELLOW plain() { - local mesg="$(_ "$1")"; shift + local mesg; mesg="$(_ "$1")"; shift + # shellcheck disable=2059 printf "${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 } msg() { - local mesg="$(_ "$1")"; shift + local mesg; mesg="$(_ "$1")"; shift + # shellcheck disable=2059 printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 } msg2() { - local mesg="$(_ "$1")"; shift + local mesg; mesg="$(_ "$1")"; shift + # shellcheck disable=2059 printf "${BLUE} ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 } warning() { - local mesg="$(_ "$1")"; shift - printf "${YELLOW}==> $(_l _ "WARNING:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 + local mesg; mesg="$(_ "$1")"; shift + # shellcheck disable=2059 + printf "${YELLOW}==> WARNING:${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 } error() { - local mesg="$(_ "$1")"; shift - printf "${RED}==> $(_l _ "ERROR:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 + local mesg; mesg="$(_ "$1")"; shift + # shellcheck disable=2059 + printf "${RED}==> ERROR:${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 } stat_busy() { - local mesg="$(_ "$1")"; shift + local mesg; mesg="$(_ "$1")"; shift + # shellcheck disable=2059 printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}...${ALL_OFF}" "$@" >&2 } stat_done() { + # shellcheck disable=2059 printf "${BOLD}$(_l _ "done")${ALL_OFF}\n" >&2 } @@ -92,7 +99,7 @@ cleanup() { if [[ -n ${WORKDIR:-} ]] && $_setup_workdir; then rm -rf "$WORKDIR" fi - exit ${1:-0} + exit "${1:-0}" } abort() { @@ -125,7 +132,7 @@ in_array() { local needle=$1; shift local item for item in "$@"; do - [[ $item = $needle ]] && return 0 # Found + [[ $item = "$needle" ]] && return 0 # Found done return 1 # Not Found } @@ -136,24 +143,27 @@ in_array() { ## get_full_version() { # set defaults if they weren't specified in buildfile - pkgbase=${pkgbase:-${pkgname[0]}} - epoch=${epoch:-0} + local pkgbase=${pkgbase:-${pkgname[0]}} + local epoch=${epoch:-0} + local pkgver=${pkgver} + local pkgrel=${pkgrel} if [[ -z $1 ]]; then if (( ! epoch )); then - echo $pkgver-$pkgrel + printf '%s\n' "$pkgver-$pkgrel" else - echo $epoch:$pkgver-$pkgrel + printf '%s\n' "$epoch:$pkgver-$pkgrel" fi else + local pkgver_override='' pkgrel_override='' epoch_override='' for i in pkgver pkgrel epoch; do local indirect="${i}_override" - eval $(declare -f package_$1 | sed -n "s/\(^[[:space:]]*$i=\)/${i}_override=/p") + eval "$(declare -f "package_$1" | sed -n "s/\(^[[:space:]]*$i=\)/${i}_override=/p")" [[ -z ${!indirect} ]] && eval ${indirect}=\"${!i}\" done - if (( ! $epoch_override )); then - echo $pkgver_override-$pkgrel_override + if (( ! epoch_override )); then + printf '%s\n' "$pkgver_override-$pkgrel_override" else - echo $epoch_override:$pkgver_override-$pkgrel_override + printf '%s\n' "$epoch_override:$pkgver_override-$pkgrel_override" fi fi } @@ -164,13 +174,13 @@ get_full_version() { lock() { # Only reopen the FD if it wasn't handed to us if ! [[ "/dev/fd/$1" -ef "$2" ]]; then - mkdir -p "${2%/*}" + mkdir -p -- "$(dirname -- "$2")" eval "exec $1>"'"$2"' fi - if ! flock -n $1; then + if ! flock -n "$1"; then stat_busy "${@:3}" - flock $1 + flock "$1" stat_done fi } @@ -181,13 +191,13 @@ lock() { slock() { # Only reopen the FD if it wasn't handed to us if ! [[ "/dev/fd/$1" -ef "$2" ]]; then - mkdir -p "${2%/*}" + mkdir -p -- "$(dirname -- "$2")" eval "exec $1>"'"$2"' fi - if ! flock -sn $1; then + if ! flock -sn "$1"; then stat_busy "${@:3}" - flock -s $1 + flock -s "$1" stat_done fi } @@ -197,6 +207,8 @@ slock() { ## lock_close() { local fd=$1 + # https://github.com/koalaman/shellcheck/issues/862 + # shellcheck disable=2034 exec {fd}>&- } @@ -204,8 +216,6 @@ lock_close() { # usage: pkgver_equal( $pkgver1, $pkgver2 ) ## pkgver_equal() { - local left right - if [[ $1 = *-* && $2 = *-* ]]; then # if both versions have a pkgrel, then they must be an exact match [[ $1 = "$2" ]] @@ -224,7 +234,7 @@ pkgver_equal() { find_cached_package() { local searchdirs=("$PWD" "$PKGDEST") results=() local targetname=$1 targetver=$2 targetarch=$3 - local dir pkg pkgbasename pkgparts name ver rel arch size r results + local dir pkg pkgbasename name ver rel arch r results for dir in "${searchdirs[@]}"; do [[ -d $dir ]] || continue @@ -262,7 +272,7 @@ find_cached_package() { return 1 ;; 1) - printf '%s\n' "$results" + printf '%s\n' "${results[0]}" return 0 ;; *) @@ -273,13 +283,58 @@ find_cached_package() { } ## -# usage : check_root ("$0" "$@") +# usage: find_cached_srcpackage( $pkgname, $pkgver, $arch ) +# +# $pkgver can be supplied with or without a pkgrel appended. +# If not supplied, any pkgrel will be matched. ## -check_root() { - (( EUID == 0 )) && return - if type -P sudo >/dev/null; then - exec sudo -- "$@" - else - exec su root -c "$(printf ' %q' "$@")" - fi +find_cached_srcpackage() { + local searchdirs=("$PWD" "$SRCPKGDEST") results=() + local targetname=$1 targetver=$2 targetarch=$3 + local dir pkg pkgbasename name ver rel arch r results + + for dir in "${searchdirs[@]}"; do + [[ -d $dir ]] || continue + + for pkg in "$dir"/*.src.tar?(.?z); do + [[ -f $pkg ]] || continue + + # avoid adding duplicates of the same inode + for r in "${results[@]}"; do + [[ $r -ef $pkg ]] && continue 2 + done + + # split apart package filename into parts + pkgbasename=${pkg##*/} + pkgbasename=${pkgbasename%.src.tar?(.?z)} + + arch=${pkgbasename##*-} + pkgbasename=${pkgbasename%-"$arch"} + + rel=${pkgbasename##*-} + pkgbasename=${pkgbasename%-"$rel"} + + ver=${pkgbasename##*-} + name=${pkgbasename%-"$ver"} + + if [[ $targetname = "$name" && $targetarch = "$arch" ]] && + pkgver_equal "$targetver" "$ver-$rel"; then + results+=("$pkg") + fi + done + done + + case ${#results[*]} in + 0) + return 1 + ;; + 1) + printf '%s\n' "${results[0]}" + return 0 + ;; + *) + _l error 'Multiple packages found:' + printf '\t%s\n' "${results[@]}" >&2 + return 1 + esac } diff --git a/lib/valid-tags.sh b/lib/valid-tags.sh index 0543ab2..2916dc7 100644 --- a/lib/valid-tags.sh +++ b/lib/valid-tags.sh @@ -1,11 +1,15 @@ +#!/hint/bash # License: Unspecified +: +# shellcheck disable=2034 _arch=( i686 x86_64 any ) +# shellcheck disable=2034 _tags=( core-i686 core-x86_64 core-any extra-i686 extra-x86_64 extra-any |