diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/.gitignore | 1 | ||||
-rw-r--r-- | scripts/Makefile.am | 5 | ||||
-rw-r--r-- | scripts/makepkg.sh.in | 433 | ||||
-rw-r--r-- | scripts/pacman-db-upgrade.sh.in | 121 | ||||
-rw-r--r-- | scripts/pacman-optimize.sh.in | 8 | ||||
-rw-r--r-- | scripts/pkgdelta.sh.in | 2 | ||||
-rw-r--r-- | scripts/rankmirrors.sh.in | 6 | ||||
-rw-r--r-- | scripts/repo-add.sh.in | 44 |
8 files changed, 395 insertions, 225 deletions
diff --git a/scripts/.gitignore b/scripts/.gitignore index eafc4930..fe4616f2 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -1,4 +1,5 @@ makepkg +pacman-db-upgrade pacman-optimize rankmirrors repo-add diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 0fde3345..2962b915 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -7,6 +7,7 @@ bin_SCRIPTS = \ OURSCRIPTS = \ makepkg \ + pacman-db-upgrade \ pacman-optimize \ pkgdelta \ rankmirrors \ @@ -14,6 +15,7 @@ OURSCRIPTS = \ EXTRA_DIST = \ makepkg.sh.in \ + pacman-db-upgrade.sh.in \ pacman-optimize.sh.in \ pkgdelta.sh.in \ rankmirrors.sh.in \ @@ -35,10 +37,10 @@ edit = sed \ -e 's|@sysconfdir[@]|$(sysconfdir)|g' \ -e 's|@localstatedir[@]|$(localstatedir)|g' \ -e 's|@prefix[@]|$(prefix)|g' \ + -e 's|@BASH_SHELL[@]|$(BASH_SHELL)|g' \ -e 's|@PACKAGE_VERSION[@]|$(REAL_PACKAGE_VERSION)|g' \ -e 's|@PACKAGE_BUGREPORT[@]|$(PACKAGE_BUGREPORT)|g' \ -e 's|@PACKAGE_NAME[@]|$(PACKAGE_NAME)|g' \ - -e 's|@DBEXT[@]|$(DBEXT)|g' \ -e 's|@BUILDSCRIPT[@]|$(BUILDSCRIPT)|g' \ -e 's|@SIZECMD[@]|$(SIZECMD)|g' \ -e 's|@SEDINPLACE[@]|$(SEDINPLACE)|g' \ @@ -61,6 +63,7 @@ $(OURSCRIPTS): Makefile @mv $@.tmp $@ makepkg: $(srcdir)/makepkg.sh.in +pacman-db-upgrade: $(srcdir)/pacman-db-upgrade.sh.in pacman-optimize: $(srcdir)/pacman-optimize.sh.in pkgdelta: $(srcdir)/pkgdelta.sh.in rankmirrors: $(srcdir)/rankmirrors.sh.in diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index ec664692..ac10ad3a 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -1,4 +1,4 @@ -#!/bin/bash -e +#!@BASH_SHELL@ -e # # makepkg - make packages compatible for use with pacman # @configure_input@ @@ -27,7 +27,7 @@ # makepkg uses quite a few external programs during its execution. You # need to have at least the following installed for makepkg to function: -# bsdtar (libarchive), bzip2, coreutils, fakeroot, file, find (findutils), +# awk, bsdtar (libarchive), bzip2, coreutils, fakeroot, file, find (findutils), # gettext, grep, gzip, openssl, sed, tput (ncurses), xz # gettext initialization @@ -45,7 +45,7 @@ srcdir="$startdir/src" pkgdir="$startdir/pkg" packaging_options=('strip' 'docs' 'libtool' 'emptydirs' 'zipman' 'purge') -other_options=('ccache' 'distcc' 'makeflags' 'force') +other_options=('ccache' 'distcc' 'makeflags') splitpkg_overrides=('pkgver' 'pkgrel' 'pkgdesc' 'arch' 'license' 'groups' \ 'depends' 'optdepends' 'provides' 'conflicts' 'replaces' \ 'backup' 'options' 'install' 'changelog') @@ -135,6 +135,8 @@ clean_up() { fi if (( ! EXIT_CODE && CLEANUP )); then + local pkg file + # If it's a clean exit and -c/--clean has been passed... msg "$(gettext "Cleaning up...")" rm -rf "$pkgdir" "$srcdir" @@ -153,7 +155,7 @@ clean_up() { # clean up dangling symlinks to packages for pkg in ${pkgname[@]}; do - for file in ${pkg}-*-*-${CARCH}${PKGEXT}; do + for file in ${pkg}-*-*-${CARCH}{${PKGEXT},${SRCEXT}}; do if [[ -h $file && ! -e $file ]]; then rm -f $file fi @@ -308,7 +310,7 @@ get_downloadclient() { for i in "${DLAGENTS[@]}"; do local handler="${i%%::*}" if [[ $proto = $handler ]]; then - agent="${i##*::}" + local agent="${i##*::}" break fi done @@ -323,7 +325,7 @@ get_downloadclient() { # ensure specified program is installed local program="${agent%% *}" if [[ ! -x $program ]]; then - local baseprog=$(basename $program) + local baseprog="${program##*/}" error "$(gettext "The download program %s is not installed.")" "$baseprog" plain "$(gettext "Aborting...")" exit 1 # $E_MISSING_PROGRAM @@ -370,7 +372,7 @@ download_file() { run_pacman() { local cmd printf -v cmd "%q " "$PACMAN" $PACMAN_OPTS "$@" - if (( ! ASROOT )) && [[ $1 != "-T" && $1 != "-Qq" ]]; then + if (( ! ASROOT )) && [[ ! $1 =~ ^-(T|Qq)$ ]]; then if [ "$(type -p sudo)" ]; then cmd="sudo $cmd" else @@ -387,6 +389,7 @@ check_deps() { # Also, a non-zero return value is not unexpected and we are manually dealing them set +E local ret=0 + local pmout pmout=$(run_pacman -T "$@") || ret=$? set -E @@ -394,7 +397,7 @@ check_deps() { echo "$pmout" elif (( ret )); then error "$(gettext "'%s' returned a fatal error (%i): %s")" "$PACMAN" "$ret" "$pmout" - exit 1 + return "$ret" fi } @@ -434,17 +437,16 @@ resolve_deps() { local R_DEPS_SATISFIED=0 local R_DEPS_MISSING=1 - local deplist="$(check_deps $*)" - if [[ -z $deplist ]]; then - return $R_DEPS_SATISFIED - fi + # deplist cannot be declared like this: local deplist=$(foo) + # Otherwise, the return value will depend on the assignment. + local deplist + deplist="$(set +E; check_deps $*)" || exit 1 + [[ -z $deplist ]] && return $R_DEPS_SATISFIED if handle_deps $deplist; then # check deps again to make sure they were resolved - deplist="$(check_deps $*)" + deplist="$(set +E; check_deps $*)" || exit 1 [[ -z $deplist ]] && return $R_DEPS_SATISFIED - elif (( DEP_BIN )); then - error "$(gettext "Failed to install all missing dependencies.")" fi msg "$(gettext "Missing Dependencies:")" @@ -543,7 +545,7 @@ generate_checksums() { msg "$(gettext "Generating checksums for source files...")" plain "" - if [ ! $(type -p openssl) ]; then + if ! type -p openssl >/dev/null; then error "$(gettext "Cannot find openssl.")" exit 1 # $E_MISSING_PROGRAM fi @@ -593,7 +595,7 @@ generate_checksums() { check_checksums() { (( ! ${#source[@]} )) && return 0 - if [ ! $(type -p openssl) ]; then + if ! type -p openssl >/dev/null; then error "$(gettext "Cannot find openssl.")" exit 1 # $E_MISSING_PROGRAM fi @@ -654,7 +656,7 @@ extract_sources() { msg "$(gettext "Extracting Sources...")" local netfile for netfile in "${source[@]}"; do - file=$(get_filename "$netfile") + local file=$(get_filename "$netfile") if in_array "$file" ${noextract[@]}; then #skip source files in the noextract=() array # these are marked explicitly to NOT be extracted @@ -685,9 +687,12 @@ extract_sources() { *) continue;; esac ;; *) - # Don't know what to use to extract this file, - # skip to the next file - continue;; + # See if bsdtar can recognize the file + if bsdtar -tf "$file" -q '*' &>/dev/null; then + cmd="bsdtar" + else + continue + fi ;; esac local ret=0 @@ -717,6 +722,7 @@ error_function() { fi # first exit all subshells, then print the error if (( ! BASH_SUBSHELL )); then + error "$(gettext "A failure occurred in %s().")" "$1" plain "$(gettext "Aborting...")" remove_deps fi @@ -727,7 +733,7 @@ run_function() { if [[ -z $1 ]]; then return 1 fi - pkgfunc="$1" + local pkgfunc="$1" # clear user-specified makeflags if requested if [[ $(check_option makeflags) = "n" ]]; then @@ -743,8 +749,9 @@ run_function() { local shellopts=$(shopt -p) local ret=0 + local restoretrap if (( LOGGING )); then - BUILDLOG="${startdir}/${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-$pkgfunc.log" + local BUILDLOG="${startdir}/${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-$pkgfunc.log" if [[ -f $BUILDLOG ]]; then local i=1 while true; do @@ -759,12 +766,12 @@ run_function() { # ensure overridden package variables survive tee with split packages logpipe=$(mktemp -u "$startdir/logpipe.XXXXXXXX") - mknod "$logpipe" p + mkfifo "$logpipe" exec 3>&1 tee "$BUILDLOG" < "$logpipe" & exec 1>"$logpipe" 2>"$logpipe" restoretrap=$(trap -p ERR) - trap 'error_function' ERR + trap 'error_function $pkgfunc' ERR $pkgfunc 2>&1 eval $restoretrap sync @@ -772,7 +779,7 @@ run_function() { rm "$logpipe" else restoretrap=$(trap -p ERR) - trap 'error_function' ERR + trap 'error_function $pkgfunc' ERR $pkgfunc 2>&1 eval $restoretrap fi @@ -799,6 +806,7 @@ run_build() { } run_package() { + local pkgfunc if [[ -z $1 ]]; then pkgfunc="package" else @@ -865,13 +873,13 @@ tidy_install() { done fi - if [[ $(check_option strip) = y && -n ${STRIP_DIRS[*]} ]]; then + if [[ $(check_option strip) = y ]]; then msg2 "$(gettext "Stripping unneeded symbols from binaries and libraries...")" # make sure library stripping variables are defined to prevent excess stripping [[ -z ${STRIP_SHARED+x} ]] && STRIP_SHARED="-S" [[ -z ${STRIP_STATIC+x} ]] && STRIP_STATIC="-S" local binary - find ${STRIP_DIRS[@]} -type f -perm -u+w 2>/dev/null | while read binary ; do + find . -type f -perm -u+w 2>/dev/null | while read binary ; do case "$(file -bi "$binary")" in *application/x-sharedlib*) # Libraries (.so) /usr/bin/strip $STRIP_SHARED "$binary";; @@ -905,56 +913,39 @@ write_pkginfo() { size="$(( ${size%%[^0-9]*} * 1024 ))" msg2 "$(gettext "Generating .PKGINFO file...")" - echo "# Generated by makepkg $myver" >.PKGINFO + echo "# Generated by makepkg $myver" if (( INFAKEROOT )); then - echo "# using $(fakeroot -v)" >>.PKGINFO - fi - echo "# $(LC_ALL=C date -u)" >>.PKGINFO - echo "pkgname = $1" >>.PKGINFO - (( SPLITPKG )) && echo pkgbase = $pkgbase >>.PKGINFO - echo "pkgver = $pkgver-$pkgrel" >>.PKGINFO - echo "pkgdesc = $pkgdesc" >>.PKGINFO - echo "url = $url" >>.PKGINFO - echo "builddate = $builddate" >>.PKGINFO - echo "packager = $packager" >>.PKGINFO - echo "size = $size" >>.PKGINFO - echo "arch = $PKGARCH" >>.PKGINFO - if [[ $(check_option force) = "y" ]]; then - echo "force = true" >> .PKGINFO - fi + echo "# using $(fakeroot -v)" + fi + echo "# $(LC_ALL=C date -u)" + echo "pkgname = $1" + (( SPLITPKG )) && echo pkgbase = $pkgbase + echo "pkgver = $pkgver-$pkgrel" + echo "pkgdesc = $pkgdesc" + [[ $epoch ]] && echo "epoch = $epoch" + echo "url = $url" + echo "builddate = $builddate" + echo "packager = $packager" + echo "size = $size" + echo "arch = $PKGARCH" + + [[ $license ]] && printf "license = %s\n" "${license[@]}" + [[ $replaces ]] && printf "replaces = %s\n" "${replaces[@]}" + [[ $groups ]] && printf "group = %s\n" "${groups[@]}" + [[ $depends ]] && printf "depend = %s\n" "${depends[@]}" + [[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]}" + [[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}" + [[ $provides ]] && printf "provides = %s\n" "${provides[@]}" + [[ $backup ]] && printf "backup = %s\n" "${backup[@]}" local it - for it in "${license[@]}"; do - echo "license = $it" >>.PKGINFO - done - for it in "${replaces[@]}"; do - echo "replaces = $it" >>.PKGINFO - done - for it in "${groups[@]}"; do - echo "group = $it" >>.PKGINFO - done - for it in "${depends[@]}"; do - echo "depend = $it" >>.PKGINFO - done - for it in "${optdepends[@]}"; do - echo "optdepend = $it" >>.PKGINFO - done - for it in "${conflicts[@]}"; do - echo "conflict = $it" >>.PKGINFO - done - for it in "${provides[@]}"; do - echo "provides = $it" >>.PKGINFO - done - for it in "${backup[@]}"; do - echo "backup = $it" >>.PKGINFO - done for it in "${packaging_options[@]}"; do local ret="$(check_option $it)" if [[ $ret != "?" ]]; then if [[ $ret = y ]]; then - echo "makepkgopt = $it" >>.PKGINFO + echo "makepkgopt = $it" else - echo "makepkgopt = !$it" >>.PKGINFO + echo "makepkgopt = !$it" fi fi done @@ -974,14 +965,18 @@ check_package() { local file for file in "${backup[@]}"; do if [[ ! -f $file ]]; then - warning "$(gettext "Invalid backup entry : %s")" "$file" + warning "$(gettext "Backup entry file not in package : %s")" "$file" fi done - # check for references to the build directory - if find "${pkgdir}" -type f -exec grep -q "${srcdir}" {} +; then + # check for references to the build and package directory + if find "${pkgdir}" -type f -exec grep -q -I "${srcdir}" {} +; then warning "$(gettext "Package contains reference to %s")" "\$srcdir" fi + if find "${pkgdir}" -type f -exec grep -q -I "${pkgdir}" {} +; then + warning "$(gettext "Package contains reference to %s")" "\$pkgdir" + fi + } create_package() { @@ -996,6 +991,7 @@ create_package() { cd "$pkgdir" msg "$(gettext "Creating package...")" + local nameofpkg if [[ -z $1 ]]; then nameofpkg="$pkgname" else @@ -1008,62 +1004,61 @@ create_package() { PKGARCH=$CARCH fi - write_pkginfo $nameofpkg + write_pkginfo $nameofpkg > .PKGINFO local comp_files=".PKGINFO" - # check for an install script - if [[ -n $install ]]; then - msg2 "$(gettext "Adding install script...")" - cp "$startdir/$install" .INSTALL - chmod 644 .INSTALL - comp_files="$comp_files .INSTALL" - fi - - # do we have a changelog? - if [[ -n $changelog ]]; then - msg2 "$(gettext "Adding package changelog...")" - cp "$startdir/$changelog" .CHANGELOG - chmod 644 .CHANGELOG - comp_files="$comp_files .CHANGELOG" - fi + # check for changelog/install files + for i in 'changelog' 'install'; do + orig=${!i} + dest=$(tr '[:lower:]' '[:upper:]' <<<".$i") + + if [[ -n $orig ]]; then + msg2 "$(gettext "Adding %s file...")" "$i" + cp "$startdir/$orig" "$dest" + chmod 644 "$dest" + comp_files+=" $dest" + fi + done # tar it up msg2 "$(gettext "Compressing package...")" + local EXT case "$PKGEXT" in *tar.gz) EXT=${PKGEXT%.gz} ;; *tar.bz2) EXT=${PKGEXT%.bz2} ;; *tar.xz) EXT=${PKGEXT%.xz} ;; + *tar) EXT=${PKGEXT} ;; *) warning "$(gettext "'%s' is not a valid archive extension.")" \ "$PKGEXT" ; EXT=$PKGEXT ;; esac - local tar_file="$PKGDEST/${nameofpkg}-${pkgver}-${pkgrel}-${PKGARCH}${EXT}" - local pkg_file="$PKGDEST/${nameofpkg}-${pkgver}-${pkgrel}-${PKGARCH}${PKGEXT}" + local pkg_file="$PKGDEST/${nameofpkg}-${pkgver}-${pkgrel}-${PKGARCH}${PKGEXT}" local ret=0 # when fileglobbing, we want * in an empty directory to expand to # the null string rather than itself shopt -s nullglob - bsdtar -cf - $comp_files * > "$tar_file" || ret=$? - shopt -u nullglob + # TODO: Maybe this can be set globally for robustness + shopt -s -o pipefail + bsdtar -cf - $comp_files * | + case "$PKGEXT" in + *tar.gz) gzip -c -f -n ;; + *tar.bz2) bzip2 -c -f ;; + *tar.xz) xz -c -z - ;; + *tar) cat ;; + esac > ${pkg_file} || ret=$? - if (( ! ret )); then - case "$PKGEXT" in - *tar.gz) gzip -f -n "$tar_file" ;; - *tar.bz2) bzip2 -f "$tar_file" ;; - *tar.xz) xz -z -f "$tar_file" ;; - esac - ret=$? - fi + shopt -u nullglob + shopt -u -o pipefail if (( ret )); then error "$(gettext "Failed to create package file.")" exit 1 # TODO: error code fi - if (( ! ret )) && [[ "$PKGDEST" != "${startdir}" ]]; then + if (( ! ret )) && [[ ! "$PKGDEST" -ef "${startdir}" ]]; then ln -sf "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}" ret=$? fi @@ -1129,6 +1124,7 @@ create_srcpackage() { *tar.gz) TAR_OPT="z" ;; *tar.bz2) TAR_OPT="j" ;; *tar.xz) TAR_OPT="J" ;; + *tar) TAR_OPT="" ;; *) warning "$(gettext "'%s' is not a valid archive extension.")" \ "$SRCEXT" ;; esac @@ -1142,6 +1138,16 @@ create_srcpackage() { error "$(gettext "Failed to create source package file.")" exit 1 # TODO: error code fi + + if (( ! ret )) && [[ ! "$SRCPKGDEST" -ef "${startdir}" ]]; then + ln -sf "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}" + ret=$? + fi + + if (( ret )); then + warning "$(gettext "Failed to create symlink to source package file.")" + fi + cd "${startdir}" rm -rf "${srclinks}" } @@ -1155,12 +1161,12 @@ install_package() { msg "$(gettext "Installing %s package group with %s -U...")" "$pkgbase" "$PACMAN" fi - local pkglist + local pkg pkglist for pkg in ${pkgname[@]}; do if [[ -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} ]]; then - pkglist="${pkglist} $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}" + pkglist+=" $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}" else - pkglist="${pkglist} $PKGDEST/${pkg}-${pkgver}-${pkgrel}-any${PKGEXT}" + pkglist+=" $PKGDEST/${pkg}-${pkgver}-${pkgrel}-any${PKGEXT}" fi done @@ -1172,22 +1178,16 @@ install_package() { check_sanity() { # check for no-no's in the build script - if [[ -z $pkgname ]]; then - error "$(gettext "%s is not allowed to be empty.")" "pkgname" - return 1 - fi - if [[ -z $pkgver ]]; then - error "$(gettext "%s is not allowed to be empty.")" "pkgver" - return 1 - fi - if [[ -z $pkgrel ]]; then - error "$(gettext "%s is not allowed to be empty.")" "pkgrel" - return 1 - fi + local i + for i in 'pkgname' 'pkgrel' 'pkgver'; do + if [[ -z ${!i} ]]; then + error "$(gettext "%s is not allowed to be empty.")" "$i" + return 1 + fi + done - local name - for name in "${pkgname[@]}"; do - if [[ ${name:0:1} = "-" ]]; then + for i in "${pkgname[@]}"; do + if [[ ${i:0:1} = "-" ]]; then error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname" return 1 fi @@ -1206,6 +1206,11 @@ check_sanity() { return 1 fi + if [[ ! $epoch =~ ^[0-9]*$ ]]; then + error "$(gettext "%s must be an integer.")" "epoch" + return 1 + fi + if [[ $arch != 'any' ]]; then if ! in_array $CARCH ${arch[@]}; then if (( ! IGNOREARCH )); then @@ -1217,31 +1222,33 @@ check_sanity() { fi fi - local provide - for provide in ${provides[@]}; do - if [[ $provide != ${provide//</} || $provide != ${provide//>/} ]]; then + local provides_list + eval $(awk '/^[[:space:]]*provides=/,/)/' "$BUILDFILE" | sed "s/provides=/provides_list+=/") + for i in ${provides_list[@]}; do + if [[ $i != ${i//</} || $i != ${i//>/} ]]; then error "$(gettext "Provides array cannot contain comparison (< or >) operators.")" return 1 fi done - local file - for file in "${backup[@]}"; do - if [[ ${file:0:1} = "/" ]]; then - error "$(gettext "Invalid backup entry : %s")" "$file" + local backup_list + eval $(awk '/^[[:space:]]*backup=/,/)/' "$BUILDFILE" | sed "s/backup=/backup_list+=/") + for i in "${backup_list[@]}"; do + if [[ ${i:0:1} = "/" ]]; then + error "$(gettext "Backup entry should not contain leading slash : %s")" "$i" return 1 fi done - local optdepend - for optdepend in "${optdepends[@]}"; do - pkg=${optdepend%%:*} - if [[ ! $pkg =~ ^[[:alnum:]\>\<\=\.\+\_\-]*$ ]]; then - error "$(gettext "Invalid syntax for optdepend : '%s'")" "$optdepend" + local optdepends_list + eval $(awk '/^[[:space:]]*optdepends=/,/)/' "$BUILDFILE" | sed "s/optdepends=/optdepends_list+=/") + for i in "${optdepends_list[@]}"; do + local pkg=${i%%:*} + if [[ ! $pkg =~ ^[[:alnum:]\>\<\=\.\+\_\-]+$ ]]; then + error "$(gettext "Invalid syntax for optdepend : '%s'")" "$i" fi done - local i for i in 'changelog' 'install'; do local filelist=$(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE") local file @@ -1256,17 +1263,18 @@ check_sanity() { done local valid_options=1 - local opt known kopt - for opt in ${options[@]}; do + local known kopt options_list + eval $(awk '/^[[:space:]]*options=/,/)/' "$BUILDFILE" | sed "s/options=/options_list+=/") + for i in ${options_list[@]}; do known=0 # check if option matches a known option or its inverse for kopt in ${packaging_options[@]} ${other_options[@]}; do - if [[ ${opt} = ${kopt} || ${opt} = "!${kopt}" ]]; then + if [[ ${i} = ${kopt} || ${i} = "!${kopt}" ]]; then known=1 fi done if (( ! known )); then - error "$(gettext "options array contains unknown option '%s'")" "$opt" + error "$(gettext "options array contains unknown option '%s'")" "$i" valid_options=0 fi done @@ -1275,22 +1283,20 @@ check_sanity() { fi if (( ${#pkgname[@]} > 1 )); then - for pkg in ${pkgname[@]}; do - if [ "$(type -t package_${pkg})" != "function" ]; then - error "$(gettext "missing package function for split package '%s'")" "$pkg" + for i in ${pkgname[@]}; do + if ! declare -f package_${i} >/dev/null; then + error "$(gettext "missing package function for split package '%s'")" "$i" return 1 fi done fi - if [[ -n "${PKGLIST[@]}" ]]; then - for pkg in ${PKGLIST[@]}; do - if ! in_array $pkg ${pkgname[@]}; then - error "$(gettext "requested package %s is not provided in %s")" "$pkg" "$BUILDFILE" - return 1 - fi - done - fi + for i in ${PKGLIST[@]}; do + if ! in_array $i ${pkgname[@]}; then + error "$(gettext "requested package %s is not provided in %s")" "$i" "$BUILDFILE" + return 1 + fi + done return 0 } @@ -1313,27 +1319,27 @@ devel_check() { # Also do a brief check to make sure we have the VCS tool available. oldpkgver=$pkgver if [[ -n ${_darcstrunk} && -n ${_darcsmod} ]] ; then - [ $(type -p darcs) ] || return 0 + type -p darcs >/dev/null || return 0 msg "$(gettext "Determining latest darcs revision...")" newpkgver=$(date +%Y%m%d) elif [[ -n ${_cvsroot} && -n ${_cvsmod} ]] ; then - [ $(type -p cvs) ] || return 0 + type -p cvs >/dev/null || return 0 msg "$(gettext "Determining latest cvs revision...")" newpkgver=$(date +%Y%m%d) elif [[ -n ${_gitroot} && -n ${_gitname} ]] ; then - [ $(type -p git) ] || return 0 + type -p git >/dev/null || return 0 msg "$(gettext "Determining latest git revision...")" newpkgver=$(date +%Y%m%d) elif [[ -n ${_svntrunk} && -n ${_svnmod} ]] ; then - [ $(type -p svn) ] || return 0 + type -p svn >/dev/null || return 0 msg "$(gettext "Determining latest svn revision...")" newpkgver=$(LC_ALL=C svn info $_svntrunk | sed -n 's/^Last Changed Rev: \([0-9]*\)$/\1/p') elif [[ -n ${_bzrtrunk} && -n ${_bzrmod} ]] ; then - [ $(type -p bzr) ] || return 0 + type -p bzr >/dev/null || return 0 msg "$(gettext "Determining latest bzr revision...")" newpkgver=$(bzr revno ${_bzrtrunk}) elif [[ -n ${_hgroot} && -n ${_hgrepo} ]] ; then - [ $(type -p hg) ] || return 0 + type -p hg >/dev/null || return 0 msg "$(gettext "Determining latest hg revision...")" if [[ -d ./src/$_hgrepo ]] ; then cd ./src/$_hgrepo @@ -1380,15 +1386,17 @@ devel_update() { } backup_package_variables() { + local var for var in ${splitpkg_overrides[@]}; do - indirect="${var}_backup" + local indirect="${var}_backup" eval "${indirect}=(\"\${$var[@]}\")" done } restore_package_variables() { + local var for var in ${splitpkg_overrides[@]}; do - indirect="${var}_backup" + local indirect="${var}_backup" if [[ -n ${!indirect} ]]; then eval "${var}=(\"\${$indirect[@]}\")" else @@ -1397,12 +1405,41 @@ restore_package_variables() { done } +run_split_packaging() { + for pkg in ${pkgname[@]}; do + pkgdir="$pkgdir/$pkg" + mkdir -p "$pkgdir" + chmod a-s "$pkgdir" + backup_package_variables + run_package $pkg + tidy_install + create_package $pkg + restore_package_variables + pkgdir="${pkgdir%/*}" + done +} + +# Canonicalize a directory path if it exists +canonicalize_path() { + local path="$1"; + + if [[ -d $path ]]; then + ( + cd "$path" + pwd -P + ) + else + echo "$path" + fi +} + # getopt like parser parse_options() { local short_options=$1; shift; local long_options=$1; shift; local ret=0; local unused_options="" + local i while [[ -n $1 ]]; do if [[ ${1:0:2} = '--' ]]; then @@ -1438,7 +1475,7 @@ parse_options() { elif [[ ${1:0:1} = '-' ]]; then for ((i=1; i<${#1}; i++)); do if [[ $short_options =~ ${1:i:1} ]]; then - if [[ $short_options =~ "${1:i:1}:" ]]; then + if [[ $short_options =~ ${1:i:1}: ]]; then if [[ -n ${1:$i+1} ]]; then printf ' -%s' "${1:i:1}" printf " '%s'" "${1:$i+1}" @@ -1535,7 +1572,7 @@ There is NO WARRANTY, to the extent permitted by law.\n")" # PROGRAM START # determine whether we have gettext; make it a no-op if we do not -if [ ! $(type -t gettext) ]; then +if ! type -p gettext >/dev/null; then gettext() { echo "$@" } @@ -1546,11 +1583,11 @@ ARGLIST=("$@") # Parse Command Line Options. OPT_SHORT="AcCdefFghiLmop:rRsV" OPT_LONG="allsource,asroot,ignorearch,clean,cleancache,nodeps" -OPT_LONG="$OPT_LONG,noextract,force,forcever:,geninteg,help,holdver" -OPT_LONG="$OPT_LONG,install,log,nocolor,nobuild,pkg:,rmdeps,repackage,skipinteg" -OPT_LONG="$OPT_LONG,source,syncdeps,version,config:" +OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver" +OPT_LONG+=",install,log,nocolor,nobuild,pkg:,rmdeps,repackage,skipinteg" +OPT_LONG+=",source,syncdeps,version,config:" # Pacman Options -OPT_LONG="$OPT_LONG,noconfirm,noprogressbar" +OPT_LONG+=",noconfirm,noprogressbar" OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@" || echo 'PARSE_OPTIONS FAILED')" if [[ $OPT_TEMP = *'PARSE_OPTIONS FAILED'* ]]; then # This is a small hack to stop the script bailing with 'set -e' @@ -1562,8 +1599,8 @@ unset OPT_SHORT OPT_LONG OPT_TEMP while true; do case "$1" in # Pacman Options - --noconfirm) PACMAN_OPTS="$PACMAN_OPTS --noconfirm" ;; - --noprogressbar) PACMAN_OPTS="$PACMAN_OPTS --noprogressbar" ;; + --noconfirm) PACMAN_OPTS+=" --noconfirm" ;; + --noprogressbar) PACMAN_OPTS+=" --noprogressbar" ;; # Makepkg Options --allsource) SOURCEONLY=2 ;; @@ -1601,10 +1638,10 @@ while true; do shift done -#preserve environment variables -_PKGDEST=${PKGDEST} -_SRCDEST=${SRCDEST} -_SRCPKGDEST=${SRCPKGDEST} +# preserve environment variables and canonicalize path +[[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST}) +[[ -n ${SRCDEST} ]] && _SRCDEST=$(canonicalize_path ${SRCDEST}) +[[ -n ${SRCPKGDEST} ]] && _SRCPKGDEST=$(canonicalize_path ${SRCPKGDEST}) # default config is makepkg.conf MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf} @@ -1638,12 +1675,12 @@ if [[ -t 2 && ! $USE_COLOR = "n" && $(check_buildenv color) = "y" ]]; then RED="${BOLD}$(tput setaf 1)" YELLOW="${BOLD}$(tput setaf 3)" else - ALL_OFF="\033[1;0m" - BOLD="\033[1;1m" - BLUE="${BOLD}\033[1;34m" - GREEN="${BOLD}\033[1;32m" - RED="${BOLD}\033[1;31m" - YELLOW="${BOLD}\033[1;33m" + ALL_OFF="\e[1;0m" + BOLD="\e[1;1m" + BLUE="${BOLD}\e[1;34m" + GREEN="${BOLD}\e[1;32m" + RED="${BOLD}\e[1;31m" + YELLOW="${BOLD}\e[1;33m" fi fi readonly ALL_OFF BOLD BLUE GREEN RED YELLOW @@ -1677,7 +1714,7 @@ fi if (( CLEANCACHE )); then #fix flyspray feature request #5223 - if [[ -n $SRCDEST && $SRCDEST != $startdir ]]; then + if [[ -n $SRCDEST && ! $SRCDEST -ef "${startdir}" ]]; then msg "$(gettext "Cleaning up ALL files from %s.")" "$SRCDEST" echo -n "$(gettext " Are you sure you wish to do this? ")" echo -n "$(gettext "[y/N]")" @@ -1719,7 +1756,7 @@ if (( ! INFAKEROOT )); then plain "$(gettext "Please rerun makepkg without the --asroot flag.")" exit 1 # $E_USER_ABORT elif [[ $(check_buildenv fakeroot) = "y" ]] && (( EUID > 0 )); then - if [ ! $(type -p fakeroot) ]; then + if ! type -p fakeroot >/dev/null; then error "$(gettext "Fakeroot must be installed if using the 'fakeroot' option")" plain "$(gettext "in the BUILDENV array in %s.")" "$MAKEPKG_CONF" exit 1 @@ -1739,7 +1776,7 @@ fi # check for sudo if we will need it during makepkg execution if (( ! ( ASROOT || INFAKEROOT ) && ( DEP_BIN || RMDEPS || INSTALL ) )); then - if [ ! "$(type -p sudo)" ]; then + if ! type -p sudo >/dev/null; then warning "$(gettext "Sudo can not be found. Will use su to acquire root privileges.")" fi fi @@ -1795,14 +1832,12 @@ if (( ${#pkgname[@]} > 1 )); then fi # test for available PKGBUILD functions -# The exclamation mark is required here to avoid triggering the ERR trap when -# a tested function does not exist. -if [[ $(! type -t build) = "function" ]]; then +if declare -f build >/dev/null; then BUILDFUNC=1 fi -if [ "$(type -t package)" = "function" ]; then +if declare -f package >/dev/null; then PKGFUNC=1 -elif [ $SPLITPKG -eq 0 -a "$(type -t package_${pkgname})" = "function" ]; then +elif [[ $SPLITPKG -eq 0 ]] && declare -f package_${pkgname} >/dev/null; then SPLITPKG=1 fi @@ -1875,17 +1910,7 @@ if (( INFAKEROOT )); then fi create_package else - for pkg in ${pkgname[@]}; do - pkgdir="$pkgdir/$pkg" - mkdir -p "$pkgdir" - chmod a-s "$pkgdir" - backup_package_variables - run_package $pkg - tidy_install - create_package $pkg - restore_package_variables - pkgdir="${pkgdir%/*}" - done + run_split_packaging fi msg "$(gettext "Leaving fakeroot environment.")" @@ -1911,20 +1936,20 @@ if (( NODEPS || ( (NOBUILD || REPKG) && !DEP_BIN ) )); then if (( NODEPS || ( REPKG && PKGFUNC ) )); then warning "$(gettext "Skipping dependency checks.")" fi -elif [ $(type -p "${PACMAN%% *}") ]; then +elif type -p "${PACMAN%% *}" >/dev/null; then if (( RMDEPS )); then - original_pkglist=($(run_pacman -Qq | sort)) # required by remove_dep + original_pkglist=($(run_pacman -Qq)) # required by remove_dep fi deperr=0 - msg "$(gettext "Checking Runtime Dependencies...")" + msg "$(gettext "Checking runtime dependencies...")" resolve_deps ${depends[@]} || deperr=1 - msg "$(gettext "Checking Buildtime Dependencies...")" + msg "$(gettext "Checking buildtime dependencies...")" resolve_deps ${makedepends[@]} || deperr=1 if (( RMDEPS )); then - current_pkglist=($(run_pacman -Qq | sort)) # required by remove_deps + current_pkglist=($(run_pacman -Qq)) # required by remove_deps fi if (( deperr )); then @@ -2003,17 +2028,7 @@ else fi create_package else - for pkg in ${pkgname[@]}; do - pkgdir="$pkgdir/$pkg" - mkdir -p "$pkgdir" - chmod a-s "$pkgdir" - backup_package_variables - run_package $pkg - tidy_install - create_package $pkg - restore_package_variables - pkgdir="${pkgdir%/*}" - done + run_split_packaging fi else if (( ! REPKG && ( PKGFUNC || SPLITPKG ) )); then diff --git a/scripts/pacman-db-upgrade.sh.in b/scripts/pacman-db-upgrade.sh.in new file mode 100644 index 00000000..4e6194fa --- /dev/null +++ b/scripts/pacman-db-upgrade.sh.in @@ -0,0 +1,121 @@ +#!@BASH_SHELL@ -e +# +# pacman-db-upgrade - upgrade the local pacman db to a newer format +# @configure_input@ +# +# Copyright (c) 2010 Pacman Development Team <pacman-dev@archlinux.org> +# +# 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 2 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 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/>. +# + +# gettext initialization +export TEXTDOMAIN='pacman' +export TEXTDOMAINDIR='@localedir@' + +myver='@PACKAGE_VERSION@' + +eval $(awk '/DBPath/ {print $1$2$3}' @sysconfdir@/pacman.conf) +dbroot="${DBPath:-@localstatedir@/lib/pacman/}" + +msg() { + local mesg=$1; shift + printf "==> ${mesg}\n" "$@" >&2 +} + +error () { + local mesg=$1; shift + printf "==> ERROR: ${mesg}\n" "$@" >&2 +} +usage() { + printf "pacman-db-upgrade (pacman) %s\n\n" "$myver" + printf "$(gettext "Usage: %s [pacman_db_root]")\n\n" "$0" +} + +version() { + printf "pacman-db-upgrade (pacman) %s\n" "$myver" + printf "$(gettext "\ +Copyright (c) 2010 Pacman Development Team <pacman-dev@archlinux.org>.\n\ +This is free software; see the source for copying conditions.\n\ +There is NO WARRANTY, to the extent permitted by law.\n")" +} + +die() { + error "$@" + exit 1 +} + +die_r() { + rm -f "$lockfile" + die "$@" +} + +# PROGRAM START + +# determine whether we have gettext; make it a no-op if we do not +if ! type gettext &>/dev/null; then + gettext() { + echo "$@" + } +fi + +if [[ $1 = "-h" || $1 = "--help" ]]; then + usage + exit 0 +fi + +if [[ $1 = "-V" || $1 = "--version" ]]; then + version + exit 0 +fi + +if [[ -n $1 ]]; then + dbroot="$1" +fi + +if [[ ! -d $dbroot || ! -d $dbroot/local ]]; then + die "$(gettext "%s does not exist or is not a directory.")" "$dbroot" +fi + +if [[ ! -w $dbroot ]]; then + die "$(gettext "You must have correct permissions to upgrade the database.")" +fi + +# strip any trailing slash from our dbroot +dbroot="${dbroot%/}" +# form the path to our lockfile location +lockfile="${dbroot}/db.lck" + +# make sure pacman isn't running +if [[ -f $lockfile ]]; then + die "$(gettext "Pacman lock file was found. Cannot run while pacman is running.")" +fi +# do not let pacman run while we do this +touch "$lockfile" + +# pacman-3.4 to 3.5 upgrade - merge depends into desc +if [[ $(find "$dbroot"/local -name depends) ]]; then + msg "$(gettext "Pre-3.5 database format detected - upgrading...")" + for i in "$dbroot"/local/*; do + if [[ -f "$i"/depends ]]; then + cat "$i"/depends >> "$i"/desc + rm "$i"/depends + fi + done + msg "$(gettext "Done.")" +fi + +# remove the lock file +rm -f "$lockfile" + +# vim: set ts=2 sw=2 noet: diff --git a/scripts/pacman-optimize.sh.in b/scripts/pacman-optimize.sh.in index 78b2345b..2404291e 100644 --- a/scripts/pacman-optimize.sh.in +++ b/scripts/pacman-optimize.sh.in @@ -1,4 +1,4 @@ -#!/bin/bash +#!@BASH_SHELL@ # # pacman-optimize # @configure_input@ @@ -25,7 +25,9 @@ export TEXTDOMAIN='pacman' export TEXTDOMAINDIR='@localedir@' myver='@PACKAGE_VERSION@' -dbroot='@localstatedir@/lib/pacman/' + +eval $(awk '/DBPath/ {print $1$2$3}' @sysconfdir@/pacman.conf) +dbroot="${DBPath:-@localstatedir@/lib/pacman/}" msg() { local mesg=$1; shift @@ -99,7 +101,7 @@ if ! type diff >/dev/null 2>&1; then die "$(gettext "diff tool was not found, please install diffutils.")" fi -if [[ ! -d $dbroot ]]; then +if [[ ! -d $dbroot || ! -d $dbroot/local ]]; then die "$(gettext "%s does not exist or is not a directory.")" "$dbroot" fi diff --git a/scripts/pkgdelta.sh.in b/scripts/pkgdelta.sh.in index 1550fa10..6bc3f5da 100644 --- a/scripts/pkgdelta.sh.in +++ b/scripts/pkgdelta.sh.in @@ -1,4 +1,4 @@ -#!/bin/bash +#!@BASH_SHELL@ # # pkgdelta - create delta files for use with pacman and repo-add # @configure_input@ diff --git a/scripts/rankmirrors.sh.in b/scripts/rankmirrors.sh.in index b0dc1ab7..64d5a73c 100644 --- a/scripts/rankmirrors.sh.in +++ b/scripts/rankmirrors.sh.in @@ -1,4 +1,4 @@ -#!/bin/bash +#!@BASH_SHELL@ # # rankmirrors - read a list of mirrors from a file and rank them by speed # @configure_input@ @@ -25,7 +25,7 @@ usage() { echo "Usage: rankmirrors [options] MIRRORFILE | URL" echo echo "Ranks pacman mirrors by their connection and opening speed. Pacman mirror" - echo "files are located in /etc/pacman.d/. It can also rank one mirror if the URL is" + echo "files are located in @sysconfdir@/pacman.d/. It can also rank one mirror if the URL is" echo "provided." echo echo "Options:" @@ -85,7 +85,7 @@ getfetchurl() { if [[ -z $reponame || $reponame = $replacedurl ]]; then echo "fail" else - local fetchurl="${replacedurl}/$reponame@DBEXT@" + local fetchurl="${replacedurl}/$reponame.db" echo "$fetchurl" fi } diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in index 283ad07a..d09d1b48 100644 --- a/scripts/repo-add.sh.in +++ b/scripts/repo-add.sh.in @@ -1,4 +1,4 @@ -#!/bin/bash +#!@BASH_SHELL@ # # repo-add - add a package to a given repo database file # repo-remove - remove a package entry from a given repo database file @@ -28,6 +28,7 @@ myver='@PACKAGE_VERSION@' confdir='@sysconfdir@' QUIET=0 +DELTA=0 REPO_DB_FILE= LOCKFILE= CLEAN_LOCK=0 @@ -37,6 +38,7 @@ startdir="$PWD" umask 0022 msg() { + (( QUIET )) && return local mesg=$1; shift printf "==> ${mesg}\n" "$@" >&1 } @@ -60,7 +62,7 @@ error() { # print usage instructions usage() { printf "repo-add, repo-remove (pacman) %s\n\n" "$myver" - printf "$(gettext "Usage: repo-add [-q] <path-to-db> <package|delta> ...\n")" + printf "$(gettext "Usage: repo-add [-d] [-q] <path-to-db> <package|delta> ...\n")" printf "$(gettext "Usage: repo-remove [-q] <path-to-db> <packagename|delta> ...\n\n")" printf "$(gettext "\ repo-add will update a package database by reading a package file.\n\ @@ -72,6 +74,10 @@ packages to remove can be specified on the command line.\n\n")" printf "$(gettext "\ Use the -q/--quiet flag to minimize output to basic messages, warnings,\n\ and errors\n\n")" + printf "$(gettext "\ +Use the -d/--delta flag to automatically generate and add a delta file\n\ +between the old entry and the new one, if the old package file is found\n\ +next to the new one.\n\n")" echo "$(gettext "Example: repo-add /path/to/repo.db.tar.gz pacman-3.0.0.pkg.tar.gz")" echo "$(gettext "Example: repo-remove /path/to/repo.db.tar.gz kernel26")" } @@ -127,13 +133,12 @@ db_write_delta() pkgentry=$(find_pkgentry $pkgname) if [[ -z $pkgentry ]]; then + error "$(gettext "No database entry for package '%s'.")" "$pkgname" return 1 fi deltas="$pkgentry/deltas" - # create deltas file if it does not already exist if [[ ! -f $deltas ]]; then - msg2 "$(gettext "Creating 'deltas' db entry...")" - echo -e "%DELTAS%" >>$deltas + echo -e "%DELTAS%" >$deltas fi # get md5sum and compressed size of package md5sum="$(openssl dgst -md5 "$deltafile")" @@ -144,10 +149,9 @@ db_write_delta() newfile=$(xdelta3 printhdr $deltafile | grep "XDELTA filename (output)" | sed 's/.*: *//') if grep -q "$oldfile.*$newfile" $deltas; then - warning "$(gettext "An entry for '%s' already existed")" "$deltafile" sed -i.backup "/$oldfile.*$newfile/d" $deltas && rm -f $deltas.backup - msg2 "$(gettext "Removing existing entry '%s'...")" "$deltafile" fi + msg2 "$(gettext "Adding 'deltas' entry : %s -> %s")" "$oldfile" "$newfile" echo ${deltafile##*/} $md5sum $csize $oldfile $newfile >> $deltas return 0 @@ -184,7 +188,7 @@ db_write_entry() { # blank out all variables local pkgfile="$1" - local pkgname pkgver pkgdesc csize size md5sum url arch builddate packager force \ + local pkgname pkgver pkgdesc epoch csize size md5sum url arch builddate packager force \ _groups _licenses _replaces _depends _conflicts _provides _optdepends local OLDIFS="$IFS" @@ -228,6 +232,14 @@ db_write_entry() if [[ -d $pkgname-$pkgver ]]; then warning "$(gettext "An entry for '%s' already existed")" "$pkgname-$pkgver" + else + if [ $DELTA -eq 1 ]; then + pkgentry=$(find_pkgentry $pkgname) + if [ -n "$pkgentry" ]; then + local oldfilename=$(grep -A1 FILENAME $pkgentry/desc | tail -n1) + local oldfile="$(dirname $1)/$oldfilename" + fi + fi fi # remove an existing entry if it exists, ignore failures @@ -261,6 +273,11 @@ db_write_entry() [[ -n $builddate ]] && echo -e "%BUILDDATE%\n$builddate\n" >>desc [[ -n $packager ]] && echo -e "%PACKAGER%\n$packager\n" >>desc write_list_entry "REPLACES" "$_replaces" "desc" + # remain backward-compatible for now; put a force entry in the database + if [[ -n $epoch ]]; then + echo -e "%EPOCH%\n#epoch\n" >>desc + echo -e "%FORCE%\n" >>desc + fi [[ -n $force ]] && echo -e "%FORCE%\n" >>desc # create depends entry @@ -274,6 +291,16 @@ db_write_entry() cd "$startdir" + # create a delta file + if [ -n "$oldfilename" -a -f "$oldfile" ]; then + delta=$(pkgdelta -q $oldfile $1) + if [ -f "$delta" ]; then + db_write_delta $delta + else + warning "$(gettext "Old package file not found : %s")" "$oldfilename" + fi + fi + return 0 } # end db_write_entry @@ -446,6 +473,7 @@ success=0 for arg in "$@"; do case "$arg" in -q|--quiet) QUIET=1;; + -d|--delta) DELTA=1;; *) if [[ -z $REPO_DB_FILE ]]; then REPO_DB_FILE="$arg" |