New update to Baph

baph

#1

So @natemaia updated baph today to include a search.

You can either wait for the update or replace the contents of your baph script yourself

#!/bin/bash

# vim:fdm=marker:fmr={,}
# shellcheck disable=2030,2031

# Simple tool to update and install AUR packages for Arch Linux
# Written by Nathaniel Maia, September 2018
# This software is provided free of charge and WITHOUT warranty


declare -g NOVIEW=""  # disable viewing the PKGBUILD
declare -g NOCONF=""  # disable extra confirmations
declare -i CACHE=1    # keep cached package downloads

declare -a APKGS=() # aur packages, populated in pkg_args()
declare -a PPKGS=() # official packages, populated in pkg_args()

readonly BUILD_DIR="$HOME/.cache/aur_builds"   # AUR build directory
readonly AUR_ADDR="https://aur.archlinux.org"  # AUR web address

usage()
{ # show the standard UNIX style help message.. usage: usage
    cat <<- EOF
 baph - Basic AUR Package Helper, simply install and update AUR packages

 usage: baph <operation> [package(s)] [options]

 operations:
     baph {-h --help}
     baph {-s --search}  <query>
     baph {-u --update}  [package(s)] [options]
     baph {-i --install} <package(s)> [options]

 options:
     --noview      Skip viewing PKGBUILD files for AUR packages
     --noconfirm   Skip most confirmations when building

EOF
}

msg()
{
    printf "$1\e[0m \e[1m$2\e[0m\n"
}

die()
{
    printf "\e[1m\e[31merror:\e[0m $1\n" && exit ${2:-1}
}

yesno()
{ # ask confirmation, usage: yesno "question"
    if ! [[ $NOCONF ]]; then
        printf "\e[34m::\e[0m \e[1m$1? [Y/n]\e[0m " && read -r conf
        [[ $conf =~ [nN] ]] && return 1
    fi
    return 0
}

json()
{
    awk -F"\",\"" -v k="$1" '{ gsub(/{|}/, ""); for (i=1; i <= NF; i++) { if ($i ~ k) print $i } }' <<< "$2" &2>/dev/null
}

search()
{
    for q in "${APKGS[@]}"; do
        msg '\e[34m::' "Searching for AUR packages matching '$q'..."
        res=$(curl -sL 'https://aur.archlinux.org/rpc.php?type=search&arg='"$q")
        if [[ $res == '{"type":"error","results":"No results found"}' ]]; then
            printf "\e[1m\e[31m :: \e[0mno search results found\n"
        else
            idx=1
            OLD_IFS="$IFS"
            IFS=$'\n'
            for i in $(sed 's/},{/\n/g' <<< "$(sed 's/.*"type":"search".*"resultcount".*"results":\[//g' <<< "$res")"); do
                v=$(json "Version" "$i" | sed -e 's/Version"://' -e 's/^"//' -e 's/"$//' -e 's/^.*":".*//')
                o=$(json "OutOfDate" "$i" | sed -e 's/OutOfDate"://' -e 's/^"//' -e 's/"$//' -e 's/.*":".*//' -e 's/"]//')
                d=$(json "Description" "$i" | sed -e 's/Description":"//' -e 's/^"//' -e 's/"$//' -e 's/CategoryID":.*,"//')
                n=$(json "Name" "$i" | sed -e 's/Name":"//' -e 's/^"//' -e 's/"$//' -e 's/ID":.*,"//' -e 's/Maintainer":null,"//')
                [[ $o == "1" ]] && s="\e[1;31m  (Out of Date!)"
                printf "\e[1;33m${idx}\e[1;36m AUR/\e[1;37m${n} \e[1;32m${v}${s}\n\e[0m    $d\n"
                unset s
                (( idx++ ))
            done
            IFS="$OLD_IFS"
        fi
    done
}

