diff --git a/scripts/pkgmeek b/scripts/pkgmeek index 943b5d2..c04011a 100755 --- a/scripts/pkgmeek +++ b/scripts/pkgmeek @@ -46,14 +46,17 @@ validate_pkgfile || exit $E_PKGFILE package="${name}#${version}-${release}.pkg.tar.${PKGMK_COMPRESSION_MODE}" declare -a _local_ for (( s=0; s<${#source[@]}; s++ )); do - [[ ${source[$s]} =~ ^(http|https|ftp|ssh|git)://.*/(.+) ]] && \ - _local_[$s]="${BASH_REMATCH[2]%%.git}" || _local_[$s]="${source[$s]}" + [[ ${source[$s]} =~ ^(http|https|ssh|ftp|git)://.*/(.+)$ ]] && \ + _local_[$s]="${BASH_REMATCH[2]%.git*}" || _local_[$s]="${source[$s]}" [ -z "${renames[$s]}" ] || [ "${renames[$s]}" = "SKIP" ] || \ _local_[$s]="${renames[$s]}" done -# Example: _local_ = ( some-git-repo/ -# upstream-ball-v12.tgz -# random.patch ) +# Example: source = ( https://gitlab.com/demo-user/cool-project.git#0.4.9 +# https://dev.big-corp.com/src/needed-library.tgz +# random.patch ) +# _local_ = ( cool-project +# needed-library.zgt <-- renamed to prevent automatic unpacking +# random.patch ) # The effective user should at least have write permissions on $PWD [ -w "$(dirname "$work")" ] || work="$(pwd)"/work @@ -81,7 +84,8 @@ done ; } # If the user only asked for '-utd', perform the check using the sources that do exist. check_pkg_mtime; pkg_utd=$? -[ "$PKGMK_MTIME_ONLY" = "no" ] || [ "$PKGMK_CHECK_SIG" = "yes" ] || exit $pkg_utd +[ "$PKGMK_MTIME_ONLY" = "no" ] || [ "$PKGMK_CHECK_SIG" = "yes" ] || \ + [ "$PKGMK_FORCE" = "yes" ] || exit $pkg_utd # Take into account all the actions that can be done with a previously built package, # or with a full set of sources @@ -133,10 +137,7 @@ case $? in esac; } [ "$PKGMK_CHECK_SIG" = "no" ] || exit 0 # no need to continue if the user only requested -cs -if [ "$pkg_utd" = 0 ] || [ "$PKGMK_FORCE" = "yes" ]; then # Skip the extract, build steps. - # What used to be called unpack_source() is now hard-coded into the main routine. - # If you need to shield specific source files from unpacking, use the "renames" - # feature of Pkgfile(5) to avoid matching any of the following patterns. +if [ "$pkg_utd" = 0 ] || [ "$PKGMK_FORCE" = "yes" ]; then for (( u=0; u<${#_local_[@]}; u++ )) ; do here="${_local_[$u]}" case "$here" in @@ -188,15 +189,16 @@ if [ "$pkg_utd" = 0 ] || [ "$PKGMK_FORCE" = "yes" ]; then # Skip the extract, bu find . -maxdepth 1 -mindepth 1 -type l -delete; cleanup_work fi # Continue from here if the extract and build were skipped -# Install if requested -# First find out how the effective user will invoke pkgadd +# Install if requested. For non-root builds, only sudo and doas are supported. +# Avoid falling back on su -c! It gobbles up the options intended for pkgadd. [ $UID = 0 ] || PKGMK_SU="sudo"; [ -z "$PKGMK_SU" ] || [ -x "$(command -v $PKGMK_SU)" ] || PKGMK_SU="/usr/bin/doas"; -[ -x "$(command -v $PKGMK_SU)" ] || PKGMK_SU="su -c"; +[ -z "$PKGMK_SU" ] || [ -x "$(command -v $PKGMK_SU)" ] \ + || { error "Cannot run pkgadd as a non-root user."; exit "$E_INSTALL"; } [ -z "$PKGMK_INSTALL_COMMAND" ] || { $PKGMK_SU $PKGMK_INSTALL_COMMAND "$pkg_dir$package" \ && info "$(basename $PKGMK_INSTALL_COMMAND) $package succeeded."; } || \ - { error "Unable to install $package using pkgadd."; exit "$E_INSTALL"; } + { error "$(basename $PKGMK_INSTALL_COMMAND) $package failed."; exit "$E_INSTALL"; } # Done! } @@ -217,31 +219,21 @@ readonly PKGMK_COMMAND="$0" readonly PKGMK_ROOT="$PWD" readonly PRTWASH_COMMAND="/usr/bin/prtwash" PKGMK_DOWNLOAD_PROG="/usr/bin/wget" - +PKGMK_GIT_COMMAND="/usr/bin/git" PKGMK_CONF="/etc/pkgmk.conf" -PKGMK_SOURCE_DIR="$PWD" -PKGMK_PACKAGE_DIR="$PWD" -PKGMK_WORK_DIR="$PWD/work" -PKGMK_COMPRESSION_MODE="gz" -PKGMK_INSTALL_COMMAND="" -PKGMK_CLEAN="no" -PKGMK_RECURSIVE="no" -PKGMK_DOWNLOAD_ONLY="no" -PKGMK_EXTRACT_ONLY="no" -PKGMK_MTIME_ONLY="no" -PKGMK_UPDATE_FOOTPRINT="no" -PKGMK_IGNORE_FOOTPRINT="no" -PKGMK_IGNORE_NEW="no" -PKGMK_FORCE="no" -PKGMK_KEEP_WORK="no" -PKGMK_UPDATE_MD5="no" -PKGMK_IGNORE_MD5="no" -PKGMK_UPDATE_SIG="no" -PKGMK_IGNORE_SIG="no" -PKGMK_REFRESH_SIG="no" -PKGMK_CHECK_SIG="no" -PKGMK_PRIVATEKEY="" +PKGMK_SOURCE_DIR="$PWD"; PKGMK_WORK_DIR="$PWD/work" +PKGMK_PACKAGE_DIR="$PWD"; PKGMK_COMPRESSION_MODE="gz" + +PKGMK_INSTALL_COMMAND=""; PKGMK_FORCE="no" +PKGMK_CLEAN="no"; PKGMK_KEEP_WORK="no" +PKGMK_RECURSIVE="no"; PKGMK_UPDATE_MD5="no" +PKGMK_DOWNLOAD_ONLY="no"; PKGMK_IGNORE_MD5="no" +PKGMK_EXTRACT_ONLY="no"; PKGMK_UPDATE_SIG="no" +PKGMK_MTIME_ONLY="no"; PKGMK_IGNORE_SIG="no" +PKGMK_UPDATE_FOOTPRINT="no"; PKGMK_REFRESH_SIG="no" +PKGMK_IGNORE_FOOTPRINT="no"; PKGMK_CHECK_SIG="no" +PKGMK_IGNORE_NEW="no"; PKGMK_PRIVATEKEY="" ######################## subroutines ################################ parse_options() { @@ -366,33 +358,44 @@ check_pkg_mtime() { # can be called even if some sources are missing } fetch_source() { - local u="$1"; local h="$2"; local finished=0; local REPO SAVE_AS OCONTINUE OOUT - - # Determine whether the source should be obtained by git - local PKGMK_GIT_COMMAND="/usr/bin/git" + local u="$1"; local h="$2"; local finished=0; local gitsrc tag CLONE_ARGS + local REPO SAVE_AS OCONTINUE OOUT; local m=0 [ -x "$PKGMK_GIT_COMMAND" ] || PKGMK_GIT_COMMAND="/bin/false" - if [[ $u =~ ^(https|http|ssh|git)://.*/(.+)\.git$ ]]; then - [ -d "$src_dir/$h.partial" ] && { ln -s "$src_dir/$h.partial" "$h"; cd "$h"; - "$PKGMK_GIT_COMMAND" pull; finished=$?; cd ..; } - [ -d "$src_dir/$h.partial" ] || \ - { "$PKGMK_GIT_COMMAND" clone "$u" "$h.partial"; finished=$?; + + # Is this a url that requires git? + if [[ $u =~ ^(https|http|ssh|git)://.*/(.+)\.git(.*)$ ]]; then + # Did the port maintainer specify a branch other than 'master'? + tag=${BASH_REMATCH[3]#\#}; gitsrc="${u%.git*}.git" + [ -z "$tag" ] || CLONE_ARGS="--branch $tag" + + # If git is not installed, this source cannot be obtained at present + [ "$PKGMK_GIT_COMMAND" != "/bin/false" ] || return 1; + + # Is it our first attempt to download this repository? + if [ ! -d "$src_dir/$h.partial" ]; then + "$PKGMK_GIT_COMMAND" clone "$gitsrc" $CLONE_ARGS "$h.partial" + finished=$? [ "$src_dir" = "" ] || { mv "$h.partial" "$src_dir"; - ln -s "$src_dir/$h.partial" "$h"; }; - [ "$src_dir" = "" ] && ln -s "$h.partial" "$h"; } + ln -s "$src_dir/$h.partial" "$h"; } + else + ln -s "$src_dir/$h.partial" "$h"; cd "$h" + "$PKGMK_GIT_COMMAND" pull $gitsrc $tag + finished=$?; cd .. + fi return $finished; fi + # haven't returned yet, so a different transport protocol must be in effect [[ "$PKGMK_DOWNLOAD_PROG" =~ wget$ ]] && { OCONTINUE="-c"; OOUT="$PKGMK_WGET_OPTIONS -O"; } [[ "$PKGMK_DOWNLOAD_PROG" =~ curl$ ]] && { OCONTINUE="-C -"; OOUT="$PKGMK_CURL_OPTIONS -o"; } [[ "$PKGMK_DOWNLOAD_PROG" =~ (wget|curl)$ ]] || SAVE_AS=/bin/false - local m=${#PKGMK_SOURCE_MIRRORS[@]} - # start with the url in the Pkgfile, then hit the mirrors until a download succeeds - while [ $m -ge 0 ] && [ $finished = 0 ] && [[ ! $SAVE_AS =~ false$ ]]; do + # start with the mirrors defined in pkgmk.conf, then go to the url found in the Pkgfile + while [ $m -le ${#PKGMK_SOURCE_MIRRORS[@]} ] && [ $finished = 0 ] && [[ ! $SAVE_AS =~ false$ ]]; do [ "${PKGMK_SOURCE_MIRRORS[m]}" = "" ] && um=$u || \ { REPO=$(echo ${PKGMK_SOURCE_MIRRORS[m]} | sed 's,/$,,'); um=$REPO/$(echo $u | sed 's,.*/,,'); } - m=$(( m-1 )) + m=$(( m+1 )) # interrupted downloads from a previous run should be put where wget or curl will find them [ -s "$src_dir/$h.partial" ] && { ln -s "$src_dir/$h.partial" . ; @@ -478,13 +481,12 @@ check_signature() { # called from $PKGMK_ROOT in the case "when"="pre-Pkgfile", # otherwise called from within $work. Pass control to # check_manifest() if the signature is missing and "ignore-md5" # has not been requested. - # Remember to clean up the soft links that get left behind! - local reqfiles=(Pkgfile); local s=0; local when="$1" + local reqfiles=(Pkgfile); local s=0; local when="$1"; if [ -f "$PKGMK_ROOT/.signature" ]; then [ "$when" = "pre-Pkgfile" ] || reqfiles=(.footprint) while [ "$when" = "pre-build" ] && [ "$s" -lt ${#_local_[@]} ]; do - [[ "${source[$s]}" =~ ^(http|https|ssh|git).*/\.git ]] || \ + [[ "${source[$s]}" =~ ^(http|https|ssh|git)://(.+)\.git ]] || \ reqfiles+=("${_local_[$s]}") s=$(( s+1 )) done