diff options
Diffstat (limited to 'brep/handler/submit/submit-pub.in')
-rw-r--r-- | brep/handler/submit/submit-pub.in | 58 |
1 files changed, 40 insertions, 18 deletions
diff --git a/brep/handler/submit/submit-pub.in b/brep/handler/submit/submit-pub.in index d262ae9..42d478d 100644 --- a/brep/handler/submit/submit-pub.in +++ b/brep/handler/submit/submit-pub.in @@ -12,7 +12,7 @@ # # Specifically, the handler performs the following steps: # -# - Lock the repository directory for the duraton of the package submission. +# - Lock the repository directory for the duration of the package submission. # # - Check for the package duplicate. # @@ -85,7 +85,10 @@ verbose= #true rep_lock_timeout=60 trap "{ exit 1; }" ERR -set -o errtrace # Trap ERR in functions. +set -o errtrace # Trap in functions and subshells. +set -o pipefail # Fail if any pipeline command fails. +shopt -s lastpipe # Execute last pipeline command in the current shell. +shopt -s nullglob # Expand no-match globs to nothing rather than themselves. @import brep/handler/handler@ @import brep/handler/submit/submit@ @@ -254,6 +257,8 @@ else message_suffix=": $name/$version" fi +revision="$(version_revision "$version")" + # Open the reading file descriptor and lock the repository. Fail if unable to # lock before timeout. # @@ -294,8 +299,22 @@ trap exit_trap EXIT # Check for the package duplicate (in all projects). # -if [ -n "$(run find "$repo_old/1" -name "$archive")" ]; then - exit_with_manifest 422 "duplicate submission" +# Use <name>-<version>.* without .tar.gz in case we want to support more +# archive types later. +# +run pkg_find_archive "$name-$version.*" "$repo_old/1" | readarray -t p + +if [ "${#p[@]}" -ne 0 ]; then + n="${p[1]}" + v="${p[2]}" + + trace "found: $n/$v in ${p[0]}" + + if [ "$n" == "$name" ]; then + exit_with_manifest 422 "duplicate submission" + else + exit_with_manifest 422 "submission conflicts with $n/$v" + fi fi # Copy the current repository using hardlinks. @@ -310,27 +329,30 @@ fi run rsync -rtO --exclude 'packages.manifest' --link-dest="$repo_old" \ "$repo_old/" "$repo_new" -# Remove the package version revisions that may exist in the repository. +# Remove the package version revision archives that may exist in the +# repository. # -# Strips the version revision part, if present. +# But first check if the repository contains newer revision of this package +# version. Respond with the 'newer revision is present' result manifest and +# exit if that's the case. # -v="$(sed -n -re 's%^(\+?[^+]+)(\+[0-9]+)?$%\1%p' <<<"$version")" +run pkg_find_archives "$name" "$version*" "$repo_new/1" | readarray -t arcs -# Go through the potentially matching archives (for example, for foo-1.2.3+2: -# foo-1.2.3.tar.gz, foo-1.2.3+1.tar.gz, foo-1.2.30.tar.gz, etc) and remove -# those that match exactly. -# -# Change CWD to the section directory to make sure that the found archive -# paths don't contain spaces. -# -fs=($(run cd "$repo_new/1" && run find -name "$name-$v*")) +for f in "${arcs[@]}"; do + pkg_verify_archive "$f" | readarray -t p + + v="${p[1]}" + rv="$(version_revision "$v")" -for f in "${fs[@]}"; do - if [[ "$f" =~ ^\./[^/]+/"$name-$v"(\+[0-9]+)?\.[^/]+$ ]]; then - run rm "$repo_new/1/$f" >&2 + if [ "$rv" -gt "$revision" ]; then + exit_with_manifest 422 "newer revision $name/$v is present" fi done +for f in "${arcs[@]}"; do + run rm "$f" +done + # Copy the archive rather than moving it since we may need it for # troubleshooting. Note: the data and repository directories can be on # different filesystems and so hardlinking could fail. |