summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xdagpkg92
1 files changed, 68 insertions, 24 deletions
diff --git a/dagpkg b/dagpkg
index d3fb723..578203e 100755
--- a/dagpkg
+++ b/dagpkg
@@ -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