diff options
-rwxr-xr-x | dagpkg | 92 |
1 files changed, 68 insertions, 24 deletions
@@ -1,18 +1,38 @@ #!/usr/bin/env bash +# +# dagpkg - create a directed graph of package dependencies and build +# them in topological order +# +# (c) 2014 Nicolás Reynolds <fauno@parabola.nu> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. set -e -# Source variables from makepkg -source /etc/makepkg.conf -source $XDG_CONFIG_HOME/.makepkg.conf &>/dev/null || true - # Source variables from libretools source /etc/libretools.conf source $XDG_CONFIG_HOME/libretools/libretools.conf &>/dev/null || true +# Source variables from makepkg +source /etc/makepkg.conf +source $XDG_CONFIG_HOME/.makepkg.conf &>/dev/null || true + # End inmediately but print an useful message trap_exit() { term_title "error!" - error "($(basename $0)) $@ (leftovers on ${temp_dir})" + test ${depth} -eq 0 && + error "(%s) %s (leftovers on %s)" \ + "${0##*/}" "$@" "${temp_dir}" exit 1 } @@ -27,6 +47,16 @@ if ! source PKGBUILD &>/dev/null ; then exit 1 fi +# Save resources +unset pkgdesc arch license groups backup install md5sums sha1sums \ + sha256sums source options &>/dev/null + +unset build package &>/dev/null + +for _pkg in ${pkgname[@]}; do + unset package_${_pkg} &>/dev/null || true +done + # This is the name of the package name="${pkgbase:-${pkgname[0]}}" @@ -54,50 +84,59 @@ get_fullver() { is_built ${pkgname[0]} $(get_fullver ${epoch:-0} ${pkgver} ${pkgrel}) && exit +echo "${arch[@]}" | grep -qw "$CARCH" || warning "%s isn't ported to %s yet" ${name} ${CARCH} + # If the envvar I contains this package, ignore it and exit -echo "$I" | grep -q "$name" && exit +echo "$I" | grep -qw "$name" && +msg2 "%s ignored" ${name} && +exit -msg "%s(%d)" $name $depth +msg "%s (%s)" ${name} ${prev} build=false if [ ! -z "${1}" -a ${depth} -eq 0 ]; then build=true fi - # If we specified a work dir on the cli it means we want to skip - # dependency graph creation and jump to build whatever is there - if ! ${build}; then +# If we specified a work dir on the cli it means we want to skip +# dependency graph creation and jump to build whatever is there +if ! ${build}; then # Export a pair of current and previous package to get a list of graph # edges - echo -e "${name}\t${prev:--}" | tee -a ${log} + echo -e "${name}\t${prev:--}" >>${log} + + # Infinite loop detection, if the inverted pair current+prev was + # already seen, skip + if grep -q "${prev}[[:space:]]${name}" ${log} ; then + msg2 "infinite loop %s<->%s" $name $prev + exit + fi # Recurse into dependencies for d in ${depends[@]} ${makedepends[@]}; do # Cleanup dependency versions d=$(echo $d | sed "s/[<>=].*//") + # Where's the pkgbuild? w=$(toru-where $d) # Skip if not available test -z "$w" && continue - # Go to this dir - pushd $w &>/dev/null - - # Infinite loop detection, if the inverted pair current+prev was - # already seen, skip - if grep -q "${prev}[[:space:]]${d}" ${log} ; then - msg2 "infinite loop %s<->%s" $d $prev - continue - fi - - # Edge detection - if grep -q "^${d}[[:space:]]" ${log} ; then + # revisited edge detection + # we use the basename of the package dir as pkgbase to avoid + # recalling an edge using one of the other pkgname's + if grep -q "^${w##*/}[[:space:]]" ${log} ; then msg2 "edge %s already visited" ${d} + # add edge anyway but avoid reprocessing + echo -e "${w##*/}\t${name}" >>${log} continue fi + # Go to this dir + pushd $w &>/dev/null + # Run this same command giving work dir, depth and previous package $0 ${temp_dir} ${next} ${name} @@ -110,9 +149,9 @@ fi # end here if we're not the first package test ${depth} -ne 0 && exit - # enter work dir pushd "${temp_dir}" &>/dev/null +# TODO do something when loops are discovered (fail? skip?) tsort ${log} | head -n-1 | tac | nl | tac | while read order pkg; do # skip if already built test -f "${pkg}/built_ok" && continue @@ -122,6 +161,9 @@ tsort ${log} | head -n-1 | tac | nl | tac | while read order pkg; do test -z "$w" && continue # copy to work dir if not already + # this means you can make modifications to the pkgbuild during the + # graph build or remove the dir after a build failure and let dagpkg + # copy a new version test -d "$pkg" || cp -r "$w" "$pkg" pushd "$pkg" &>/dev/null @@ -130,6 +172,8 @@ tsort ${log} | head -n-1 | tac | nl | tac | while read order pkg; do msg "Building %s" ${pkg} # upgrade the system + # this would probably have to go on HOOKPREBUILD if you're working + # outside chroots sudo -E pacman -Syu --noconfirm # run the pre build command from libretools.conf |