diff options
Diffstat (limited to 'fullpkg-ng')
-rwxr-xr-x | fullpkg-ng | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/fullpkg-ng b/fullpkg-ng new file mode 100755 index 0000000..4159320 --- /dev/null +++ b/fullpkg-ng @@ -0,0 +1,312 @@ +#!/bin/bash +# TO TEST: (on find_deps) +# * Detect pkgnames by provides, replaces, etc. instead of dir tree + +eval "$(egrep "PACKAGER=|CARCH=" /etc/makepkg.conf)" +eval "$(egrep "ABSROOT=" /etc/abs.conf)" +eval "$(egrep "REPOS=|FULLBUILDCMD=" /etc/libretools.conf)" +source /usr/bin/libremessages + +[ -r $XDG_CONFIG_HOME/libretools/libretools.conf ] && \ + source $XDG_CONFIG_HOME/libretools/libretools.conf + +## START FUNCTIONS ## + +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 " -a absdir : set absdir as ABSROOT." + echo " -c : check deps only, do not build." + echo " -d build_dir : use this dir to build. Defaults to mktemp." + echo " -n : don't update pacman db." + echo " -m max_level : check deps until this level" + # printf " -f pkgname : build even when a package has been built. " + # printf " Use it as many times as needed\n" + echo +} + +# Queue Management +# * Always get the queue list from the server +# * Add/Remove from queue +# * Check if a package is listed + +# TODO +# * Check for concurrence # @ fauno: What do you mean? + +# 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 $? + echo "$(basename $PWD):$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 + mv $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 $? + + local 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 # + +guess_repo() { + basename $(dirname $(pwd)) +} + +# Usage: cleanup [ $(basename $PWD) ] from PKGBUILD dir +# cleans the build_dir +function cleanup { + if [ ! -d $build_dir ]; then + return 1 + elif [ -d $build_dir -a ${#@} -gt 0 ]; then + for _dir in $@; do + rm -rf $build_dir/$_dir/ + done + fi +} + +# Check PKGBUILD and find non built or outdated deps +# on ABSROOT which should be abslibre-misp64el +function find_deps { + ## Check this level. + source PKGBUILD + local repo=${repo:-$(guess_repo)} + + # If package is built exit + # TODO?: If this package is in force_build: skip this step + if is_built "${pkgbase:-${pkgname[0]}}>=${pkgver}-${pkgrel}"; then + exit 0 + fi + + # Tell which packages are deeper in deps (even if they are on build_dir) + # so we can build them first. + echo "${level}:$(basename $PWD)" >> "${build_dir}/BUILDORDER" + + # if pkgbuild directory is on build_dir, do not copy and exit + if [ -d "${build_dir}/$(basename $PWD)" ]; then + exit 0 + else + cp -r ../$(basename $PWD) ${build_dir}/ + # Info to eval later + echo "repo=$repo" > "${build_dir}/$(basename $PWD)/.INFO" + fi + + msg2 "${pkgbase:-${pkgname[0]}}>=${pkgver}-${pkgrel}" + + ## Check next levels + # Clean version checking + deps=$(echo "${depends[@]} ${makedepends[@]}" | \ + sed "s/[=<>]\+[^ ]\+//g" | \ + tr ' ' "\n" | \ + sort -u) + declare -i next_level=$level+1 + + for _dep in ${deps[@]}; do + for _repo in ${REPOS[@]}; do + # try to find $_dep on each repo from dirname + [ -e "$ABSROOT/${_repo}/$_dep/PKGBUILD" ] && { + pushd "$ABSROOT/${_repo}/$_dep" > /dev/null + $0 -c -d ${build_dir} -l ${next_level} + # Circular deps must fail + [ $? -eq 20 ] && return 20 + popd > /dev/null + } && break 1 # found, go to next dep + + # search pkgname in repo if that doesn't work + # this should find pkgsplits + _dir=$(find "$ABSROOT/${_repo}" -type f -name PKGBUILD -print0 | \ + "xargs" -0 -e grep -H -Ew grep $_dep > /dev/null ) && { + pushd $(dirname $(echo $_dir | cut -d: -f1)) > /dev/null + $0 -c -d ${build_dir} -l ${next_level} + # Circular deps must fail + [ $? -eq 20 ] && return 20 + popd > /dev/null + } && break 1 # found, go to next dep + done + done + unset next_level dir + # unset PKGBUILD variables + unset pkgname pkgver pkgrel epoch pkgdesc arch url license groups depends \ + makedepens checkdepends optdepends provides conflicts replaces backup \ + options install changelog source noextract md5sums build check package +} + +## END FUNCTIONS ## + +force_build="" +level=0 +noupdate='n' +check_deps_only='n' +max_level=21 +while getopts 'ha:cd:l:nm:' arg; do + case $arg in + h) usage; exit 0 ;; + a) ABSROOT="$OPTARG" ;; + c) check_deps_only='y' ;; + # f) force_build+="-f pkgname " ;; + d) build_dir="$OPTARG" ;; + # hidden option to know what to build first. + # if $level > 0 it will not build + l) level=$OPTARG ;; + n) noupdate='y';; + m) max_level=$OPTARG ;; + esac +done + +# Only on level 0 +[ $level -eq 0 ] && { + # if build_dir exist use it, else make a build_dir + build_dir=${build_dir:-$(mktemp -d /tmp/fullpkg.XXXXXX)} + + # set queue_file and ban_file + mkdir -p $XDG_CONFIG_HOME/libretools + queue_file=$XDG_CONFIG_HOME/libretools/queue + ban_file=$XDG_CONFIG_HOME/libretools/ban + touch $build_dir/{deps,log,BUILDORDER} $queue_file $ban_file + + [ $noupdate = 'n' ] && { + msg "Updating pacman db and packages" + sudo pacman -Syu --noconfirm + } + msg "Checking dependencies" +} +buildorder=$build_dir/BUILDORDER + +[ ! -r PKGBUILD ] && { + error "This isn't a build directory" + usage && exit 1 +} + +## if $level = 20 there is highly likely there are circular deps +[ $level -eq $max_level -o $level -gt $max_level ] && exit 20 + +find_deps || { + # if find_deps finds circular deps + # it should exit with status 20 + [ $? -eq 20 ] && { + # only show message on level 0 + [ $level -eq 0 ] && error "Check for circular deps on $build_dir/BUILDORDER"; + } + exit 20 +} + +# levels greater than 0 must only check deps +[ $check_deps_only = 'y' -o $level -gt 0 ] && exit 0 + +# check BUILDORDER to not include banned deps and +[ $level -eq 0 -a -d $build_dir ] && { + # Check for banned deps + if [ -w $ban_file -a -r $ban_file ]; then + chmod o+rw $ban_file || error "Ban file is not readable/writable ($ban_file)" + else + rsync -e ssh -aq $PARABOLAHOST:mips64el/ban >/dev/null 2>&1 || { + warning "Failed to get ban list" && [ -r $ban_file ] && { + # continue if download failed but local copy + search=$(cat $ban_file | tr "\n" "|") + echo ${@} | tr " " "\n" | egrep -w "$search" $buildorder >> $build_dir/banned + echo ${@} | tr " " "\n" | egrep -vw "$search" $buildorder > $buildorder.2 + mv $buildorder.2 $buildorder + unset search + } + } + fi +} + +## START Building + +msg "Building packages:" +cd ${build_dir} > /dev/null + +[ ! -w $queue_file ] && error "can't write queue file" + +# Exit loop on Ctrl+C +trap "break" INT +# Remove from queue package being built on error +trap "remove_queue" EXIT INT QUIT TERM KILL +build_packages=$(sort -gr $buildorder | cut -d: -f2) +while [ ${#build_packages[@]} -gt 0 ]; do + build_packages=$(sort -gr $buildorder | cut -d: -f2) + pushd $build_dir/${build_packages[0]} > /dev/null + source PKGBUILD + msg2 "${pkgbase:-${pkgname[0]}} $pkgver-$pkgrel" + if ! grep mips64el PKGBUILD >/dev/null; then + plain "Adding mips64el arch" + sed -i "s/^\(arch=([^)anym]\+\))/\1 'mips64el')/" "PKGBUILD" + fi + # Check if pkg is being built, if it's not let everybody know we're building this. + check_queue && update_queue || { + warning "Couldn't update the queue, let your partners know about this." + } + $FULLBUILDCMD; r=$? + case $r in + 0) plain "The build was succesful." + source .INFO && [ -n $repo ] && librestage $repo || \ + echo "unstaged:$(basename $PWD)" >> $build_dir/log + echo "built:$(basename $PWD)" >> $build_dir/log + cleanup "$(basename $PWD)" + ;; + 1) error "There were errors while trying to build the package." + echo "failed: $(basename $PWD)" >> $build_dir/log ;; + 2) error "The build failed." + echo "failed: $(basename $PWD)" >> $build_dir/log ;; + esac + egrep -vw ${build_packages[0]} $buildorder > $buildorder.2 + mv $buildorder.2 $buildorder + unset build_packages + popd > /dev/null +done + +pkgs=$(cat $build_dir/log | grep "built:") && { + error "Those packages were built and installed:" + plain "$(echo ${pkgs[@]} | cut -d: -f2)" + msg "Uploading packages to the server" + librerelease +} +pkgs=$(cat $build_dir/log | grep "failed:") && { + error "Those packages failed to build:" + plain "$(echo ${pkgs[@]} | cut -d: -f2)" +} +pkgs=$(cat $build_dir/log | grep "unstaged:") && { + error "Those packages couldn't be staged because of missing reponame:" + plain "$(cat $build_dir/log | grep "unstaged:" | cut -d: -f2)" +} + +exit 0
\ No newline at end of file |