#!/bin/bash # TODO # * Do version checking # * Detect circular builds # * Detect pkgnames by provides, replaces, etc. instead of dir tree source /etc/makepkg.conf source /etc/abs.conf source /etc/libretools.conf [[ -r ~/.config/libretools/libretools.conf ]] && \ source ~/.config/libretools/libretools.conf function usage { echo "cd to a dir containing a PKGBUILD and run:" echo "$0 [options]" printf "This script will check dependencies, build them if possible " printf "and stage the packages on it's repo." echo echo "OPTIONS:" echo " -h : this message." echo " -f : build even when a package has been built." echo " -n absdir : set ABSROOT to this dir" echo " -r reponame : set repo name to reponame" echo " -R pkgname : build pkgname if it is a dep" echo } force_build='n' force_array=() _fullpkgargs="" failed=() missing=() while getopts 'hfn:r:R:' arg; do case $arg in h) usage; exit 0 ;; f) force_build='y' ;; R) force_array=(${force_array[@]} $OPTARG); _fullpkgargs+="-R $OPTARG ";; n) ABSROOT="$OPTARG" ;; r) repo="$OPTARG" ;; esac done [[ ! -r PKGBUILD ]] && { error "This isn't a build directory" echo usage exit 1 } tmp_dir=$(mktemp -d /tmp/$(basename $PWD).XXXXXX) queue_file=$(mktemp /tmp/queue.XXXXXX) ban_file=$(mktemp /tmp/ban.XXXXXX) ## START FUNCTIONS ## # Queue Management # * Always get the queue list from the server # * Add/Remove from queue # * Check if a package is listed # TODO # * Check for concurrence # Get the queue list from the server get_queue() { rsync -e ssh -aq $PARABOLAHOST:mips64el/queue $queue_file >/dev/null 2>&1 || { error "Failed to retrieve queue list" return 1 } } # Put the queue list on the server put_queue() { rsync -e ssh -aq $queue_file $PARABOLAHOST:mips64el/queue >/dev/null 2>&1 || { error "Failed to put queue list" return 1 } } # Add packages to the queue update_queue() { get_queue || return $? basename $PWD | sed "s/$/:$PACKAGER/" >> $queue_file || return 2 put_queue || return $? } # Remove a package from the queue remove_queue() { get_queue || return $? grep -vw "^$(basename $PWD)" $queue_file > $queue_file.2 cat $queue_file.2 > $queue_file put_queue && rm $queue_file{,.2} && return 0 || return $? } # Checks if a package is listed check_queue() { get_queue || return $? packager=$(grep -w "$(basename $PWD)" ${queue_file} | cut -d ':' -f2) [[ ! -z $packager ]] && [[ "$packager" != "$PACKAGER" ]] && { warning "$(basename $PWD) is being packaged by $packager. Please wait." return 1 } return 0 } # END Queue Management # # Checks if the package is banned from building is_banned() { rsync -e ssh -aq $PARABOLAHOST:mips64el/ban $ban_file >/dev/null 2>&1 || { plain "Failed to get ban list" return 1 } grep -w $1 $ban_file >/dev/null 2>&1 return $? } guess_repo() { basename $(dirname $(pwd)) } # usage : in_array( $needle, $haystack ) # return : 0 - found # 1 - not found function in_array { [[ $2 ]] || return 1 local needle=$1; shift local item for item in "$@"; do [[ ${item#@} = $needle ]] && return 0 done return 1 # Not Found } function quit { remove_queue exit 1 } function cleanup { rm $ban_file $queue_file rm -rf $tmp_dir } # TODO keep track of spawned fullpkgs ## END FUNCTIONS ## source PKGBUILD repo=${repo:-$(guess_repo)} msg "Building ${repo:-missing repo}/${pkgbase:-${pkgname[@]}}: $pkgdesc" # Pre build tests if [ $force_build == 'n' ]; then # Be able to write files if [[ ! -w $queue_file ]]; then error "can't write queue file" exit 1 elif [[ ! -w $ban_file ]] ; then error "can't write ban file" exit 1 fi if is_built "${pkgbase:-${pkgname[0]}}>=${pkgver}-${pkgrel}"; then msg2 "This package is built." exit 0 fi if is_banned ${pkgbase:-$pkgname}; then error "This package is banned from building. Check the ban list" exit 1 fi check_queue || exit 1 fi # This will be executed at exit for any reason. trap "quit" EXIT INT QUIT TERM KILL HUP if ! grep mips64el PKGBUILD >/dev/null; then msg "Adding mips64el arch" sed -i "s/^\(arch=([^)anym]\+\))/\1 'mips64el')/" "PKGBUILD" fi # Clean version checking deps=$(echo "${depends[@]} ${makedepends[@]} ${pkgdeps[@]}" | \ sed "s/[=<>]\+[^ ]\+//g" | \ tr ' ' "\n" | \ sort -u) msg "Checking dependencies" for _dep in ${deps[@]}; do is_banned $_dep && continue for _repo in ${REPOS[@]}; do # TODO find split packages [[ -e "$ABSROOT/${_repo}/$_dep/PKGBUILD" ]] && { source "$ABSROOT/${_repo}/$_dep/PKGBUILD" msg2 "Checking for $_dep>=$pkgver-$pkgrel" if ! in_array $_dep ${force_array[@]}; then if is_built "$_dep>=$pkgver-$pkgrel"; then plain "this package is built" break fi else _fullpkgargs+="-f " _fullpkgargs="$(echo $_fullpkgargs | sed s/"-R $_dep "//)" force_array=( $(echo ${forcearray[@]} | tr " " "\n" | grep -vw "^$_dep") ) fi cp -r "$ABSROOT/$_repo/$_dep" $tmp_dir/ || { error "Can't copy $_dep to the work dir." exit 1 } # Enter the work dir and run this command in it pushd $tmp_dir/$_dep >/dev/null $0 -r $_repo $_fullpkgargs [[ $? -ne 0 ]] && { failed=(${failed[@]} $_dep) } popd >/dev/null } done done # TODO probably not elegant enough # TODO only the last fullpkg should show this message # and it should contain all failed pkgs [[ ${#failed[@]} -gt 0 ]] && { error "This packages failed to build: ${failed[@]}" exit 1 } # Let everybody know we're building this update_queue || { warning "Couldn't update the queue, let your partners know about this." } cp -r ../$(basename $PWD) $tmp_dir/ pushd $tmp_dir/$(basename $PWD) >/dev/null msg "Syncing database" sudo pacman -Syu --noconfirm makepkg --noconfirm --nocheck -sLcr ; r=$? case $r in 0) msg "The build was succesful." mipsrelease *.pkg.tar.* librestage $repo sudo pacman -Sy # cleanup is only on succesfull build so failed can be inspected cleanup;; 1) error "There were errors while trying to build the package." ;; 2) error "The build failed." ;; esac exit $r