From 8c3da8abdb16ecad007dc60068deb90e151737ea Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 21 Sep 2020 17:52:52 +0300 Subject: Fix submission handler issues arising due to package archive name ambiguity Now we take into account the fact that the foo-bar-1.0.tar.gz archive may contain either foo-bar/1.0 or foo/bar-1.0 package. --- brep/handler/buildfile | 1 + brep/handler/handler.bash.in | 7 ++++++ brep/handler/submit/submit-git.bash.in | 17 +++++++++----- brep/handler/submit/submit-git.in | 29 ++++++------------------ brep/handler/submit/submit-pub.in | 41 ++++++++++++++++++---------------- 5 files changed, 48 insertions(+), 47 deletions(-) (limited to 'brep') diff --git a/brep/handler/buildfile b/brep/handler/buildfile index b351ca3..00c072e 100644 --- a/brep/handler/buildfile +++ b/brep/handler/buildfile @@ -3,6 +3,7 @@ import mods = libbutl.bash%bash{manifest-parser} import mods += libbutl.bash%bash{manifest-serializer} +import mods += bpkg-rep%bash{package-archive} ./: bash{handler} submit/ ci/ diff --git a/brep/handler/handler.bash.in b/brep/handler/handler.bash.in index 1169b99..0aa3f69 100644 --- a/brep/handler/handler.bash.in +++ b/brep/handler/handler.bash.in @@ -12,6 +12,9 @@ fi @import libbutl/manifest-parser@ @import libbutl/manifest-serializer@ +bpkg_rep_bpkg=bpkg +@import bpkg-rep/package-archive@ + # Diagnostics. # # We expect the user to set the verbose variable either to true or empty @@ -148,3 +151,7 @@ function manifest_serialize () # # trace "$1: $2" printf "%s:%s\0" "$1" "$2" >&"$manifest_serializer_ifd" } + +function pkg_verify_archive () { bpkg_rep_pkg_verify_archive "$@"; } +function pkg_find_archives () { bpkg_rep_pkg_find_archives "$@"; } +function pkg_find_archive () { bpkg_rep_pkg_find_archive "$@"; } diff --git a/brep/handler/submit/submit-git.bash.in b/brep/handler/submit/submit-git.bash.in index 9f25c28..983d7b5 100644 --- a/brep/handler/submit/submit-git.bash.in +++ b/brep/handler/submit/submit-git.bash.in @@ -77,15 +77,20 @@ function check_package_duplicate () # # local s for s in "${!sections[@]}"; do - local d="$rep/${sections[$s]}" + local p + IFS=$'\n' eval \ + 'p=($(run pkg_find_archive "$nam-$ver.*" "$rep/${sections[$s]}"))' - if [ -d "$d" ]; then - local f - f="$(run find "$d" -name "$nam-$ver.*")" + if [ "${#p[@]}" -ne 0 ]; then + local n="${p[0]}" + local v="${p[1]}" - if [ -n "$f" ]; then - trace "found: $f" + trace "found: $n/$v in ${p[3]}" + + if [ "$n" == "$nam" ]; then exit_with_manifest 422 "duplicate submission" + else + exit_with_manifest 422 "submission conflicts with $n/$v" fi fi done diff --git a/brep/handler/submit/submit-git.in b/brep/handler/submit/submit-git.in index 54cd230..c67c30c 100644 --- a/brep/handler/submit/submit-git.in +++ b/brep/handler/submit/submit-git.in @@ -639,28 +639,11 @@ for i in {1..11}; do exit_with_manifest 400 "unrecognized section '$section'" fi - # Strips the version revision part, if present. - # - v="$(sed -n -re 's%^(\+?[^+]+)(\+[0-9]+)?$%\1%p' <<<"$version")" - - # Make sure the section directory exists before we run find in it. - # - d="$tgt_dir/$s/$project" - run mkdir -p "$d" # Create all the parent directories as well. - - # 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 "$tgt_dir/$s" && run find -name "$name-$v*")) + IFS=$'\n' eval \ + 'arcs=($(run pkg_find_archives "$name" "$version*" "$tgt_dir/$s"))' - for f in "${fs[@]}"; do - if [[ "$f" =~ ^\./[^/]+/"$name-$v"(\+[0-9]+)?\.[^/]+$ ]]; then - run git -C "$tgt_dir" rm $gqo "$s/$f" >&2 - fi + for f in "${arcs[@]}"; do + run git -C "$tgt_dir" rm $gqo "${f#$tgt_dir/}" >&2 done # Finally, add the package archive to the target repository. @@ -669,8 +652,10 @@ for i in {1..11}; do # Make sure the project directory exists before we copy the archive into it. # Note that it was removed by git-rm if it became empty. # + d="$tgt_dir/$s/$project" + run mkdir -p "$d" # Create all the parent directories as well. + a="$d/$archive" - run mkdir -p "$d" # Create all the parent directories as well. run cp "$data_dir/$archive" "$a" git_add "$tgt_dir" "${a#$tgt_dir/}" diff --git a/brep/handler/submit/submit-pub.in b/brep/handler/submit/submit-pub.in index d262ae9..d5f5c4e 100644 --- a/brep/handler/submit/submit-pub.in +++ b/brep/handler/submit/submit-pub.in @@ -294,8 +294,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 -.* without .tar.gz in case we want to support more +# archive types later. +# +IFS=$'\n' eval 'p=($(run pkg_find_archive "$name-$version.*" "$repo_old/1"))' + +if [ "${#p[@]}" -ne 0 ]; then + n="${p[0]}" + v="${p[1]}" + + trace "found: $n/$v in ${p[3]}" + + 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,25 +324,14 @@ 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. -# -v="$(sed -n -re 's%^(\+?[^+]+)(\+[0-9]+)?$%\1%p' <<<"$version")" +IFS=$'\n' eval \ +'arcs=($(run pkg_find_archives "$name" "$version*" "$repo_new/1"))' -# 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 "${fs[@]}"; do - if [[ "$f" =~ ^\./[^/]+/"$name-$v"(\+[0-9]+)?\.[^/]+$ ]]; then - run rm "$repo_new/1/$f" >&2 - fi +for f in "${arcs[@]}"; do + run rm "$f" done # Copy the archive rather than moving it since we may need it for -- cgit v1.1