--- packer.old/packer 2012-02-25 03:49:45.000000000 -0800 +++ packer.new/packer 2012-02-25 03:28:49.088184439 -0800 @@ -23,6 +23,8 @@ makepkgconf='/etc/makepkg.conf' usermakepkgconf="$HOME/.makepkg.conf" pacmanconf='/etc/pacman.conf' +absconf='/etc/abs.conf' +userabsconf='~.abs.conf' RPCURL="https://aur.archlinux.org/rpc.php?type" PKGURL="https://aur.archlinux.org" @@ -56,6 +58,7 @@ echo echo ' -S - installs package' echo ' -Syu|-Su - updates all packages, also takes -uu and -yy options' + echo ' -Sb - builds from ABS; use the ABSPKG variable for updates' echo ' -Ss|-Ssq - searches for package' echo ' -Si - outputs info for package' echo ' -G - download and extract aur tarball only' @@ -89,6 +92,12 @@ [[ -r "$usermakepkgconf" ]] && . "$usermakepkgconf" } +# Source abs.conf file +sourceabsconf() { + . "$absconf" + [[ -r "$userabsconf" ]] && . "$userabsconf" +} + # Parse IgnorePkg and --ignore, put in globally accessible ignoredpackages array getignoredpackages() { IFS=',' read -ra ignoredpackages <<< "$ignorearg" @@ -108,7 +117,7 @@ # Tests whether $1 exists in pacman existsinpacman() { - pacman -Si -- "$1" &>/dev/null + $PACMAN -Si -- "$1" &>/dev/null } # Tests whether $1 is provided in pacman, sets globally accessibly providepkg var @@ -118,23 +127,79 @@ # Tests whether $1 exists in a pacman group existsinpacmangroup() { - [[ $(pacman -Sgq "$1") ]] + [[ $($PACMAN -Sgq "$1") ]] } # Tests whether $1 exists locally existsinlocal() { - pacman -Qq -- "$1" &>/dev/null + $PACMAN -Qq -- "$1" &>/dev/null +} + +# Runs customizepkg on AUR/ABS PKGBUILDs to ensure accurate deps +custdeps() { + if [[ -f "/etc/customizepkg.d/$1" ]] && type -t customizepkg &>/dev/null; then + mkdir "$tmpdir/$1" + mv "$tmpdir/$1.PKGBUILD" "$tmpdir/$1/PKGBUILD" + cd "$tmpdir/$1" + customizepkg --modify &>/dev/null + mv "$tmpdir/$1/PKGBUILD" "$tmpdir/$1.PKGBUILD" + cd "$tmpdir" + rm -rf "$tmpdir/$1" + fi } # Scrapes the aur deps from PKGBUILDS and puts in globally available dependencies array scrapeaurdeps() { pkginfo "$1" + custdeps "$1" . "$tmpdir/$1.PKGBUILD" IFS=$'\n' dependencies=( $(echo -e "${depends[*]}\n${makedepends[*]}" | sed -e 's/=.*//' -e 's/>.*//' -e 's/<.*//'| sort -u) ) unset IFS } +# Gets ABS PKGBUILD +absinfo() { + if ! [[ -f "$tmpdir/$1.PKGBUILD" ]]; then + sourceabsconf + if existsinpacman $1; then + pkgrepo="$($PACMAN -Si -- "$1" 2>/dev/null | sed -e 's/Repository : //g' -e '1q;d')" + if [[ -n "$pkgrepo" && "${REPOS[*]}" =~ "$pkgrepo" ]]; then + if ! rsync -mrtvq --no-motd --no-p --no-o --no-g "$SYNCSERVER::abs/$ARCH/$pkgrepo/$1/PKGBUILD" "$tmpdir/$1.PKGBUILD"; then + abserr=1 + fi + else + err "Could not determine repo!" + fi + else + err "Package does not exist in pacman!" + fi + fi +} + +# Scrapes the deps from abs PKGBUILDS and puts in globally available dependencies array +scrapeabsdeps() { + absinfo $1 PKGBUILD + custdeps "$1" + . "$tmpdir/$1.PKGBUILD" + IFS=$'\n' + dependencies=( $(echo -e "${depends[*]}\n${makedepends[*]}" | sed -e 's/=.*//' -e 's/>.*//' -e 's/<.*//'| sort -u) ) + unset IFS +} + +# Gets the version from the pkgbuild. +scrapeabsver() { + if [ -e "$tmpdir/$1.PKGBUILD" ]; then + rm -f "$tmpdir/$1.PKGBUILD" + fi + absinfo $1 PKGBUILD + if [ -z "$abserr" ]; then + custdeps "$1" + . "$tmpdir/$1.PKGBUILD" + version=${pkgver}-${pkgrel} + fi +} + # Finds dependencies of package $1 # Sets pacmandeps and aurdeps array, which can be accessed globally after function runs finddeps() { @@ -142,7 +207,7 @@ pacmandeps=() aurdeps=() scrapeaurdeps "$1" - missingdeps=( $(pacman -T "${dependencies[@]}") ) + missingdeps=( $($PACMAN -T "${dependencies[@]}") ) while [[ $missingdeps ]]; do checkdeps=() for dep in "${missingdeps[@]}"; do @@ -170,7 +235,48 @@ for dep in "${checkdeps[@]}"; do scrapeaurdeps "$dep" for depdep in "${dependencies[@]}"; do - [[ $(pacman -T "$depdep") ]] && missingdeps+=("$depdep") + [[ $($PACMAN -T "$depdep") ]] && missingdeps+=("$depdep") + done + done + done + return 0 +} + +# Finds dependencies of package $1 (ABS packages) +findabsdeps() { + # loop through dependencies, if not installed, determine if pacman or aur deps + pacmandeps=() + aurdeps=() + scrapeabsdeps "$1" + missingdeps=( $($PACMAN -T "${dependencies[@]}") ) + while [[ $missingdeps ]]; do + checkdeps=() + for dep in "${missingdeps[@]}"; do + if [[ " $1 ${aurdeps[@]} ${pacmandeps[@]} " =~ " $dep " ]]; then + continue + fi + if existsinpacman "$dep"; then + pacmandeps+=("$dep") + elif existsinaur "$dep"; then + if [[ $aurdeps ]]; then + aurdeps=("$dep" "${aurdeps[@]}") + else + aurdeps=("$dep") + fi + checkdeps+=("$dep") + elif providedinpacman "$dep"; then + pacmandeps+=("$providepkg") + else + [[ $option = "install" ]] && err "Dependency \`$dep' of \`$1' does not exist." + echo "Dependency \`$dep' of \`$1' does not exist." + return 1 + fi + done + missingdeps=() + for dep in "${checkdeps[@]}"; do + scrapeabsdeps "$dep" + for depdep in "${dependencies[@]}"; do + [[ $($PACMAN -T "$depdep") ]] && missingdeps+=("$depdep") done done done @@ -236,8 +342,8 @@ pkginfo() { if ! [[ -f "$tmpdir/$1.PKGBUILD" ]]; then - pkgpath=$(pkglink $1) - curl -Lfs "${pkgpath%/*}/PKGBUILD" > "$tmpdir/$1.PKGBUILD" + pkgpath=$(pkglink $1) + curl -Lfs "${pkgpath%/*}/PKGBUILD" > "$tmpdir/$1.PKGBUILD" fi } @@ -319,6 +425,64 @@ fi } +# Gets ABS PKGBUILD, $1 is package name +getabspkgbuild() { + sourceabsconf + pkgrepo="$($PACMAN -Si -- "$1" 2>/dev/null | sed -e 's/Repository : //g' -e '1q;d')" + if [[ -n "$pkgrepo" && "${REPOS[*]}" =~ "$pkgrepo" ]]; then + rsync -mrtvq --no-motd --no-p --no-o --no-g "$SYNCSERVER::abs/$ARCH/$pkgrepo/$1/" . + else + err "Could not determine repo!" + fi +} + +# Installs packages from aur ($1 is package, $2 is dependency or explicit) +absinstall() { + dir="${TMPDIR:-/tmp}/packerbuild-$UID/$1" + + # Prepare the installation directory + # If there is an old directory delete it. + [[ -d $dir ]] && rm -rf $dir + mkdir -p "$dir" + cd "$dir" + mkdir "$1" + cd "$1" + getabspkgbuild "$1" + + # customizepkg + if [[ -f "/etc/customizepkg.d/$1" ]] && type -t customizepkg &>/dev/null; then + echo "Applying customizepkg instructions..." + customizepkg --modify + fi + #fi + + # Allow user to edit PKGBUILD + confirm_edit "${COLOR6}Edit $1 PKGBUILD with \$EDITOR? [Y/n]${ENDCOLOR} " PKGBUILD + if ! [[ -f PKGBUILD ]]; then + err "No PKGBUILD found in directory." + fi + + # Allow user to edit .install + unset install + . PKGBUILD + confirm_edit "${COLOR6}Edit $install with \$EDITOR? [Y/n]${ENDCOLOR} " "$install" + + # Installation (makepkg and pacman) + if [[ $UID -eq 0 ]]; then + makepkg $MAKEPKGOPTS --asroot -f + else + makepkg $MAKEPKGOPTS -f + fi + + + [[ $? -ne 0 ]] && echo "The build failed." && return 1 + if [[ $2 = dependency ]]; then + runasroot $PACMAN ${PACOPTS[@]} --asdeps -U $pkgname-*$PKGEXT + elif [[ $2 = explicit ]]; then + runasroot $PACMAN ${PACOPTS[@]} -U $pkgname-*$PKGEXT + fi +} + # Goes through all of the install tests and execution ($@ is packages to be installed) installhandling() { packageargs=("$@") @@ -326,8 +490,15 @@ sourcemakepkgconf # Figure out all of the packages that need to be installed for package in "${packageargs[@]}"; do + # Determine if repo package is to be built from source + if ! [[ $auronly ]] && existsinpacman "$package" && [[ $abs = yes ]] ; then + if findabsdeps "$package"; then + # here is where dep dupes are created + abspackages+=("$package") + pacmandepends+=("${pacmandeps[@]}") + fi # Determine whether package is in pacman repos - if ! [[ $auronly ]] && existsinpacman "$package"; then + elif ! [[ $auronly ]] && existsinpacman "$package"; then pacmanpackages+=("$package") elif ! [[ $auronly ]] && existsinpacmangroup "$package"; then pacmanpackages+=("$package") @@ -370,13 +541,14 @@ if [[ $pacmanpackages ]]; then runasroot $PACMAN "${PACOPTS[@]}" -S -- "${pacmanpackages[@]}" fi - if [[ -z $aurtargets ]]; then + if [[ -z $aurtargets && -z $abspackages ]]; then exit fi + # Test if aurpackages are already installed; echo warning if so for pkg in "${aurtargets[@]}"; do if existsinlocal "$pkg"; then - localversion="$(pacman -Qs "$pkg" | grep -F "local/$pkg" | cut -d ' ' -f 2)" + localversion="$($PACMAN -Qs "$pkg" | grep -F "local/$pkg" | cut -d ' ' -f 2)" if ! aurversionisnewer "$pkg" "$localversion"; then echo -e "${COLOR6}warning:$ENDCOLOR $pkg-$localversion is up to date -- reinstalling" fi @@ -395,9 +567,12 @@ if [[ $aurdepends ]]; then num="$((${#aurdepends[@]}+${#aurtargets[@]}))" echo -e "${COLOR6}Aur Targets ($num):${ENDCOLOR} ${aurdepends[@]} ${aurtargets[@]}" - else + elif [[ $aurtargets ]]; then echo -e "${COLOR6}Aur Targets ($((${#aurtargets[@]}))):${ENDCOLOR} ${aurtargets[@]}" fi + if [[ $abspackages ]]; then + echo -e "${COLOR6}Abs Targets ($((${#abspackages[@]}))):${ENDCOLOR} ${abspackages[@]}" + fi if [[ $pacmandepends ]]; then IFS=$'\n' read -rd '' -a pacmandepends < \ <(printf "%s\n" "${pacmandepends[@]}" | sort -u) @@ -425,14 +600,28 @@ fi # Install the aur packages - for package in "${aurtargets[@]}"; do - scrapeaurdeps "$package" - if pacman -T "${dependencies[@]}" &>/dev/null; then - aurinstall "$package" "explicit" - else - echo "Dependencies for \`$package' are not met, not building..." - fi - done + if [[ $aurtargets ]]; then + for package in "${aurtargets[@]}"; do + scrapeaurdeps "$package" + if $PACMAN -T "${dependencies[@]}" &>/dev/null; then + aurinstall "$package" "explicit" + else + echo "Dependencies for \`$package' are not met, not building..." + fi + done + fi + + # Install the abs packages + if [[ $abspackages ]]; then + for package in "${abspackages[@]}"; do + scrapeabsdeps "$package" + if $PACMAN -T "${dependencies[@]}" &>/dev/null; then + absinstall "$package" "explicit" + else + echo "Dependencies for \`$package' are not met, not building..." + fi + done + fi } # proceed with installation prompt @@ -458,6 +647,7 @@ while [[ $1 ]]; do case "$1" in '-S') option=install ;; + '-Sb') option=install ; abs=yes ;; '-Ss') option=search ;; '-Ssq'|'-Sqs') option=search ; quiet='1' ;; '-Si') option=info ;; @@ -472,7 +662,8 @@ '--devel') devel='1' ;; '--skipinteg') MAKEPKGOPTS="--skipinteg" ;; '--') shift ; packageargs+=("$@") ; break ;; - -*) echo "packer: Option \`$1' is not valid." ; exit 5 ;; + -Q*) $PACMAN $@; exit 5;; + -*) runasroot $PACMAN $@; exit 5;; *) packageargs+=("$1") ;; esac shift @@ -492,11 +683,40 @@ if [[ $option = update ]]; then getignoredpackages sourcemakepkgconf + + # Abs update + if [[ "$ABSPKGS" ]]; then + echo -e "${COLOR5}:: ${COLOR1}Checking ABS Packages...${ENDCOLOR}" + absarray=($ABSPKGS) + absupdate=() + for i in ${absarray[@]}; do + instver="$($PACMAN -Qi -- "$i" 2>/dev/null | sed -e 's/Version : //g' -e '2q;d')" + scrapeabsver $i + if [ "$abserr" = 1 ]; then + echo "Error while checking ABS Packages!" + echo + absupdate="" + break + fi + if [ $(vercmp $version $instver) -gt 0 ]; then + absupdate+=("$i") + fi + done + if [[ "$absupdate" ]]; then + abs=yes + installhandling "${absupdate[@]}" + unset abs + else + absignore=$(echo "$ABSPKGS" | tr ' ' ',') + PACOPTS+=("--ignore" "$absignore") + fi + fi + # Pacman update if ! [[ $auronly ]]; then runasroot $PACMAN "${PACOPTS[@]}" "$pacmanarg" fi - + # Aur update echo -e "${COLOR5}:: ${COLOR1}Synchronizing aur database...${ENDCOLOR}" IFS=$'\n' read -rd '' -a packages < <(pacman -Qm) @@ -592,18 +812,26 @@ # Pacman searching if ! [[ $auronly ]]; then if [[ $quiet ]]; then - results="$(pacman -Ssq -- "${packageargs[@]}")" + results="$($PACMAN -Ssq -- "${packageargs[@]}")" else - results="$(pacman -Ss -- "${packageargs[@]}")" + results="$($PACMAN -Ss -- "${packageargs[@]}")" + # Repo results="$(sed -r "s|^[^ ][^/]*/|$S${COLOR3}&$S${COLOR1}|" <<< "$results")" + # Package results="$(sed -r "s|^([^ ]+) ([^ ]+)(.*)$|\1 $S${COLOR2}\2$S${ENDCOLOR}\3|" <<< "$results")" + # Group + results="$(sed -r "s|^([^ ]+ [^ ]+ \[.*\]) (\(.*\))(.*)$|\1 $S${COLOR5}\2$S${ENDCOLOR}\3|" <<< "$results")" + # Status + results="$(sed -r "s|^([^ ]+ [^ ]+ \[.*\].*) (\[.*\])$|\1 $S${COLOR4}\2$S${ENDCOLOR}|" <<< "$results")" + fi + if [ "$results" ]; then + if [[ $option = search ]]; then + echo -e "$results" | fmt -"$_WIDTH" -s + else # interactive + echo -e "$results" | fmt -"$_WIDTH" -s | nl -v 0 -w 1 -s ' ' -b 'p^[^ ]' + fi | sed '/^$/d' fi - if [[ $option = search ]]; then - echo -e "$results" | fmt -"$_WIDTH" -s - else # interactive - echo -e "$results" | fmt -"$_WIDTH" -s | nl -v 0 -w 1 -s ' ' -b 'p^[^ ]' - fi | sed '/^$/d' - pacname=( $(pacman -Ssq -- "${packageargs[@]}") ) + pacname=( $($PACMAN -Ssq -- "${packageargs[@]}") ) pactotal="${#pacname[@]}" else pactotal=0 @@ -687,7 +915,7 @@ sourcemakepkgconf for package in "${packageargs[@]}"; do if ! [[ $auronly ]] && existsinpacman "$package"; then - results="$(pacman -Si -- "$package")" + results="$($PACMAN -Si -- "$package")" results="$(sed -r "s|^(Repository[^:]*:)(.*)$|\1$S${COLOR3}\2$S${ENDCOLOR}|" <<< "$results")" results="$(sed -r "s|^(Name[^:]*:)(.*)$|\1$S${COLOR1}\2$S${ENDCOLOR}|" <<< "$results")" results="$(sed -r "s|^(Version[^:]*:)(.*)$|\1$S${COLOR2}\2$S${ENDCOLOR}|" <<< "$results")"