diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/.gitignore | 1 | ||||
-rw-r--r-- | scripts/Makefile.am | 7 | ||||
-rw-r--r-- | scripts/makepkg.sh.in | 560 | ||||
-rw-r--r-- | scripts/pacman-db-upgrade.sh.in | 121 | ||||
-rw-r--r-- | scripts/pacman-optimize.sh.in | 12 | ||||
-rw-r--r-- | scripts/pkgdelta.sh.in | 2 | ||||
-rw-r--r-- | scripts/rankmirrors.sh.in | 6 | ||||
-rw-r--r-- | scripts/repo-add.sh.in | 72 |
8 files changed, 510 insertions, 271 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..ae6ce366 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 \ @@ -23,7 +25,7 @@ EXTRA_DIST = \ MOSTLYCLEANFILES = $(bin_SCRIPTS) *.tmp if USE_GIT_VERSION -GIT_VERSION := $(shell sh -c 'git describe --abbrev=4 | sed s/^v//')-dirty +GIT_VERSION := $(shell sh -c 'git describe --abbrev=4 --dirty | sed s/^v//') REAL_PACKAGE_VERSION = $(GIT_VERSION) else REAL_PACKAGE_VERSION = $(PACKAGE_VERSION) @@ -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..13415fbe 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -1,9 +1,9 @@ -#!/bin/bash -e +#!@BASH_SHELL@ -e # # makepkg - make packages compatible for use with pacman # @configure_input@ # -# Copyright (c) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org> +# Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org> # Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> # Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> # Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org> @@ -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' 'buildflags' 'makeflags') splitpkg_overrides=('pkgver' 'pkgrel' 'pkgdesc' 'arch' 'license' 'groups' \ 'depends' 'optdepends' 'provides' 'conflicts' 'replaces' \ 'backup' 'options' 'install' 'changelog') @@ -71,6 +71,7 @@ SOURCEONLY=0 IGNOREARCH=0 HOLDVER=0 BUILDFUNC=0 +CHECKFUNC=0 PKGFUNC=0 SPLITPKG=0 PKGLIST=() @@ -135,25 +136,32 @@ 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" if [[ -n $pkgbase ]]; then + # TODO: this wasn't properly fixed in commit 2020e629 + local fullver=$(get_full_version $epoch $pkgver $pkgrel) # Can't do this unless the BUILDSCRIPT has been sourced. if (( BUILDFUNC )); then - rm -f "${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-build.log"* + rm -f "${pkgbase}-${fullver}-${CARCH}-build.log"* + fi + if (( CHECKFUNC )); then + rm -f "${pkgbase}-${fullver}-${CARCH}-check.log"* fi if (( PKGFUNC )); then - rm -f "${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-package.log"* + rm -f "${pkgbase}-${fullver}-${CARCH}-package.log"* elif (( SPLITPKG )); then for pkg in ${pkgname[@]}; do - rm -f "${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-package_${pkg}.log"* + rm -f "${pkgbase}-${fullver}-${CARCH}-package_${pkg}.log"* done fi # 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 @@ -219,6 +227,19 @@ get_url() { } ## +# usage : get_full_version( $epoch, $pkgver, $pkgrel ) +# return : full version spec, including epoch (if necessary), pkgver, pkgrel +## +get_full_version() { + if [[ $1 -eq 0 ]]; then + # zero epoch case, don't include it in version + echo $2-$3 + else + echo $1:$2-$3 + fi +} + +## # Checks to see if options are present in makepkg.conf or PKGBUILD; # PKGBUILD options always take precedence. # @@ -308,7 +329,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 +344,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 +391,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 +408,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 +416,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 +456,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 +564,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 +614,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 +675,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 +706,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 +741,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 +752,14 @@ run_function() { if [[ -z $1 ]]; then return 1 fi - pkgfunc="$1" + local pkgfunc="$1" + + # clear user-specified buildflags if requested + if [[ $(check_option buildflags) = "n" ]]; then + CFLAGS="" + CXXFLAGS="" + LDFLAGS="" + fi # clear user-specified makeflags if requested if [[ $(check_option makeflags) = "n" ]]; then @@ -743,8 +775,10 @@ run_function() { local shellopts=$(shopt -p) local ret=0 + local restoretrap if (( LOGGING )); then - BUILDLOG="${startdir}/${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-$pkgfunc.log" + local fullver=$(get_full_version $epoch $pkgver $pkgrel) + local BUILDLOG="${startdir}/${pkgbase}-${fullver}-${CARCH}-$pkgfunc.log" if [[ -f $BUILDLOG ]]; then local i=1 while true; do @@ -759,12 +793,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 +806,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 @@ -798,7 +832,12 @@ run_build() { run_function "build" } +run_check() { + run_function "check" +} + run_package() { + local pkgfunc if [[ -z $1 ]]; then pkgfunc="package" else @@ -865,13 +904,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 +944,38 @@ 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 = $(get_full_version $epoch $pkgver $pkgrel)" + echo "pkgdesc = $pkgdesc" + 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 +995,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 -print0 | xargs -0 grep -q -I "${srcdir}" ; then warning "$(gettext "Package contains reference to %s")" "\$srcdir" fi + if find "${pkgdir}" -type f -print0 | xargs -0 grep -q -I "${pkgdir}" ; then + warning "$(gettext "Package contains reference to %s")" "\$pkgdir" + fi + } create_package() { @@ -996,6 +1021,7 @@ create_package() { cd "$pkgdir" msg "$(gettext "Creating package...")" + local nameofpkg if [[ -z $1 ]]; then nameofpkg="$pkgname" else @@ -1008,62 +1034,62 @@ 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 fullver=$(get_full_version $epoch $pkgver $pkgrel) + local pkg_file="$PKGDEST/${nameofpkg}-${fullver}-${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,11 +1155,13 @@ 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 - local pkg_file="$SRCPKGDEST/${pkgbase}-${pkgver}-${pkgrel}${SRCEXT}" + local fullver=$(get_full_version $epoch $pkgver $pkgrel) + local pkg_file="$SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT}" # tar it up msg2 "$(gettext "Compressing source package...")" @@ -1142,6 +1170,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 +1193,14 @@ install_package() { msg "$(gettext "Installing %s package group with %s -U...")" "$pkgbase" "$PACMAN" fi - local pkglist + local fullver pkg pkglist for pkg in ${pkgname[@]}; do - if [[ -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} ]]; then - pkglist="${pkglist} $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}" + # TODO: this wasn't properly fixed in commit 2020e629 + fullver=$(get_full_version $epoch $pkgver $pkgrel) + if [[ -f $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT} ]]; then + pkglist+=" $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT}" else - pkglist="${pkglist} $PKGDEST/${pkg}-${pkgver}-${pkgrel}-any${PKGEXT}" + pkglist+=" $PKGDEST/${pkg}-${fullver}-any${PKGEXT}" fi done @@ -1172,38 +1212,38 @@ 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 + local ret=0 + for i in 'pkgname' 'pkgrel' 'pkgver'; do + if [[ -z ${!i} ]]; then + error "$(gettext "%s is not allowed to be empty.")" "$i" + ret=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 + ret=1 fi done if [[ ${pkgbase:0:1} = "-" ]]; then error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgbase" - return 1 + ret=1 fi - if [[ $pkgver != ${pkgver//-/} ]]; then - error "$(gettext "%s is not allowed to contain hyphens.")" "pkgver" - return 1 + if [[ $pkgver =~ [:-] ]]; then + error "$(gettext "%s is not allowed to contain colons or hyphens.")" "pkgver" + ret=1 fi if [[ $pkgrel != ${pkgrel//-/} ]]; then error "$(gettext "%s is not allowed to contain hyphens.")" "pkgrel" - return 1 + ret=1 + fi + + if [[ ! $epoch =~ ^[0-9]*$ ]]; then + error "$(gettext "%s must be an integer.")" "epoch" + ret=1 fi if [[ $arch != 'any' ]]; then @@ -1212,36 +1252,39 @@ check_sanity() { error "$(gettext "%s is not available for the '%s' architecture.")" "$pkgbase" "$CARCH" plain "$(gettext "Note that many packages may need a line added to their %s")" "$BUILDSCRIPT" plain "$(gettext "such as arch=('%s').")" "$CARCH" - return 1 + ret=1 fi 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 + ret=1 fi done - local file - for file in "${backup[@]}"; do - if [[ ${file:0:1} = "/" ]]; then - error "$(gettext "Invalid backup entry : %s")" "$file" - return 1 + 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" + ret=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" + ret=1 fi done - local i for i in 'changelog' 'install'; do local filelist=$(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE") local file @@ -1250,49 +1293,48 @@ check_sanity() { eval file=${file} if [[ ! -f $file ]]; then error "$(gettext "%s file (%s) does not exist.")" "$i" "$file" - return 1 + ret=1 fi done 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 if (( ! valid_options )); then - return 1 + ret=1 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" - return 1 + for i in ${pkgname[@]}; do + if ! declare -f package_${i} >/dev/null; then + error "$(gettext "missing package function for split package '%s'")" "$i" + ret=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" + ret=1 + fi + done - return 0 + return $ret } devel_check() { @@ -1313,27 +1355,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 +1422,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 +1441,43 @@ restore_package_variables() { done } +run_split_packaging() { + local pkgname_backup=${pkgname[@]} + for pkgname in ${pkgname_backup[@]}; do + pkgdir="$pkgdir/$pkgname" + mkdir -p "$pkgdir" + chmod a-s "$pkgdir" + backup_package_variables + run_package $pkgname + tidy_install + create_package $pkgname + restore_package_variables + pkgdir="${pkgdir%/*}" + done + pkgname=${pkgname_backup[@]} +} + +# 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 +1513,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}" @@ -1508,8 +1583,10 @@ usage() { echo "$(gettext " -s, --syncdeps Install missing dependencies with pacman")" echo "$(gettext " --allsource Generate a source-only tarball including downloaded sources")" echo "$(gettext " --asroot Allow makepkg to run as root user")" + printf "$(gettext " --check Run the check() function in the %s")\n" "$BUILDSCRIPT" printf "$(gettext " --config <file> Use an alternate config file (instead of '%s')")\n" "$confdir/makepkg.conf" - echo "$(gettext " --holdver Prevent automatic version bumping for development PKGBUILDs")" + printf "$(gettext " --holdver Prevent automatic version bumping for development %ss")\n" "$BUILDSCRIPT" + printf "$(gettext " --nocheck Do not run the check() function in the %s")\n" "$BUILDSCRIPT" echo "$(gettext " --pkg <list> Only build listed packages from a split package")" echo "$(gettext " --skipinteg Do not fail when integrity checks are missing")" echo "$(gettext " --source Generate a source-only tarball without downloaded sources")" @@ -1526,7 +1603,7 @@ usage() { version() { printf "makepkg (pacman) %s\n" "$myver" printf "$(gettext "\ -Copyright (c) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org>.\n\ +Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>.\n\ Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>.\n\n\ This is free software; see the source for copying conditions.\n\ There is NO WARRANTY, to the extent permitted by law.\n")" @@ -1535,7 +1612,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 "$@" } @@ -1545,12 +1622,12 @@ 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="allsource,asroot,ignorearch,check,clean,cleancache,nodeps" +OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver" +OPT_LONG+=",install,log,nocolor,nobuild,nocheck,pkg:,rmdeps" +OPT_LONG+=",repackage,skipinteg,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 +1639,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 ;; @@ -1571,6 +1648,7 @@ while true; do -A|--ignorearch) IGNOREARCH=1 ;; -c|--clean) CLEANUP=1 ;; -C|--cleancache) CLEANCACHE=1 ;; + --check) RUN_CHECK='y' ;; --config) shift; MAKEPKG_CONF=$1 ;; -d|--nodeps) NODEPS=1 ;; -e|--noextract) NOEXTRACT=1 ;; @@ -1583,6 +1661,7 @@ while true; do -i|--install) INSTALL=1 ;; -L|--log) LOGGING=1 ;; -m|--nocolor) USE_COLOR='n' ;; + --nocheck) RUN_CHECK='n' ;; -o|--nobuild) NOBUILD=1 ;; -p) shift; BUILDFILE=$1 ;; --pkg) shift; PKGLIST=($1) ;; @@ -1601,10 +1680,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 +1717,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 @@ -1666,7 +1745,7 @@ if [[ ! -w $SRCDEST ]] ; then fi SRCPKGDEST=${_SRCPKGDEST:-$SRCPKGDEST} -SRCPKGDEST=${SRCPKGDEST:-$PKGDEST} #default to $PKGDEST if undefined +SRCPKGDEST=${SRCPKGDEST:-$startdir} #default to $startdir if undefined if (( HOLDVER )) && [[ -n $FORCE_VER ]]; then @@ -1677,7 +1756,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 +1798,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,12 +1818,12 @@ 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 -unset pkgname pkgbase pkgver pkgrel pkgdesc url license groups provides +unset pkgname pkgbase pkgver pkgrel epoch pkgdesc url license groups provides unset md5sums replaces depends conflicts backup source install changelog build unset makedepends optdepends options noextract @@ -1780,6 +1859,9 @@ if (( GENINTEG )); then exit 0 # $E_OK fi +pkgbase=${pkgbase:-${pkgname[0]}} +epoch=${epoch:-0} + # check the PKGBUILD for some basic requirements check_sanity || exit 1 @@ -1795,27 +1877,30 @@ 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 check >/dev/null; then + # "Hide" check() function if not going to be run + if [[ $RUN_CHECK = 'y' || (! $(check_buildenv check) = "n" && ! $RUN_CHECK = "n") ]]; then + CHECKFUNC=1 + fi +fi +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 -pkgbase=${pkgbase:-${pkgname[0]}} - if [[ -n "${PKGLIST[@]}" ]]; then unset pkgname pkgname=("${PKGLIST[@]}") fi if (( ! SPLITPKG )); then - if [[ -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} \ - || -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-any${PKGEXT} ]] \ + fullver=$(get_full_version $epoch $pkgver $pkgrel) + if [[ -f $PKGDEST/${pkgname}-${fullver}-${CARCH}${PKGEXT} \ + || -f $PKGDEST/${pkgname}-${fullver}-any${PKGEXT} ]] \ && ! (( FORCE || SOURCEONLY || NOBUILD )); then if (( INSTALL )); then warning "$(gettext "A package has already been built, installing existing package...")" @@ -1830,8 +1915,10 @@ else allpkgbuilt=1 somepkgbuilt=0 for pkg in ${pkgname[@]}; do - if [[ -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} \ - || -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-any${PKGEXT} ]]; then + # TODO: this wasn't properly fixed in commit 2020e629 + fullver=$(get_full_version $epoch $pkgver $pkgrel) + if [[ -f $PKGDEST/${pkg}-${fullver}-${CARCH}${PKGEXT} \ + || -f $PKGDEST/${pkg}-${fullver}-any${PKGEXT} ]]; then somepkgbuilt=1 else allpkgbuilt=0 @@ -1863,6 +1950,7 @@ if (( INFAKEROOT )); then if (( ! REPKG )); then if (( BUILDFUNC )); then run_build + (( CHECKFUNC )) && run_check tidy_install fi else @@ -1875,28 +1963,19 @@ 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.")" exit 0 # $E_OK fi -msg "$(gettext "Making package: %s")" "$pkgbase $pkgver-$pkgrel ($(date))" +fullver=$(get_full_version $epoch $pkgver $pkgrel) +msg "$(gettext "Making package: %s")" "$pkgbase $fullver ($(date))" # if we are creating a source-only package, go no further if (( SOURCEONLY )); then - if [[ -f $SRCPKGDEST/${pkgbase}-${pkgver}-${pkgrel}${SRCEXT} ]] \ + if [[ -f $SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT} ]] \ && (( ! FORCE )); then error "$(gettext "A source package has already been built. (use -f to overwrite)")" exit 1 @@ -1911,20 +1990,24 @@ 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 (( CHECKFUNC )); then + resolve_deps ${checkdepends[@]} || deperr=1 + fi + 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 @@ -1988,6 +2071,7 @@ else if (( ! REPKG )); then devel_update (( BUILDFUNC )) && run_build + (( CHECKFUNC )) && run_check fi if (( ! SPLITPKG )); then if (( PKGFUNC )); then @@ -2003,22 +2087,13 @@ 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 devel_update (( BUILDFUNC )) && run_build + (( CHECKFUNC )) && run_check cd "$startdir" fi @@ -2032,7 +2107,8 @@ else fi fi -msg "$(gettext "Finished making: %s")" "$pkgbase $pkgver-$pkgrel ($(date))" +fullver=$(get_full_version $epoch $pkgver $pkgrel) +msg "$(gettext "Finished making: %s")" "$pkgbase $fullver ($(date))" install_package diff --git a/scripts/pacman-db-upgrade.sh.in b/scripts/pacman-db-upgrade.sh.in new file mode 100644 index 00000000..0813acc6 --- /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-2011 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-2011 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..4e2a328a 100644 --- a/scripts/pacman-optimize.sh.in +++ b/scripts/pacman-optimize.sh.in @@ -1,9 +1,9 @@ -#!/bin/bash +#!@BASH_SHELL@ # # pacman-optimize # @configure_input@ # -# Copyright (c) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org> +# Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org> # Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> # # This program is free software; you can redistribute it and/or modify @@ -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 @@ -55,7 +57,7 @@ does not have to move around the disk as much.\n")" version() { printf "pacman-optimize (pacman) %s\n" "$myver" printf "$(gettext "\ -Copyright (c) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org>.\n\ +Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>.\n\ Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>.\n\n\ This is free software; see the source for copying conditions.\n\ There is NO WARRANTY, to the extent permitted by law.\n")" @@ -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..9b79022a 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,15 +28,17 @@ myver='@PACKAGE_VERSION@' confdir='@sysconfdir@' QUIET=0 +DELTA=0 +WITHFILES=0 REPO_DB_FILE= LOCKFILE= CLEAN_LOCK=0 -startdir="$PWD" # ensure we have a sane umask set 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] [-f] [-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\ @@ -71,7 +73,13 @@ specified on the command line from the given repo database. Multiple\n\ 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")" +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")" + printf "$(gettext "\ +Use the -f/--files flag to update a database including file entries.\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 +135,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 +151,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 +190,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 csize size md5sum url arch builddate packager \ _groups _licenses _replaces _depends _conflicts _provides _optdepends local OLDIFS="$IFS" @@ -224,10 +230,17 @@ db_write_entry() return 1 fi - cd "$tmpdir" - + pushd "$tmpdir" >/dev/null if [[ -d $pkgname-$pkgver ]]; then warning "$(gettext "An entry for '%s' already existed")" "$pkgname-$pkgver" + else + if (( DELTA )); 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 @@ -235,7 +248,7 @@ db_write_entry() # create package directory mkdir "$pkgname-$pkgver" - cd "$pkgname-$pkgver" + pushd "$pkgname-$pkgver" >/dev/null # restore an eventual deltas file [[ -f ../$pkgname.deltas ]] && mv "../$pkgname.deltas" deltas @@ -261,7 +274,6 @@ 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" - [[ -n $force ]] && echo -e "%FORCE%\n" >>desc # create depends entry msg2 "$(gettext "Creating 'depends' db entry...")" @@ -272,7 +284,30 @@ db_write_entry() write_list_entry "PROVIDES" "$_provides" "depends" write_list_entry "OPTDEPENDS" "$_optdepends" "depends" - cd "$startdir" + popd >/dev/null + popd >/dev/null + + # create files file if wanted + if (( WITHFILES )); then + msg2 "$(gettext "Creating 'files' db entry...")" + local files_path="$tmpdir/$pkgname-$pkgver/files" + echo "%FILES%" >$files_path + bsdtar --exclude='.*' -tf "$pkgfile" >>$files_path + fi + + # create a delta file + if (( DELTA )); then + if [[ -n $oldfilename ]]; then + if [[ -f $oldfile ]]; then + delta=$(pkgdelta -q $oldfile $1) + if [[ -f $delta ]]; then + db_write_delta $delta + fi + else + warning "$(gettext "Old package file not found: %s")" "$oldfilename" + fi + fi + fi return 0 } # end db_write_entry @@ -404,7 +439,6 @@ trap_exit() clean_up() { local exit_code=$? - cd "$startdir" [[ -d $tmpdir ]] && rm -rf "$tmpdir" (( CLEAN_LOCK )) && [[ -f $LOCKFILE ]] && rm -f "$LOCKFILE" @@ -446,6 +480,8 @@ success=0 for arg in "$@"; do case "$arg" in -q|--quiet) QUIET=1;; + -d|--delta) DELTA=1;; + -f|--files) WITHFILES=1;; *) if [[ -z $REPO_DB_FILE ]]; then REPO_DB_FILE="$arg" @@ -475,7 +511,7 @@ if (( success )); then filename=$(basename "$REPO_DB_FILE") - cd "$tmpdir" + pushd "$tmpdir" >/dev/null if [[ -n $(ls) ]]; then bsdtar -c${TAR_OPT}f "$filename" * else @@ -483,7 +519,7 @@ if (( success )); then warning "$(gettext "No packages remain, creating empty database.")" bsdtar -c${TAR_OPT}f "$filename" -T /dev/null fi - cd "$startdir" + popd >/dev/null [[ -f $REPO_DB_FILE ]] && mv -f "$REPO_DB_FILE" "${REPO_DB_FILE}.old" [[ -f $tmpdir/$filename ]] && mv "$tmpdir/$filename" "$REPO_DB_FILE" |