update()
{ # check each package in APKGS=() for updates, usage: update

    # populate package array if not passed any
    (( ${#APKGS[@]} == 0 )) && APKGS=($(pacman -Qqm 2>/dev/null))

    if (( ${#APKGS[@]} > 0 )); then
        local up=()
        local i n o
        msg '\e[34m::' "Synchronizing AUR package versions..."
        for i in "${APKGS[@]}"; do
            n="$(pacman -Qs "^$i$" 2>/dev/null | awk 'NR==1 {print $2}')"
            o="$(curl -sL "$AUR_ADDR/packages/$i" | awk '/Details:/ {sub(/<\/h.?>/,""); print $4}')"
            if [[ $n && $o && $(vercmp "$o" "$n") -gt 0 ]]; then
                up+=("$i"); printf " $i \e[1m\e[31m$o \e[33m->\e[32m $n\e[0m\n"
            fi
        done

        msg '\e[34m::' "Starting AUR package upgrade..."
        if (( ${#up[@]} > 0 )); then
            printf "\n\e[1mPackages (%s)\e[0m  %s\n\n" "${#up[@]}" "${up[*]}"
            printf "\e[34m::\e[0m \e[1mProceed with package upgrade? [Y/n]\e[0m "
            read -r conf
            [[ $conf =~ [nN] ]] || for i in "${up[@]}"; do getpkg "$i"; done
        else
            printf " there is nothing to do\n"
        fi
    else
        msg '\e[34m::' "No AUR packages installed.."
    fi
    exit 0
}

install()
{ # loop over package array and install each.. usage: install
    if (( ${#PPKGS[@]} > 0 )); then
        local m="for official package(s) you should use pacman instead:\n\n "
        msg "\e[1m\e[33mwarning:" "\e[0m$m\e[32m pacman -S ${PPKGS[*]}\e[0m\n"
        exit 1
    elif (( ${#APKGS[@]} == 0 )); then
        die "no targets specified" 2
    else
        for pkg in "${APKGS[@]}"; do
            response="$(curl -sLI "$AUR_ADDR/packages/$pkg" | awk 'NR==1 {print $2}')"
            if (( response == 200 )); then
                getpkg "$pkg" || msg '\e[33m::' "Exiting $pkg build early"
            else
                local e="please check the package name is spelled correctly"
                die "$response response from $AUR_ADDR/packages/$pkg\n\n$e"
            fi
        done
    fi
}

getpkg()
{ # install an AUR package.. usage: getpkg "package"
    local bd="$BUILD_DIR/$1"
    local pkgbuild="$bd/PKGBUILD"

    (( CACHE == 1 )) || rm -rf "$bd" >/dev/null 2>&1
    [[ -d $bd ]] || mkdir -p "$bd"

    if [[ ! -e $pkgbuild || $CACHE -eq 0 ]]; then
        rm -rf "$bd" >/dev/null 2>&1
        git clone "$AUR_ADDR/$1" "$bd" ||
            die "failed to clone package repo: $AUR_ADDR/$1"
    elif [[ -e $pkgbuild ]]; then
        cd "$bd" || die "failed to change directory: $bd"
        msg '\e[34m::' "Synchronizing \e[32m$1\e[0m\e[1m git repo cache..."
        git pull || die "failed to pull package repo: $AUR_ADDR/$1"
    fi

    if [[ -e $pkgbuild ]]; then
        cd "$bd" || die "failed to change directory: $bd"
    else
        die "$bd doesn't contain a PKGBUILD"
    fi

    view "$1" "$pkgbuild" || yesno "Continue building $1" || return 1
    buildpkg "$1" "$pkgbuild"
    return 0
}

view()
{ # view PKGBUILD.. usage: view "package" "/path/to/PKGBUILD"
    if ! [[ $NOVIEW ]] && yesno "View the PKGBUILD for $1"; then
        if [[ $PAGER ]]; then
            $PAGER "$2"
        else
            less -P " -- Viewing PKGBUILD for $1 -- (press q to exit)" "$2"
        fi
        return 1
    fi
    return 0
}

buildpkg()
{ # build package.. usage: buildpkg "package" "/path/to/PKGBUILD"
    local depends=()
    local validpgpkeys=()
    eval "$(cat "$2")"
    (( ${#validpgpkeys[@]} > 0 )) && importkeys "${validpgpkeys[@]}"
    (( ${#depends[@]} > 0 )) && builddeps "$1" "${depends[@]}"
    makepkg -sicr && { rm -rf ./*.tar.xz >/dev/null 2>&1 || return 0; }
}

importkeys()
{ # import PGP keys from package.. usage: importkeys ${KEYS[@]}
    for key in "$@"; do
        if ! pacman-key --list-keys | grep -q "$key"; then
            msg '\e[33m::' "Resolving missing pgp key: $key"
            if ! gpg --receive-keys "$key" && sudo pacman-key -r "$key" &&
                    sudo pacman-key --lsign-key "$key"; then
                msg '\e[33m::' "Failed to import pgp key, continuing anyway"
            fi
        fi
    done
}

builddeps()
{ # build package depends.. usage: builddeps "package" ${DEPENDS[@]}
    local pdir="$1"; shift
    for i in "$@"; do
        dep="$(sed 's/[=<>]=\?[0-9.\-]*\?//g' <<< "$i")"
        if ! [[ $(pacman -Ssq "^$dep$" 2>/dev/null) ]]; then
            msg '\e[33m::' "Resolving \e[32m$1\e[0m\e[1m AUR dependency: $dep"
            getpkg "$dep" || die "failed to build dependency $dep"
        fi
    done
    cd "$BUILD_DIR/$pdir" || die "failed to cd $BUILD_DIR/$pdir"
}

pkg_args()
{ # parse additional command line arguments.. usage: pkg_args $@
    for i in "$@"; do case $i in
        --noview) NOVIEW="--noview" ;;
        --noconfirm) NOCONF="--noconfirm" ;;
        -*) die "invalid option -- '$i'" ;;
        *) pacman -Ssq "^$i$" >/dev/null 2>&1 && PPKGS+=("$i") || APKGS+=("$i")
    esac done
}

# catch Ctrl-C and exit
trap 'echo; exit' SIGINT

if [[ $(whoami) == 'root' ]]; then
    die "do not run baph as root" 1
elif (( $# == 0 )); then
    die "no operation specified (use -h for help)" 2
elif ! hash pacman git curl >/dev/null 2>&1; then
    die "baph requires the following packages: pacman git curl"
else
    for arg in "$@"; do
        case $arg in
            --search|-s) shift; pkg_args "$@"; search; break ;;
            --install|-i) shift; pkg_args "$@"; install; break ;;
            --update|-u) shift; pkg_args "$@"; update; break ;;
            --help|-h) usage; exit 0 ;;
            *) die "invalid option -- '$arg'"
        esac
    done
    [[ $CACHE -eq 1 ]] || rm -rf "$BUILD_DIR"/* >/dev/null 2>&1
fi

#2

Thx for the update in there & thx for the hard work.


#3

Actually have loved baph just the way it is, simple and does the job but it’ll be nice to search from time to time.

Awesome.


#4

The update will be coming through very soon.


#5

Thanks :smiley:


#6

The update has been pushed so should be good to go.


#7

awesome :slight_smile:


#8

Will update later on.


#9

Thank you very much Team!! I currently use it frequently


#10

@natemaia Thank you very much! Now it is really perfect. LOVE baph.