[pacman-dev] [PATCH 1/6] remove --destination-dir argument from a2x options
This option is only for HTML output, and we're building manpages here. --- doc/Makefile.am | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/Makefile.am b/doc/Makefile.am index a7908df..60a70b3 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -124,8 +124,7 @@ A2X_OPTS = \ --no-xmllint \ -d manpage \ -f manpage \ - --xsltproc-opts='-param man.endnotes.list.enabled 0 -param man.endnotes.are.numbered 0' \ - --destination-dir='./' + --xsltproc-opts='-param man.endnotes.list.enabled 0 -param man.endnotes.are.numbered 0' # These rules are due to the includes and files of the asciidoc text $(ASCIIDOC_MANS): asciidoc.conf footer.txt Makefile.am -- 2.0.4
This is a confusing feature, and no one uses it. --- As per Allan's request. scripts/makepkg.sh.in | 45 ++++++++++++--------------------------------- 1 file changed, 12 insertions(+), 33 deletions(-) diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index f9e816f..9ae1e95 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -48,12 +48,12 @@ declare -r startdir="$PWD" LIBRARY=${LIBRARY:-'@libmakepkgdir@'} -packaging_options=('strip' 'docs' 'libtool' 'staticlibs' 'emptydirs' 'zipman' \ +packaging_options=('strip' 'docs' 'libtool' 'staticlibs' 'emptydirs' 'zipman' 'purge' 'upx' 'debug') other_options=('ccache' 'distcc' 'buildflags' 'makeflags') -splitpkg_overrides=('pkgver' 'pkgrel' 'epoch' 'pkgdesc' 'arch' 'url' 'license' \ - 'groups' 'depends' 'optdepends' 'provides' 'conflicts' \ - 'replaces' 'backup' 'options' 'install' 'changelog') +splitpkg_overrides=('pkgdesc' 'arch' 'url' 'license' 'groups' 'depends' + 'optdepends' 'provides' 'conflicts' 'replaces' 'backup' + 'options' 'install' 'changelog') readonly -a packaging_options other_options splitpkg_overrides known_hash_algos=('md5' 'sha1' 'sha224' 'sha256' 'sha384' 'sha512') @@ -842,27 +842,14 @@ missing_source_file() { } ## -# usage : get_full_version( [$pkgname] ) +# usage : get_full_version() # return : full version spec, including epoch (if necessary), pkgver, pkgrel ## get_full_version() { - if [[ -z $1 ]]; then - if [[ -n $epoch ]] && (( $epoch )); then - printf "%s\n" "$epoch:$pkgver-$pkgrel" - else - printf "%s\n" "$pkgver-$pkgrel" - fi + if [[ $epoch ]] && (( epoch > 0 )); then + printf "%s\n" "$epoch:$pkgver-$pkgrel" else - for i in pkgver pkgrel epoch; do - local indirect="${i}_override" - eval $(declare -f package_$1 | sed -n "s/\(^[[:space:]]*$i=\)/${i}_override=/p") - [[ -z ${!indirect} ]] && eval ${indirect}=\"${!i}\" - done - if [[ -n $epoch_override ]] && (( $epoch_override )); then - printf "%s\n" "$epoch_override:$pkgver_override-$pkgrel_override" - else - printf "%s\n" "$pkgver_override-$pkgrel_override" - fi + printf "%s\n" "$pkgver-$pkgrel" fi } @@ -2184,7 +2171,7 @@ install_package() { (( NEEDED )) && pkglist+=('--needed') for pkg in ${pkgname[@]}; do - fullver=$(get_full_version $pkg) + fullver=$(get_full_version) pkgarch=$(get_pkg_arch $pkg) pkglist+=("$PKGDEST/${pkg}-${fullver}-${pkgarch}${PKGEXT}") @@ -2386,20 +2373,12 @@ validate_pkgver() { } check_pkgver() { - local ret=0 - if [[ -z ${pkgver} ]]; then error "$(gettext "%s is not allowed to be empty.")" "pkgver" - ret=1 + return 1 fi - awk -F'=' '$1 ~ /^[[:space:]]*pkgver$/' "$BUILDFILE" | sed "s/[[:space:]]*#.*//" | - while IFS='=' read -r _ i; do - eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\" - validate_pkgver "$i" || return 1 - done || ret=1 - - return $ret + validate_pkgver "$pkgver" } check_software() { @@ -2515,7 +2494,7 @@ check_build_status() { allpkgbuilt=1 somepkgbuilt=0 for pkg in ${pkgname[@]}; do - fullver=$(get_full_version $pkg) + fullver=$(get_full_version) pkgarch=$(get_pkg_arch $pkg) if [[ -f $PKGDEST/${pkg}-${fullver}-${pkgarch}${PKGEXT} ]]; then somepkgbuilt=1 -- 2.0.4
Break apart each of the blocks into their own separate functions. And, instead of the hand crafted eval statements, reuse the logic from pkgbuild-introspection[0] to abstract away the complexities of parsing bash. This commit fixes at least 3 bugs in check_sanity: 1) The wrong variable is shown for the error which would be thrown when, e.g. pkgname=('foopkg' 'bar^pkg') 2) The "arch" variable is not sanity checked when the PKGBUILD has an arch override, but only one output package. 3) https://bugs.archlinux.org/task/40361 Lastly, there's some string changes here which should help to clarify a few errors emitted in the linting process. [0] https://github.com/falconindy/pkgbuild-introspection --- scripts/makepkg.sh.in | 406 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 299 insertions(+), 107 deletions(-) diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index 9ae1e95..e8cf60c 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -2190,18 +2190,103 @@ have_function() { declare -f "$1" >/dev/null } -check_sanity() { - # check for no-no's in the build script - local i - local ret=0 - for i in 'pkgname' 'pkgrel'; do - if [[ -z ${!i} ]]; then - error "$(gettext "%s is not allowed to be empty.")" "$i" - ret=1 - fi +array_build() { + local dest=$1 src=$2 i keys values + + # it's an error to try to copy a value which doesn't exist. + declare -p "$2" &>/dev/null || return 1 + + # Build an array of the indicies of the source array. + eval "keys=(\"\${!$2[@]}\")" + + # Read values indirectly via their index. This approach gives us support + # for associative arrays, sparse arrays, and empty strings as elements. + for i in "${keys[@]}"; do + values+=("printf -v '$dest[$i]' %s \"\${$src[$i]}\";") done + eval "${values[*]}" +} + +funcgrep() { + { declare -f "$1" || declare -f package; } 2>/dev/null | grep -E "$2" +} + +extract_global_var() { + # $1: variable name + # $2: multivalued + # $3: name of output var + + local attr=$1 isarray=$2 outputvar=$3 + + if (( isarray )); then + array_build ref "$attr" + [[ ${ref[@]} ]] && array_build "$outputvar" "$attr" + else + [[ -v $attr ]] && printf -v "$outputvar" %s "${!attr}" + fi +} + +extract_function_var() { + # $1: function name + # $2: variable name + # $3: multivalued + # $4: name of output var + + local funcname=$1 attr=$2 isarray=$3 outputvar=$4 attr_regex= decl= r=1 + + if (( isarray )); then + printf -v attr_regex '^[[:space:]]*(declare( -[[:alpha:]])*)? %q\+?=\(' "$2" + else + printf -v attr_regex '^[[:space:]]*(declare( -[[:alpha:]])*)? %q\+?=[^(]' "$2" + fi + + while read -r; do + # strip leading whitespace and any usage of declare + decl=${REPLY##*([[:space:]])?(declare +(-+([[:alpha:]]) ))} + eval "${decl/#$attr/$outputvar}" + + # entering this loop at all means we found a match, so notify the caller. + r=0 + done < <(funcgrep "$funcname" "$attr_regex") + + return $r +} + +pkgbuild_get_attribute() { + # $1: package name + # $2: attribute name + # $3: name of output var + # $4: multivalued + + local pkgname=$1 attrname=$2 outputvar=$3 isarray=$4 + + printf -v "$outputvar" %s '' + + if [[ $pkgname ]]; then + extract_global_var "$attrname" "$isarray" "$outputvar" + extract_function_var "package_$pkgname" "$attrname" "$isarray" "$outputvar" + else + extract_global_var "$attrname" "$isarray" "$outputvar" + fi +} + +lint_pkgbase() { + if [[ ${pkgbase:0:1} = "-" ]]; then + error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname" + return 1 + fi +} + +lint_pkgname() { + local ret=0 i + for i in "${pkgname[@]}"; do + if [[ -z $i ]]; then + error "$(gettext "%s is not allowed to be empty.")" "pkgname" + ret=1 + continue + fi if [[ ${i:0:1} = "-" ]]; then error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname" ret=1 @@ -2212,155 +2297,262 @@ check_sanity() { fi if [[ $i = *[^[:alnum:]+_.@-]* ]]; then error "$(gettext "%s contains invalid characters: '%s'")" \ - 'pkgname' "${pkgname//[[:alnum:]+_.@-]}" + 'pkgname' "${i//[[:alnum:]+_.@-]}" ret=1 fi done - if [[ ${pkgbase:0:1} = "-" ]]; then - error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgbase" - ret=1 + return $ret +} + +lint_pkgrel() { + if [[ -z $pkgrel ]]; then + error "$(gettext "%s is not allowed to be empty.")" "pkgrel" + return 1 fi - if (( ! PKGVERFUNC )) ; then - check_pkgver || ret=1 + if [[ $pkgrel != +([0-9])?(.+([0-9])) ]]; then + error "$(gettext "%s must be a decimal, not %s.")" "pkgrel" "$pkgrel" + return 1 fi +} - awk -F'=' '$1 ~ /^[[:space:]]*pkgrel$/' "$BUILDFILE" | sed "s/[[:space:]]*#.*//" | - while IFS='=' read -r _ i; do - eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\" - if [[ $i != +([0-9])?(.+([0-9])) ]]; then - error "$(gettext "%s must be a decimal.")" "pkgrel" - return 1 - fi - done || ret=1 +lint_pkgver() { + if (( PKGVERFUNC )); then + # defer check to after getting version from pkgver function + return 0 + fi - awk -F'=' '$1 ~ /^[[:space:]]*epoch$/' "$BUILDFILE" | - while IFS='=' read -r _ i; do - eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\" - if [[ $i != *([[:digit:]]) ]]; then - error "$(gettext "%s must be an integer.")" "epoch" - return 1 - fi - done || ret=1 + check_pkgver +} + +lint_epoch() { + if [[ $epoch != *([[:digit:]]) ]]; then + error "$(gettext "%s must be an integer, not %s.")" "epoch" "$epoch" + return 1 + fi +} - if [[ $arch != 'any' ]]; then - if ! in_array $CARCH "${arch[@]}"; then +lint_arch() { + local name list=("${@:-"${arch[@]}"}") + + if [[ $list == 'any' ]]; then + return 0 + fi + + if ! in_array "$CARCH" "${list[@]}" && (( ! IGNOREARCH )); then + 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 %s.")" "arch=('$CARCH')" + return 1 + fi + + for name in "${pkgname[@]}"; do + pkgbuild_get_attribute "$name" 'arch' list 1 + if [[ $list && $list != 'any' ]] && ! in_array $CARCH "${list[@]}"; then if (( ! IGNOREARCH )); then - 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 %s.")" "arch=('$CARCH')" + error "$(gettext "%s is not available for the '%s' architecture.")" "$name" "$CARCH" ret=1 fi fi - fi + done +} - if (( ${#pkgname[@]} > 1 )); then - for i in ${pkgname[@]}; do - local arch_list="" - eval $(declare -f package_${i} | sed -n 's/\(^[[:space:]]*arch=\)/arch_list=/p') - if [[ ${arch_list[@]} && ${arch_list} != 'any' ]]; then - if ! in_array $CARCH "${arch_list[@]}"; then - if (( ! IGNOREARCH )); then - error "$(gettext "%s is not available for the '%s' architecture.")" "$i" "$CARCH" - ret=1 - fi - fi - fi - done - fi +lint_provides() { + local list name provides_list ret=0 + + provides_list=("${provides[@]}") + for name in "${pkgname[@]}"; do + if extract_function_var "package_$name" provides 1 list; then + provides_list+=("${list[@]}") + fi + done - local provides_list=() - eval $(awk '/^[[:space:]]*provides=/,/\)/' "$BUILDFILE" | \ - sed -e "s/provides=/provides_list+=/" -e "s/#.*//" -e 's/\\$//') - for i in ${provides_list[@]}; do - if [[ $i == *['<>']* ]]; then + for provide in "${provides_list[@]}"; do + if [[ $provide == *['<>']* ]]; then error "$(gettext "%s array cannot contain comparison (< or >) operators.")" "provides" ret=1 fi done - local backup_list=() - eval $(awk '/^[[:space:]]*backup=/,/\)/' "$BUILDFILE" | \ - sed -e "s/backup=/backup_list+=/" -e "s/#.*//" -e 's/\\$//') - for i in "${backup_list[@]}"; do - if [[ ${i:0:1} = "/" ]]; then - error "$(gettext "%s entry should not contain leading slash : %s")" "backup" "$i" + return $ret +} + +lint_backup() { + local list name backup_list ret=0 + + backup_list=("${backup[@]}") + for name in "${pkgname[@]}"; do + if extract_function_var "package_$name" backup 1 list; then + backup_list+=("${list[@]}") + fi + done + + for name in "${backup_list[@]}"; do + if [[ ${name:0:1} = "/" ]]; then + error "$(gettext "%s entry should not contain leading slash : %s")" "backup" "$name" ret=1 fi done - local optdepends_list=() - eval $(awk '/^[[:space:]]*optdepends=\(/,/\)[[:space:]]*(#.*)?$/' "$BUILDFILE" | \ - sed -e "s/optdepends=/optdepends_list+=/" -e "s/#.*//" -e 's/\\$//') - for i in "${optdepends_list[@]}"; do - local pkg=${i%%:[[:space:]]*} + return $ret +} + +lint_optdepends() { + local list name optdepends_list ret=0 + + optdepends_list=("${optdepends[@]}") + for name in "${pkgname[@]}"; do + if extract_function_var "package_$name" optdepends 1 list; then + optdepends_list+=("${list[@]}") + fi + done + + for name in "${optdepends_list[@]}"; do + local pkg=${name%%:[[:space:]]*} # the '-' character _must_ be first or last in the character range if [[ $pkg != +([-[:alnum:]><=.+_:]) ]]; then - error "$(gettext "Invalid syntax for %s : '%s'")" "optdepend" "$i" + error "$(gettext "Invalid syntax for %s: '%s'")" "optdepend" "$name" ret=1 fi done - for i in 'changelog' 'install'; do - local file - while read -r file; do - # evaluate any bash variables used - eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\" - if [[ $file && ! -f $file ]]; then - error "$(gettext "%s file (%s) does not exist.")" "$i" "$file" - ret=1 - fi - done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE") + return $ret +} + +check_files_exist() { + local kind=$1 files=("${@:2}") file ret + + for file in "${files[@]}"; do + if [[ $file && ! -f $file ]]; then + error "$(gettext "%s file (%s) does not exist or is not a regular file.")" \ + "$kind" "$file" + ret=1 + fi + done + + return $ret +} + +lint_install() { + local list file name install_list ret=0 + + install_list=("${install[@]}") + for name in "${pkgname[@]}"; do + extract_function_var "package_$name" install 0 file + install_list+=("$file") + done + + check_files_exist 'install' "${install_list[@]}" +} + +lint_changelog() { + local list name file changelog_list ret=0 + + changelog_list=("${changelog[@]}") + for name in "${pkgname[@]}"; do + if extract_function_var "package_$name" changelog 0 file; then + changelog_list+=("$file") + fi + done + + check_files_exist 'changelog' "${changelog_list[@]}" +} + +lint_options() { + local ret=0 list name kopt options_list + + options_list=("${options[@]}") + for name in "${pkgname[@]}"; do + if extract_function_var "package_$name" options 1 list; then + options_list+=("${list[@]}") + fi done - local valid_options=1 - local known kopt options_list - eval $(awk '/^[[:space:]]*options=/,/\)/' "$BUILDFILE" | \ - sed -e "s/options=/options_list+=/" -e "s/#.*//" -e 's/\\$//') - for i in ${options_list[@]}; do - known=0 + for i in "${options_list[@]}"; do # check if option matches a known option or its inverse - for kopt in ${packaging_options[@]} ${other_options[@]}; do - if [[ ${i} = "${kopt}" || ${i} = "!${kopt}" ]]; then - known=1 + for kopt in "${packaging_options[@]}" "${other_options[@]}"; do + if [[ $i = "$kopt" || $i = "!$kopt" ]]; then + # continue to the next $i + continue 2 fi done - if (( ! known )); then - error "$(gettext "%s array contains unknown option '%s'")" "options" "$i" - valid_options=0 - fi - done - if (( ! valid_options )); then + + error "$(gettext "%s array contains unknown option '%s'")" "options" "$i" ret=1 + done + + return $ret +} + +lint_source() { + local idx=("${!source[@]}") + + if (( ${#source[*]} > 0 && (idx[-1] + 1) != ${#source[*]} )); then + error "$(gettext "Sparse arrays are not allowed for source")" + return 1 fi +} + +lint_pkglist() { + local i ret=0 + + 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 $ret +} + +lint_packagefn() { + local i ret=0 if (( ${#pkgname[@]} == 1 )); then - if have_function build && ! ( have_function package || have_function package_${pkgname}); then + if have_function 'build' && ! { have_function 'package' || have_function "package_$pkgname"; }; then error "$(gettext "Missing %s function in %s")" "package()" "$BUILDFILE" ret=1 fi else - for i in ${pkgname[@]}; do - if ! have_function package_${i}; then + for i in "${pkgname[@]}"; do + if ! have_function "package_$i"; then error "$(gettext "Missing %s function for split package '%s'")" "package_$i()" "$i" ret=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 $ret +} - local idx=("${!source[@]}") - if (( ${#source[*]} > 0 && (idx[-1] + 1) != ${#source[*]} )); then - error "$(gettext "Sparse arrays are not allowed for source")" - ret=1 - fi +check_sanity() { + # check for no-no's in the build script + local ret=0 + local lintfn lint_functions + + lint_functions=( + lint_pkgbase + lint_pkgname + lint_pkgver + lint_pkgrel + lint_epoch + lint_arch + lint_provides + lint_backup + lint_optdepends + lint_changelog + lint_install + lint_options + lint_packagefn + lint_pkglist + lint_source + ) + + for lintfn in "${lint_functions[@]}"; do + "$lintfn" || ret=1 + done return $ret } -- 2.0.4
This introduces support for architecutre-specific conflicts, depends, optdepends, makedepends, replaces, and conflicts by appending "_$CARCH" to the array name. For example, in the global section: arch=('i686' 'x86_64') depends=('foo') depends_x86_64=('bar') This will generate depends of 'foo' and 'bar' on x86_64, but only 'foo' on i686. Moreover, this is supported in the package functions with the same heuristics as the generic names, e.g. ... arch=('i686' 'x86_64') depends=('foo') ... package_somepkg() { depends_x86_64=('bar') ... } Again, will cause x86_64 to have depends of 'foo' and 'bar', but only 'foo' for i686. --- doc/PKGBUILD.5.txt | 21 +++++++++++++++++++++ scripts/makepkg.sh.in | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/doc/PKGBUILD.5.txt b/doc/PKGBUILD.5.txt index 17e8af2..c957180 100644 --- a/doc/PKGBUILD.5.txt +++ b/doc/PKGBUILD.5.txt @@ -183,17 +183,26 @@ If the dependency name appears to be a library (ends with .so), makepkg will try to find a binary that depends on the library in the built package and append the version needed by the binary. Appending the version yourself disables automatic detection. ++ +Additional architecture-specific depends can be added by appending an +underscore and the architecture name e.g., 'depends_x86_64=()'. *makedepends (array)*:: An array of packages this package depends on to build but are not needed at runtime. Packages in this list follow the same format as depends. ++ +Additional architecture-specific makedepends can be added by appending an +underscore and the architecture name e.g., 'makedepends_x86_64=()'. *checkdepends (array)*:: An array of packages this package depends on to run its test suite but are not needed at runtime. Packages in this list follow the same format as depends. These dependencies are only considered when the check() function is present and is to be run by makepkg. ++ +Additional architecture-specific checkdepends can be added by appending an +underscore and the architecture name e.g., 'checkdepends_x86_64=()'. *optdepends (array)*:: An array of packages (and accompanying reasons) that are not essential for @@ -203,12 +212,18 @@ disables automatic detection. for specifying optdepends is: optdepends=('fakeroot: for makepkg usage as normal user') ++ +Architecture-specific optdepends can be added by appending an underscore and +the architecture name e.g., 'optdepends_x86_64=()'. *conflicts (array)*:: An array of packages that will conflict with this package (i.e. they cannot both be installed at the same time). This directive follows the same format as depends. Versioned conflicts are supported using the operators as described in `depends`. ++ +Additional architecture-specific conflicts can be added by appending an +underscore and the architecture name e.g., 'conflicts_x86_64=()'. *provides (array)*:: An array of ``virtual provisions'' this package provides. This allows @@ -224,6 +239,9 @@ only specific versions of a package may be provided. If the provision name appears to be a library (ends with .so), makepkg will try to find the library in the built package and append the correct version. Appending the version yourself disables automatic detection. ++ +Additional architecture-specific provides can be added by appending an +underscore and the architecture name e.g., 'provides_x86_64=()'. *replaces (array)*:: An array of packages this package should replace. This can be used @@ -234,6 +252,9 @@ version. Appending the version yourself disables automatic detection. + Sysupgrade is currently the only pacman operation that utilizes this field. A normal sync or upgrade will not use its value. ++ +Additional architecture-specific replaces can be added by appending an +underscore and the architecture name e.g., 'replaces_x86_64=()'. *options (array)*:: This array allows you to override some of makepkg's default behavior diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index e8cf60c..a4f4494 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -1475,6 +1475,24 @@ source_safe() { shopt -s extglob } +merge_arch_attrs() { + local attr supported_attrs=( + provides conflicts depends replaces optdepends + makedepends checkdepends) + + for attr in "${supported_attrs[@]}"; do + eval "$attr+=(\"\${${attr}_$CARCH[@]}\")" + done + + # ensure that calling this function is idempotent. + unset -v "${supported_attrs[@]/%/_$CARCH}" +} + +source_buildfile() { + source_safe "$@" + merge_arch_attrs +} + run_function_safe() { local restoretrap @@ -1893,6 +1911,8 @@ write_pkginfo() { local size="$(@DUPATH@ @DUFLAGS@)" size="$(( ${size%%[^0-9]*} * 1024 ))" + merge_arch_attrs + msg2 "$(gettext "Generating %s file...")" ".PKGINFO" printf "# Generated by makepkg %s\n" "$makepkg_version" printf "# using %s\n" "$(fakeroot -v)" @@ -2359,13 +2379,24 @@ lint_arch() { } lint_provides() { - local list name provides_list ret=0 + local a list name provides_list ret=0 provides_list=("${provides[@]}") + for a in "${arch[@]}"; do + array_build list "provides_$a" + provides_list+=("${list[@]}") + done + for name in "${pkgname[@]}"; do if extract_function_var "package_$name" provides 1 list; then provides_list+=("${list[@]}") fi + + for a in "${arch[@]}"; do + if extract_function_var "package_$name" "provides_$a" 1 list; then + provides_list+=("${list[@]}") + fi + done done for provide in "${provides_list[@]}"; do @@ -2399,13 +2430,24 @@ lint_backup() { } lint_optdepends() { - local list name optdepends_list ret=0 + local a list name optdepends_list ret=0 optdepends_list=("${optdepends[@]}") + for a in "${arch[@]}"; do + array_build list "optdepends_$a" + optdepends_list+=("${list[@]}") + done + for name in "${pkgname[@]}"; do if extract_function_var "package_$name" optdepends 1 list; then optdepends_list+=("${list[@]}") fi + + for a in "${arch[@]}"; do + if extract_function_var "package_$name" "optdepends_$a" 1 list; then + optdepends_list+=("${list[@]}") + fi + done done for name in "${optdepends_list[@]}"; do @@ -3091,7 +3133,7 @@ else if [[ ${BUILDFILE:0:1} != "/" ]]; then BUILDFILE="$startdir/$BUILDFILE" fi - source_safe "$BUILDFILE" + source_buildfile "$BUILDFILE" fi # set defaults if they weren't specified in buildfile -- 2.0.4
--- scripts/makepkg.sh.in | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index a4f4494..34ffb25 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -866,7 +866,7 @@ get_pkg_arch() { fi else local arch_override - eval $(declare -f package_$1 | sed -n 's/\(^[[:space:]]*arch=\)/arch_override=/p') + pkgbuild_get_attribute "$1" arch arch_override 0 (( ${#arch_override[@]} == 0 )) && arch_override=("${arch[@]}") if [[ $arch_override = "any" ]]; then printf "%s\n" "any" @@ -2121,15 +2121,21 @@ create_srcpackage() { local i for i in 'changelog' 'install'; do - local file - while read -r file; do - # evaluate any bash variables used - eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\" + local file files + + [[ $install ]] && files+=("$install") + for name in "${pkgname[@]}"; do + if extract_function_var "package_$name" "$i" 0 file; then + files+=("$file") + fi + done + + for file in "${files[@]}"; do if [[ $file && ! -f "${srclinks}/${pkgbase}/$file" ]]; then msg2 "$(gettext "Adding %s file (%s)...")" "$i" "${file}" ln -s "${startdir}/$file" "${srclinks}/${pkgbase}/" fi - done < <(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE") + done done local TAR_OPT -- 2.0.4
Aside from the hack at the foot of the script, this commit introduces no logical changes or new code. Any globally scoped declaration or code are moved into a 'makepkg_main' function which is called when the script is executed (not sourced). Doing this allows other scripts to source makepkg for its juicy functions, and also makes these functions more easily unit testable. This commit explicitly does NOT attempt to define an API or any other stability guarantees of any kind. --- scripts/makepkg.sh.in | 985 +++++++++++++++++++++++++------------------------- 1 file changed, 496 insertions(+), 489 deletions(-) diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index 34ffb25..4b23a5b 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -30,72 +30,6 @@ # awk, bsdtar (libarchive), bzip2, coreutils, fakeroot, file, find (findutils), # gettext, gpg, grep, gzip, openssl, sed, tput (ncurses), xz -# gettext initialization -export TEXTDOMAIN='pacman-scripts' -export TEXTDOMAINDIR='@localedir@' - -# file -i does not work on Mac OSX unless legacy mode is set -export COMMAND_MODE='legacy' -# Ensure CDPATH doesn't screw with our cd calls -unset CDPATH -# Ensure GREP_OPTIONS doesn't screw with our grep calls -unset GREP_OPTIONS - -declare -r makepkg_version='@PACKAGE_VERSION@' -declare -r confdir='@sysconfdir@' -declare -r BUILDSCRIPT='@BUILDSCRIPT@' -declare -r startdir="$PWD" - -LIBRARY=${LIBRARY:-'@libmakepkgdir@'} - -packaging_options=('strip' 'docs' 'libtool' 'staticlibs' 'emptydirs' 'zipman' - 'purge' 'upx' 'debug') -other_options=('ccache' 'distcc' 'buildflags' 'makeflags') -splitpkg_overrides=('pkgdesc' 'arch' 'url' 'license' 'groups' 'depends' - 'optdepends' 'provides' 'conflicts' 'replaces' 'backup' - 'options' 'install' 'changelog') -readonly -a packaging_options other_options splitpkg_overrides - -known_hash_algos=('md5' 'sha1' 'sha224' 'sha256' 'sha384' 'sha512') - -# Options -ASDEPS=0 -BUILDFUNC=0 -CHECKFUNC=0 -CLEANBUILD=0 -CLEANUP=0 -DEP_BIN=0 -FORCE=0 -GENINTEG=0 -HOLDVER=0 -IGNOREARCH=0 -INFAKEROOT=0 -INSTALL=0 -LOGGING=0 -NEEDED=0 -NOARCHIVE=0 -NOBUILD=0 -NODEPS=0 -NOEXTRACT=0 -PKGFUNC=0 -PKGLIST=() -PKGVERFUNC=0 -PREPAREFUNC=0 -REPKG=0 -RMDEPS=0 -SKIPCHECKSUMS=0 -SKIPPGPCHECK=0 -SIGNPKG='' -SPLITPKG=0 -SOURCEONLY=0 -VERIFYSOURCE=0 - -# Forces the pkgver of the current PKGBUILD. Used by the fakeroot call -# when dealing with svn/cvs/etc PKGBUILDs. -FORCE_VER="" - -PACMAN_OPTS= - shopt -s extglob ### SUBROUTINES ### @@ -2883,499 +2817,572 @@ This is free software; see the source for copying conditions.\n\ There is NO WARRANTY, to the extent permitted by law.\n")" } -# PROGRAM START - -# ensure we have a sane umask set -umask 0022 - -# determine whether we have gettext; make it a no-op if we do not -if ! type -p gettext >/dev/null; then - gettext() { - printf "%s\n" "$@" - } -fi +makepkg_main() { + # gettext initialization + export TEXTDOMAIN='pacman-scripts' + export TEXTDOMAINDIR='@localedir@' + + # file -i does not work on Mac OSX unless legacy mode is set + export COMMAND_MODE='legacy' + # Ensure CDPATH doesn't screw with our cd calls + unset CDPATH + # Ensure GREP_OPTIONS doesn't screw with our grep calls + unset GREP_OPTIONS + + declare -r makepkg_version='@PACKAGE_VERSION@' + declare -r confdir='@sysconfdir@' + declare -r BUILDSCRIPT='@BUILDSCRIPT@' + declare -r startdir="$PWD" + + LIBRARY=${LIBRARY:-'@libmakepkgdir@'} + + packaging_options=('strip' 'docs' 'libtool' 'staticlibs' 'emptydirs' 'zipman' + 'purge' 'upx' 'debug') + other_options=('ccache' 'distcc' 'buildflags' 'makeflags') + splitpkg_overrides=('pkgdesc' 'arch' 'url' 'license' 'groups' 'depends' + 'optdepends' 'provides' 'conflicts' 'replaces' 'backup' + 'options' 'install' 'changelog') + readonly -a packaging_options other_options splitpkg_overrides + + known_hash_algos=('md5' 'sha1' 'sha224' 'sha256' 'sha384' 'sha512') + + # Options + ASDEPS=0 + BUILDFUNC=0 + CHECKFUNC=0 + CLEANBUILD=0 + CLEANUP=0 + DEP_BIN=0 + FORCE=0 + GENINTEG=0 + HOLDVER=0 + IGNOREARCH=0 + INFAKEROOT=0 + INSTALL=0 + LOGGING=0 + NEEDED=0 + NOARCHIVE=0 + NOBUILD=0 + NODEPS=0 + NOEXTRACT=0 + PKGFUNC=0 + PKGLIST=() + PKGVERFUNC=0 + PREPAREFUNC=0 + REPKG=0 + RMDEPS=0 + SKIPCHECKSUMS=0 + SKIPPGPCHECK=0 + SIGNPKG='' + SPLITPKG=0 + SOURCEONLY=0 + VERIFYSOURCE=0 + + # Forces the pkgver of the current PKGBUILD. Used by the fakeroot call + # when dealing with svn/cvs/etc PKGBUILDs. + FORCE_VER="" + + PACMAN_OPTS= + + # ensure we have a sane umask set + umask 0022 + + # determine whether we have gettext; make it a no-op if we do not + if ! type -p gettext >/dev/null; then + gettext() { + printf "%s\n" "$@" + } + fi + + ARGLIST=("$@") + + # Parse Command Line Options. + OPT_SHORT="AcCdefFghiLmop:rRsSV" + OPT_LONG=('allsource' 'check' 'clean' 'cleanbuild' 'config:' 'force' 'geninteg' + 'help' 'holdver' 'ignorearch' 'install' 'key:' 'log' 'noarchive' 'nobuild' + 'nocolor' 'nocheck' 'nodeps' 'noextract' 'noprepare' 'nosign' 'pkg:' 'repackage' + 'rmdeps' 'sign' 'skipchecksums' 'skipinteg' 'skippgpcheck' 'source' 'syncdeps' + 'verifysource' 'version') + + # Pacman Options + OPT_LONG+=('asdeps' 'noconfirm' 'needed' 'noprogressbar') + + if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then + exit 1 # E_INVALID_OPTION; + fi + set -- "${OPTRET[@]}" + unset OPT_SHORT OPT_LONG OPTRET + + while true; do + case "$1" in + # Pacman Options + --asdeps) ASDEPS=1;; + --needed) NEEDED=1;; + --noconfirm) PACMAN_OPTS+=" --noconfirm" ;; + --noprogressbar) PACMAN_OPTS+=" --noprogressbar" ;; + + # Makepkg Options + --allsource) SOURCEONLY=2 ;; + -A|--ignorearch) IGNOREARCH=1 ;; + -c|--clean) CLEANUP=1 ;; + -C|--cleanbuild) CLEANBUILD=1 ;; + --check) RUN_CHECK='y' ;; + --config) shift; MAKEPKG_CONF=$1 ;; + -d|--nodeps) NODEPS=1 ;; + -e|--noextract) NOEXTRACT=1 ;; + -f|--force) FORCE=1 ;; + -F) INFAKEROOT=1 ;; + -g|--geninteg) GENINTEG=1 ;; + --holdver) HOLDVER=1 ;; + -i|--install) INSTALL=1 ;; + --key) shift; GPGKEY=$1 ;; + -L|--log) LOGGING=1 ;; + -m|--nocolor) USE_COLOR='n'; PACMAN_OPTS+=" --color never" ;; + --noarchive) NOARCHIVE=1 ;; + --nocheck) RUN_CHECK='n' ;; + --noprepare) RUN_PREPARE='n' ;; + --nosign) SIGNPKG='n' ;; + -o|--nobuild) NOBUILD=1 ;; + -p) shift; BUILDFILE=$1 ;; + --pkg) shift; IFS=, read -ra p <<<"$1"; PKGLIST+=("${p[@]}"); unset p ;; + -r|--rmdeps) RMDEPS=1 ;; + -R|--repackage) REPKG=1 ;; + --sign) SIGNPKG='y' ;; + --skipchecksums) SKIPCHECKSUMS=1 ;; + --skipinteg) SKIPCHECKSUMS=1; SKIPPGPCHECK=1 ;; + --skippgpcheck) SKIPPGPCHECK=1;; + -s|--syncdeps) DEP_BIN=1 ;; + -S|--source) SOURCEONLY=1 ;; + --verifysource) VERIFYSOURCE=1 ;; + + -h|--help) usage; exit 0 ;; # E_OK + -V|--version) version; exit 0 ;; # E_OK + + --) OPT_IND=0; shift; break 2;; + esac + shift + done -ARGLIST=("$@") + # attempt to consume any extra argv as environment variables. this supports + # overriding (e.g. CC=clang) as well as overriding (e.g. CFLAGS+=' -g'). + extra_environment=() + while [[ $1 ]]; do + if [[ $1 = [_[:alpha:]]*([[:alnum:]_])?(+)=* ]]; then + extra_environment+=("$1") + fi + shift + done -# Parse Command Line Options. -OPT_SHORT="AcCdefFghiLmop:rRsSV" -OPT_LONG=('allsource' 'check' 'clean' 'cleanbuild' 'config:' 'force' 'geninteg' - 'help' 'holdver' 'ignorearch' 'install' 'key:' 'log' 'noarchive' 'nobuild' - 'nocolor' 'nocheck' 'nodeps' 'noextract' 'noprepare' 'nosign' 'pkg:' 'repackage' - 'rmdeps' 'sign' 'skipchecksums' 'skipinteg' 'skippgpcheck' 'source' 'syncdeps' - 'verifysource' 'version') + # setup signal traps + trap 'clean_up' 0 + for signal in TERM HUP QUIT; do + trap "trap_exit $signal \"$(gettext "%s signal caught. Exiting...")\" \"$signal\"" "$signal" + done + trap 'trap_exit INT "$(gettext "Aborted by user! Exiting...")"' INT + trap 'trap_exit USR1 "$(gettext "An unknown error has occurred. Exiting...")"' ERR + + # preserve environment variables and canonicalize path + [[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST}) + [[ -n ${SRCDEST} ]] && _SRCDEST=$(canonicalize_path ${SRCDEST}) + [[ -n ${SRCPKGDEST} ]] && _SRCPKGDEST=$(canonicalize_path ${SRCPKGDEST}) + [[ -n ${LOGDEST} ]] && _LOGDEST=$(canonicalize_path ${LOGDEST}) + [[ -n ${BUILDDIR} ]] && _BUILDDIR=$(canonicalize_path ${BUILDDIR}) + [[ -n ${PKGEXT} ]] && _PKGEXT=${PKGEXT} + [[ -n ${SRCEXT} ]] && _SRCEXT=${SRCEXT} + [[ -n ${GPGKEY} ]] && _GPGKEY=${GPGKEY} + [[ -n ${PACKAGER} ]] && _PACKAGER=${PACKAGER} + [[ -n ${CARCH} ]] && _CARCH=${CARCH} + + # default config is makepkg.conf + MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf} + + # Source the config file; fail if it is not found + if [[ -r $MAKEPKG_CONF ]]; then + source_safe "$MAKEPKG_CONF" + else + error "$(gettext "%s not found.")" "$MAKEPKG_CONF" + plain "$(gettext "Aborting...")" + exit 1 # $E_CONFIG_ERROR + fi -# Pacman Options -OPT_LONG+=('asdeps' 'noconfirm' 'needed' 'noprogressbar') + # Source user-specific makepkg.conf overrides, but only if no override config + # file was specified + XDG_PACMAN_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/pacman" + if [[ "$MAKEPKG_CONF" = "$confdir/makepkg.conf" ]]; then + if [[ -r "$XDG_PACMAN_DIR/makepkg.conf" ]]; then + source_safe "$XDG_PACMAN_DIR/makepkg.conf" + elif [[ -r "$HOME/.makepkg.conf" ]]; then + source_safe "$HOME/.makepkg.conf" + fi + fi + + # set pacman command if not already defined + PACMAN=${PACMAN:-pacman} + # save full path to command as PATH may change when sourcing /etc/profile + PACMAN_PATH=$(type -P $PACMAN) + + # check if messages are to be printed using color + unset ALL_OFF BOLD BLUE GREEN RED YELLOW + if [[ -t 2 && ! $USE_COLOR = "n" ]] && check_buildenv "color" "y"; then + # prefer terminal safe colored and bold text when tput is supported + if tput setaf 0 &>/dev/null; then + ALL_OFF="$(tput sgr0)" + BOLD="$(tput bold)" + BLUE="${BOLD}$(tput setaf 4)" + GREEN="${BOLD}$(tput setaf 2)" + RED="${BOLD}$(tput setaf 1)" + YELLOW="${BOLD}$(tput setaf 3)" + else + ALL_OFF="\e[0m" + BOLD="\e[1m" + BLUE="${BOLD}\e[34m" + GREEN="${BOLD}\e[32m" + RED="${BOLD}\e[31m" + YELLOW="${BOLD}\e[33m" + fi + fi + readonly ALL_OFF BOLD BLUE GREEN RED YELLOW + + # override settings with an environment variable for batch processing + BUILDDIR=${_BUILDDIR:-$BUILDDIR} + BUILDDIR=${BUILDDIR:-$startdir} #default to $startdir if undefined + if [[ ! -d $BUILDDIR ]]; then + if ! mkdir -p "$BUILDDIR"; then + error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR" + plain "$(gettext "Aborting...")" + exit 1 + fi + chmod a-s "$BUILDDIR" + fi + if [[ ! -w $BUILDDIR ]]; then + error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR" + plain "$(gettext "Aborting...")" + exit 1 + fi -if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then - exit 1 # E_INVALID_OPTION; -fi -set -- "${OPTRET[@]}" -unset OPT_SHORT OPT_LONG OPTRET - -while true; do - case "$1" in - # Pacman Options - --asdeps) ASDEPS=1;; - --needed) NEEDED=1;; - --noconfirm) PACMAN_OPTS+=" --noconfirm" ;; - --noprogressbar) PACMAN_OPTS+=" --noprogressbar" ;; - - # Makepkg Options - --allsource) SOURCEONLY=2 ;; - -A|--ignorearch) IGNOREARCH=1 ;; - -c|--clean) CLEANUP=1 ;; - -C|--cleanbuild) CLEANBUILD=1 ;; - --check) RUN_CHECK='y' ;; - --config) shift; MAKEPKG_CONF=$1 ;; - -d|--nodeps) NODEPS=1 ;; - -e|--noextract) NOEXTRACT=1 ;; - -f|--force) FORCE=1 ;; - -F) INFAKEROOT=1 ;; - -g|--geninteg) GENINTEG=1 ;; - --holdver) HOLDVER=1 ;; - -i|--install) INSTALL=1 ;; - --key) shift; GPGKEY=$1 ;; - -L|--log) LOGGING=1 ;; - -m|--nocolor) USE_COLOR='n'; PACMAN_OPTS+=" --color never" ;; - --noarchive) NOARCHIVE=1 ;; - --nocheck) RUN_CHECK='n' ;; - --noprepare) RUN_PREPARE='n' ;; - --nosign) SIGNPKG='n' ;; - -o|--nobuild) NOBUILD=1 ;; - -p) shift; BUILDFILE=$1 ;; - --pkg) shift; IFS=, read -ra p <<<"$1"; PKGLIST+=("${p[@]}"); unset p ;; - -r|--rmdeps) RMDEPS=1 ;; - -R|--repackage) REPKG=1 ;; - --sign) SIGNPKG='y' ;; - --skipchecksums) SKIPCHECKSUMS=1 ;; - --skipinteg) SKIPCHECKSUMS=1; SKIPPGPCHECK=1 ;; - --skippgpcheck) SKIPPGPCHECK=1;; - -s|--syncdeps) DEP_BIN=1 ;; - -S|--source) SOURCEONLY=1 ;; - --verifysource) VERIFYSOURCE=1 ;; - - -h|--help) usage; exit 0 ;; # E_OK - -V|--version) version; exit 0 ;; # E_OK - - --) OPT_IND=0; shift; break 2;; - esac - shift -done - -# attempt to consume any extra argv as environment variables. this supports -# overriding (e.g. CC=clang) as well as overriding (e.g. CFLAGS+=' -g'). -extra_environment=() -while [[ $1 ]]; do - if [[ $1 = [_[:alpha:]]*([[:alnum:]_])?(+)=* ]]; then - extra_environment+=("$1") - fi - shift -done - -# setup signal traps -trap 'clean_up' 0 -for signal in TERM HUP QUIT; do - trap "trap_exit $signal \"$(gettext "%s signal caught. Exiting...")\" \"$signal\"" "$signal" -done -trap 'trap_exit INT "$(gettext "Aborted by user! Exiting...")"' INT -trap 'trap_exit USR1 "$(gettext "An unknown error has occurred. Exiting...")"' ERR - -# preserve environment variables and canonicalize path -[[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST}) -[[ -n ${SRCDEST} ]] && _SRCDEST=$(canonicalize_path ${SRCDEST}) -[[ -n ${SRCPKGDEST} ]] && _SRCPKGDEST=$(canonicalize_path ${SRCPKGDEST}) -[[ -n ${LOGDEST} ]] && _LOGDEST=$(canonicalize_path ${LOGDEST}) -[[ -n ${BUILDDIR} ]] && _BUILDDIR=$(canonicalize_path ${BUILDDIR}) -[[ -n ${PKGEXT} ]] && _PKGEXT=${PKGEXT} -[[ -n ${SRCEXT} ]] && _SRCEXT=${SRCEXT} -[[ -n ${GPGKEY} ]] && _GPGKEY=${GPGKEY} -[[ -n ${PACKAGER} ]] && _PACKAGER=${PACKAGER} -[[ -n ${CARCH} ]] && _CARCH=${CARCH} - -# default config is makepkg.conf -MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf} - -# Source the config file; fail if it is not found -if [[ -r $MAKEPKG_CONF ]]; then - source_safe "$MAKEPKG_CONF" -else - error "$(gettext "%s not found.")" "$MAKEPKG_CONF" - plain "$(gettext "Aborting...")" - exit 1 # $E_CONFIG_ERROR -fi + # override settings from extra variables on commandline, if any + if (( ${#extra_environment[*]} )); then + export "${extra_environment[@]}" + fi -# Source user-specific makepkg.conf overrides, but only if no override config -# file was specified -XDG_PACMAN_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/pacman" -if [[ "$MAKEPKG_CONF" = "$confdir/makepkg.conf" ]]; then - if [[ -r "$XDG_PACMAN_DIR/makepkg.conf" ]]; then - source_safe "$XDG_PACMAN_DIR/makepkg.conf" - elif [[ -r "$HOME/.makepkg.conf" ]]; then - source_safe "$HOME/.makepkg.conf" + PKGDEST=${_PKGDEST:-$PKGDEST} + PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined + if (( ! (NOBUILD || GENINTEG) )) && [[ ! -w $PKGDEST ]]; then + error "$(gettext "You do not have write permission to store packages in %s.")" "$PKGDEST" + plain "$(gettext "Aborting...")" + exit 1 fi -fi -# set pacman command if not already defined -PACMAN=${PACMAN:-pacman} -# save full path to command as PATH may change when sourcing /etc/profile -PACMAN_PATH=$(type -P $PACMAN) - -# check if messages are to be printed using color -unset ALL_OFF BOLD BLUE GREEN RED YELLOW -if [[ -t 2 && ! $USE_COLOR = "n" ]] && check_buildenv "color" "y"; then - # prefer terminal safe colored and bold text when tput is supported - if tput setaf 0 &>/dev/null; then - ALL_OFF="$(tput sgr0)" - BOLD="$(tput bold)" - BLUE="${BOLD}$(tput setaf 4)" - GREEN="${BOLD}$(tput setaf 2)" - RED="${BOLD}$(tput setaf 1)" - YELLOW="${BOLD}$(tput setaf 3)" - else - ALL_OFF="\e[0m" - BOLD="\e[1m" - BLUE="${BOLD}\e[34m" - GREEN="${BOLD}\e[32m" - RED="${BOLD}\e[31m" - YELLOW="${BOLD}\e[33m" + SRCDEST=${_SRCDEST:-$SRCDEST} + SRCDEST=${SRCDEST:-$startdir} #default to $startdir if undefined + if [[ ! -w $SRCDEST ]] ; then + error "$(gettext "You do not have write permission to store downloads in %s.")" "$SRCDEST" + plain "$(gettext "Aborting...")" + exit 1 fi -fi -readonly ALL_OFF BOLD BLUE GREEN RED YELLOW -# override settings with an environment variable for batch processing -BUILDDIR=${_BUILDDIR:-$BUILDDIR} -BUILDDIR=${BUILDDIR:-$startdir} #default to $startdir if undefined -if [[ ! -d $BUILDDIR ]]; then - if ! mkdir -p "$BUILDDIR"; then - error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR" + SRCPKGDEST=${_SRCPKGDEST:-$SRCPKGDEST} + SRCPKGDEST=${SRCPKGDEST:-$startdir} #default to $startdir if undefined + if (( SOURCEONLY )) && [[ ! -w $SRCPKGDEST ]]; then + error "$(gettext "You do not have write permission to store source tarballs in %s.")" "$SRCPKGDEST" plain "$(gettext "Aborting...")" exit 1 fi - chmod a-s "$BUILDDIR" -fi -if [[ ! -w $BUILDDIR ]]; then - error "$(gettext "You do not have write permission to create packages in %s.")" "$BUILDDIR" - plain "$(gettext "Aborting...")" - exit 1 -fi -# override settings from extra variables on commandline, if any -if (( ${#extra_environment[*]} )); then - export "${extra_environment[@]}" -fi + LOGDEST=${_LOGDEST:-$LOGDEST} + LOGDEST=${LOGDEST:-$startdir} #default to $startdir if undefined + if (( LOGGING )) && [[ ! -w $LOGDEST ]]; then + error "$(gettext "You do not have write permission to store logs in %s.")" "$LOGDEST" + plain "$(gettext "Aborting...")" + exit 1 + fi -PKGDEST=${_PKGDEST:-$PKGDEST} -PKGDEST=${PKGDEST:-$startdir} #default to $startdir if undefined -if (( ! (NOBUILD || GENINTEG) )) && [[ ! -w $PKGDEST ]]; then - error "$(gettext "You do not have write permission to store packages in %s.")" "$PKGDEST" - plain "$(gettext "Aborting...")" - exit 1 -fi + PKGEXT=${_PKGEXT:-$PKGEXT} + SRCEXT=${_SRCEXT:-$SRCEXT} + GPGKEY=${_GPGKEY:-$GPGKEY} + PACKAGER=${_PACKAGER:-$PACKAGER} + CARCH=${_CARCH:-$CARCH} -SRCDEST=${_SRCDEST:-$SRCDEST} -SRCDEST=${SRCDEST:-$startdir} #default to $startdir if undefined -if [[ ! -w $SRCDEST ]] ; then - error "$(gettext "You do not have write permission to store downloads in %s.")" "$SRCDEST" - plain "$(gettext "Aborting...")" - exit 1 -fi + if (( ! INFAKEROOT )); then + if (( EUID == 0 )); then + error "$(gettext "Running %s as root is not allowed as it can cause permanent,\n\ + catastrophic damage to your system.")" + exit 1 # $E_USER_ABORT + fi + else + if [[ -z $FAKEROOTKEY ]]; then + error "$(gettext "Do not use the %s option. This option is only for use by %s.")" "'-F'" "makepkg" + exit 1 # TODO: error code + fi + fi -SRCPKGDEST=${_SRCPKGDEST:-$SRCPKGDEST} -SRCPKGDEST=${SRCPKGDEST:-$startdir} #default to $startdir if undefined -if (( SOURCEONLY )) && [[ ! -w $SRCPKGDEST ]]; then - error "$(gettext "You do not have write permission to store source tarballs in %s.")" "$SRCPKGDEST" - plain "$(gettext "Aborting...")" - exit 1 -fi + 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 validpgpkeys -LOGDEST=${_LOGDEST:-$LOGDEST} -LOGDEST=${LOGDEST:-$startdir} #default to $startdir if undefined -if (( LOGGING )) && [[ ! -w $LOGDEST ]]; then - error "$(gettext "You do not have write permission to store logs in %s.")" "$LOGDEST" - plain "$(gettext "Aborting...")" - exit 1 -fi + BUILDFILE=${BUILDFILE:-$BUILDSCRIPT} + if [[ ! -f $BUILDFILE ]]; then + error "$(gettext "%s does not exist.")" "$BUILDFILE" + exit 1 + else + if [[ $(<"$BUILDFILE") = *$'\r'* ]]; then + error "$(gettext "%s contains %s characters and cannot be sourced.")" "$BUILDFILE" "CRLF" + exit 1 + fi -PKGEXT=${_PKGEXT:-$PKGEXT} -SRCEXT=${_SRCEXT:-$SRCEXT} -GPGKEY=${_GPGKEY:-$GPGKEY} -PACKAGER=${_PACKAGER:-$PACKAGER} -CARCH=${_CARCH:-$CARCH} + if [[ ! $BUILDFILE -ef $PWD/${BUILDFILE##*/} ]]; then + error "$(gettext "%s must be in the current working directory.")" "$BUILDFILE" + exit 1 + fi -if (( ! INFAKEROOT )); then - if (( EUID == 0 )); then - error "$(gettext "Running %s as root is not allowed as it can cause permanent,\n\ -catastrophic damage to your system.")" - exit 1 # $E_USER_ABORT - fi -else - if [[ -z $FAKEROOTKEY ]]; then - error "$(gettext "Do not use the %s option. This option is only for use by %s.")" "'-F'" "makepkg" - exit 1 # TODO: error code + if [[ ${BUILDFILE:0:1} != "/" ]]; then + BUILDFILE="$startdir/$BUILDFILE" + fi + source_buildfile "$BUILDFILE" fi -fi -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 validpgpkeys - -BUILDFILE=${BUILDFILE:-$BUILDSCRIPT} -if [[ ! -f $BUILDFILE ]]; then - error "$(gettext "%s does not exist.")" "$BUILDFILE" - exit 1 -else - if [[ $(<"$BUILDFILE") = *$'\r'* ]]; then - error "$(gettext "%s contains %s characters and cannot be sourced.")" "$BUILDFILE" "CRLF" - exit 1 - fi + # set defaults if they weren't specified in buildfile + pkgbase=${pkgbase:-${pkgname[0]}} + epoch=${epoch:-0} + basever=$(get_full_version) - if [[ ! $BUILDFILE -ef $PWD/${BUILDFILE##*/} ]]; then - error "$(gettext "%s must be in the current working directory.")" "$BUILDFILE" - exit 1 - fi + if [[ $BUILDDIR = "$startdir" ]]; then + srcdir="$BUILDDIR/src" + pkgdirbase="$BUILDDIR/pkg" + else + srcdir="$BUILDDIR/$pkgbase/src" + pkgdirbase="$BUILDDIR/$pkgbase/pkg" - if [[ ${BUILDFILE:0:1} != "/" ]]; then - BUILDFILE="$startdir/$BUILDFILE" fi - source_buildfile "$BUILDFILE" -fi - -# set defaults if they weren't specified in buildfile -pkgbase=${pkgbase:-${pkgname[0]}} -epoch=${epoch:-0} -basever=$(get_full_version) -if [[ $BUILDDIR = "$startdir" ]]; then - srcdir="$BUILDDIR/src" - pkgdirbase="$BUILDDIR/pkg" -else - srcdir="$BUILDDIR/$pkgbase/src" - pkgdirbase="$BUILDDIR/$pkgbase/pkg" + # set pkgdir to something "sensible" for (not recommended) use during build() + pkgdir="$pkgdirbase/$pkgbase" -fi + if (( GENINTEG )); then + mkdir -p "$srcdir" + chmod a-s "$srcdir" + cd_safe "$srcdir" + download_sources fast + generate_checksums + exit 0 # $E_OK + fi -# set pkgdir to something "sensible" for (not recommended) use during build() -pkgdir="$pkgdirbase/$pkgbase" + if have_function pkgver; then + PKGVERFUNC=1 + fi -if (( GENINTEG )); then - mkdir -p "$srcdir" - chmod a-s "$srcdir" - cd_safe "$srcdir" - download_sources fast - generate_checksums - exit 0 # $E_OK -fi + # check the PKGBUILD for some basic requirements + check_sanity || exit 1 -if have_function pkgver; then - PKGVERFUNC=1 -fi + # check we have the software required to process the PKGBUILD + check_software || exit 1 -# check the PKGBUILD for some basic requirements -check_sanity || exit 1 + if (( ${#pkgname[@]} > 1 )); then + SPLITPKG=1 + fi -# check we have the software required to process the PKGBUILD -check_software || exit 1 + # test for available PKGBUILD functions + if have_function prepare; then + # "Hide" prepare() function if not going to be run + if [[ $RUN_PREPARE != "n" ]]; then + PREPAREFUNC=1 + fi + fi + if have_function build; then + BUILDFUNC=1 + fi + if have_function check; 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 have_function package; then + PKGFUNC=1 + elif [[ $SPLITPKG -eq 0 ]] && have_function package_${pkgname}; then + SPLITPKG=1 + fi -if (( ${#pkgname[@]} > 1 )); then - SPLITPKG=1 -fi + if [[ -n "${PKGLIST[@]}" ]]; then + unset pkgname + pkgname=("${PKGLIST[@]}") + fi -# test for available PKGBUILD functions -if have_function prepare; then - # "Hide" prepare() function if not going to be run - if [[ $RUN_PREPARE != "n" ]]; then - PREPAREFUNC=1 + # check if gpg signature is to be created and if signing key is valid + if { [[ -z $SIGNPKG ]] && check_buildenv "sign" "y"; } || [[ $SIGNPKG == 'y' ]]; then + SIGNPKG='y' + if ! gpg --list-key ${GPGKEY} &>/dev/null; then + if [[ ! -z $GPGKEY ]]; then + error "$(gettext "The key %s does not exist in your keyring.")" "${GPGKEY}" + else + error "$(gettext "There is no key in your keyring.")" + fi + exit 1 + fi fi -fi -if have_function build; then - BUILDFUNC=1 -fi -if have_function check; then - # "Hide" check() function if not going to be run - if [[ $RUN_CHECK = 'y' ]] || { ! check_buildenv "check" "n" && [[ $RUN_CHECK != "n" ]]; }; then - CHECKFUNC=1 + + if (( ! PKGVERFUNC )); then + check_build_status fi -fi -if have_function package; then - PKGFUNC=1 -elif [[ $SPLITPKG -eq 0 ]] && have_function package_${pkgname}; then - SPLITPKG=1 -fi -if [[ -n "${PKGLIST[@]}" ]]; then - unset pkgname - pkgname=("${PKGLIST[@]}") -fi + # Run the bare minimum in fakeroot + if (( INFAKEROOT )); then + if (( SOURCEONLY )); then + create_srcpackage + msg "$(gettext "Leaving %s environment.")" "fakeroot" + exit 0 # $E_OK + fi -# check if gpg signature is to be created and if signing key is valid -if { [[ -z $SIGNPKG ]] && check_buildenv "sign" "y"; } || [[ $SIGNPKG == 'y' ]]; then - SIGNPKG='y' - if ! gpg --list-key ${GPGKEY} &>/dev/null; then - if [[ ! -z $GPGKEY ]]; then - error "$(gettext "The key %s does not exist in your keyring.")" "${GPGKEY}" + chmod 755 "$pkgdirbase" + if (( ! SPLITPKG )); then + pkgdir="$pkgdirbase/$pkgname" + mkdir "$pkgdir" + if (( PKGFUNC )); then + run_package + fi + tidy_install + create_package + create_debug_package else - error "$(gettext "There is no key in your keyring.")" + run_split_packaging fi - exit 1 + + msg "$(gettext "Leaving %s environment.")" "fakeroot" + exit 0 # $E_OK fi -fi -if (( ! PKGVERFUNC )); then - check_build_status -fi + msg "$(gettext "Making package: %s")" "$pkgbase $basever ($(date))" -# Run the bare minimum in fakeroot -if (( INFAKEROOT )); then + # if we are creating a source-only package, go no further if (( SOURCEONLY )); then - create_srcpackage - msg "$(gettext "Leaving %s environment.")" "fakeroot" - exit 0 # $E_OK + if [[ -f $SRCPKGDEST/${pkgbase}-${basever}${SRCEXT} ]] \ + && (( ! FORCE )); then + error "$(gettext "A source package has already been built. (use %s to overwrite)")" "-f" + exit 1 + fi + + # Get back to our src directory so we can begin with sources. + mkdir -p "$srcdir" + chmod a-s "$srcdir" + cd_safe "$srcdir" + if (( SOURCEONLY == 2 )); then + download_sources + elif ( (( ! SKIPCHECKSUMS )) || \ + ( (( ! SKIPPGPCHECK )) && source_has_signatures ) ); then + download_sources fast + fi + check_source_integrity + cd_safe "$startdir" + + enter_fakeroot + + msg "$(gettext "Source package created: %s")" "$pkgbase ($(date))" + exit 0 fi - chmod 755 "$pkgdirbase" - if (( ! SPLITPKG )); then - pkgdir="$pkgdirbase/$pkgname" - mkdir "$pkgdir" - if (( PKGFUNC )); then - run_package + if (( NODEPS || (NOBUILD && !DEP_BIN ) )); then + # no warning message needed for nobuild + if (( NODEPS )); then + warning "$(gettext "Skipping dependency checks.")" fi - tidy_install - create_package - create_debug_package else - run_split_packaging - fi + if (( RMDEPS && ! INSTALL )); then + original_pkglist=($(run_pacman -Qq)) # required by remove_dep + fi + deperr=0 - msg "$(gettext "Leaving %s environment.")" "fakeroot" - exit 0 # $E_OK -fi + msg "$(gettext "Checking runtime dependencies...")" + resolve_deps ${depends[@]} || deperr=1 -msg "$(gettext "Making package: %s")" "$pkgbase $basever ($(date))" + if (( RMDEPS && INSTALL )); then + original_pkglist=($(run_pacman -Qq)) # required by remove_dep + fi -# if we are creating a source-only package, go no further -if (( SOURCEONLY )); then - if [[ -f $SRCPKGDEST/${pkgbase}-${basever}${SRCEXT} ]] \ - && (( ! FORCE )); then - error "$(gettext "A source package has already been built. (use %s to overwrite)")" "-f" - exit 1 + msg "$(gettext "Checking buildtime dependencies...")" + if (( CHECKFUNC )); then + resolve_deps "${makedepends[@]}" "${checkdepends[@]}" || deperr=1 + else + resolve_deps "${makedepends[@]}" || deperr=1 + fi + + if (( RMDEPS )); then + current_pkglist=($(run_pacman -Qq)) # required by remove_deps + fi + + if (( deperr )); then + error "$(gettext "Could not resolve all dependencies.")" + exit 1 + fi fi - # Get back to our src directory so we can begin with sources. + # get back to our src directory so we can begin with sources mkdir -p "$srcdir" chmod a-s "$srcdir" cd_safe "$srcdir" - if (( SOURCEONLY == 2 )); then - download_sources - elif ( (( ! SKIPCHECKSUMS )) || \ - ( (( ! SKIPPGPCHECK )) && source_has_signatures ) ); then - download_sources fast - fi - check_source_integrity - cd_safe "$startdir" - - enter_fakeroot - - msg "$(gettext "Source package created: %s")" "$pkgbase ($(date))" - exit 0 -fi -if (( NODEPS || (NOBUILD && !DEP_BIN ) )); then - # no warning message needed for nobuild - if (( NODEPS )); then - warning "$(gettext "Skipping dependency checks.")" - fi -else - if (( RMDEPS && ! INSTALL )); then - original_pkglist=($(run_pacman -Qq)) # required by remove_dep - fi - deperr=0 + if (( NOEXTRACT && ! VERIFYSOURCE )); then + warning "$(gettext "Using existing %s tree")" "\$srcdir/" + elif (( !REPKG )); then + download_sources + check_source_integrity + (( VERIFYSOURCE )) && exit 0 # $E_OK - msg "$(gettext "Checking runtime dependencies...")" - resolve_deps ${depends[@]} || deperr=1 + if (( CLEANBUILD )); then + msg "$(gettext "Removing existing %s directory...")" "\$srcdir/" + rm -rf "$srcdir"/* + fi - if (( RMDEPS && INSTALL )); then - original_pkglist=($(run_pacman -Qq)) # required by remove_dep + extract_sources + if (( PKGVERFUNC )); then + update_pkgver + basever=$(get_full_version) + check_build_status + fi + if (( PREPAREFUNC )); then + run_prepare + fi fi - msg "$(gettext "Checking buildtime dependencies...")" - if (( CHECKFUNC )); then - resolve_deps "${makedepends[@]}" "${checkdepends[@]}" || deperr=1 + if (( NOBUILD )); then + msg "$(gettext "Sources are ready.")" + exit 0 #E_OK else - resolve_deps "${makedepends[@]}" || deperr=1 - fi + # clean existing pkg directory + if [[ -d $pkgdirbase ]]; then + msg "$(gettext "Removing existing %s directory...")" "\$pkgdir/" + rm -rf "$pkgdirbase" + fi + mkdir -p "$pkgdirbase" + chmod a-srwx "$pkgdirbase" + cd_safe "$startdir" - if (( RMDEPS )); then - current_pkglist=($(run_pacman -Qq)) # required by remove_deps - fi + if (( ! REPKG )); then + (( BUILDFUNC )) && run_build + (( CHECKFUNC )) && run_check + cd_safe "$startdir" + fi - if (( deperr )); then - error "$(gettext "Could not resolve all dependencies.")" - exit 1 + enter_fakeroot fi -fi -# get back to our src directory so we can begin with sources -mkdir -p "$srcdir" -chmod a-s "$srcdir" -cd_safe "$srcdir" - -if (( NOEXTRACT && ! VERIFYSOURCE )); then - warning "$(gettext "Using existing %s tree")" "\$srcdir/" -elif (( !REPKG )); then - download_sources - check_source_integrity - (( VERIFYSOURCE )) && exit 0 # $E_OK - - if (( CLEANBUILD )); then - msg "$(gettext "Removing existing %s directory...")" "\$srcdir/" - rm -rf "$srcdir"/* + # if inhibiting archive creation, go no further + if (( NOARCHIVE )); then + msg "$(gettext "Package folder is ready.")" + exit 0 fi - extract_sources - if (( PKGVERFUNC )); then - update_pkgver - basever=$(get_full_version) - check_build_status - fi - if (( PREPAREFUNC )); then - run_prepare - fi -fi + msg "$(gettext "Finished making: %s")" "$pkgbase $basever ($(date))" -if (( NOBUILD )); then - msg "$(gettext "Sources are ready.")" - exit 0 #E_OK -else - # clean existing pkg directory - if [[ -d $pkgdirbase ]]; then - msg "$(gettext "Removing existing %s directory...")" "\$pkgdir/" - rm -rf "$pkgdirbase" - fi - mkdir -p "$pkgdirbase" - chmod a-srwx "$pkgdirbase" - cd_safe "$startdir" - - if (( ! REPKG )); then - (( BUILDFUNC )) && run_build - (( CHECKFUNC )) && run_check - cd_safe "$startdir" - fi + install_package - enter_fakeroot -fi + exit 0 #E_OK +} -# if inhibiting archive creation, go no further -if (( NOARCHIVE )); then - msg "$(gettext "Package folder is ready.")" - exit 0 +# if this file was not sourced, then "return" will be an error here, and we'll +# run makepkg_main. Otherwise, the return succeeds and we'll only have sourced +# the functions out of this file. +if ! return 0 2>/dev/null; then + makepkg_main "$@" fi -msg "$(gettext "Finished making: %s")" "$pkgbase $basever ($(date))" - -install_package - -exit 0 #E_OK - # vim: set noet: -- 2.0.4
On 08/08/14 09:22, Dave Reisner wrote:
Aside from the hack at the foot of the script, this commit introduces no logical changes or new code. Any globally scoped declaration or code are moved into a 'makepkg_main' function which is called when the script is executed (not sourced).
Doing this allows other scripts to source makepkg for its juicy functions, and also makes these functions more easily unit testable.
This commit explicitly does NOT attempt to define an API or any other stability guarantees of any kind.
I am OK with this as an interim solution. Note that we have added the ability to have makepkg split up into small independent files (which I think is good for testing and reusability), so I'd like us to head that way at some stage. A
On Fri, Aug 08, 2014 at 02:11:09PM +1000, Allan McRae wrote:
On 08/08/14 09:22, Dave Reisner wrote:
Aside from the hack at the foot of the script, this commit introduces no logical changes or new code. Any globally scoped declaration or code are moved into a 'makepkg_main' function which is called when the script is executed (not sourced).
Doing this allows other scripts to source makepkg for its juicy functions, and also makes these functions more easily unit testable.
This commit explicitly does NOT attempt to define an API or any other stability guarantees of any kind.
I am OK with this as an interim solution. Note that we have added the ability to have makepkg split up into small independent files (which I think is good for testing and reusability), so I'd like us to head that way at some stage.
A
This feature you speak of seems poorly/not-at-all documented and half-finished (nothing uses it, at least). It's also a solution which could be independent of being able to source makepkg as a final result. d
On 08/08/14 22:22, Dave Reisner wrote:
On Fri, Aug 08, 2014 at 02:11:09PM +1000, Allan McRae wrote:
On 08/08/14 09:22, Dave Reisner wrote:
Aside from the hack at the foot of the script, this commit introduces no logical changes or new code. Any globally scoped declaration or code are moved into a 'makepkg_main' function which is called when the script is executed (not sourced).
Doing this allows other scripts to source makepkg for its juicy functions, and also makes these functions more easily unit testable.
This commit explicitly does NOT attempt to define an API or any other stability guarantees of any kind.
I am OK with this as an interim solution. Note that we have added the ability to have makepkg split up into small independent files (which I think is good for testing and reusability), so I'd like us to head that way at some stage.
A
This feature you speak of seems poorly/not-at-all documented and half-finished (nothing uses it, at least). It's also a solution which could be independent of being able to source makepkg as a final result.
d
Correct on both accounts. There are patches to split out the VCS handling that were delayed while the patches for incremental VCS builds were added... (soon!) See: https://patchwork.archlinux.org/patch/1565/ https://patchwork.archlinux.org/patch/1566/ Allan
On 08/08/14 09:22, Dave Reisner wrote:
This option is only for HTML output, and we're building manpages here.
I'm glad someone stop ignoring those messages. I thought the fix would be harder...
participants (3)
-
Allan McRae
-
Dave Reisner
-
Dave Reisner