On 09/18/13 at 06:59pm, Allan McRae wrote:
> Signed-off-by: Allan McRae <[email protected]>
> ---
> 
> v2: Use awk to do symlink to actual directory replacement
> 
> As an example of what changes get made:
> 
> diff -Naur local.tmp/glibc-2.18-4/files local/glibc-2.18-4/files
> --- local.tmp/glibc-2.18-4/files      2013-09-18 18:45:35.747068765 +1000
> +++ local/glibc-2.18-4/files  2013-09-18 18:51:29.633643945 +1000
> @@ -4,8 +4,8 @@
>  etc/locale.gen
>  etc/nscd.conf
>  etc/rpc
> -lib/
> -lib/libc.a
> +usr/lib/
> +usr/lib/libc.a
>  usr/
>  usr/bin/
>  usr/bin/catchsegv
> 
> 
> Note that now usr/lib/ is present twice in the file (may not always be the 
> case)
> and these entries are out of alphabetical order.  Both these are cosmetic to
> pacman.
> 
>  scripts/pacman-db-upgrade.sh.in | 59 
> ++++++++++++++++++++++++++++++++++-------
>  1 file changed, 49 insertions(+), 10 deletions(-)
> 
> diff --git a/scripts/pacman-db-upgrade.sh.in b/scripts/pacman-db-upgrade.sh.in
> index a1630c5..d6f4169 100644
> --- a/scripts/pacman-db-upgrade.sh.in
> +++ b/scripts/pacman-db-upgrade.sh.in
> @@ -109,18 +109,57 @@ 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.")"
> +if [[ -f "${dbroot}"/local/.alpm_db_version ]]; then
> +     db_version=$(cat "${dbroot}"/local/.alpm_db_version)
>  fi
>  
> +if [[ -z "$db_version" ]]; then
> +     # 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
> +
> +     # pacman 4.1 to 4.2 upgrade - remove directory symlink support
> +     dirlist=()
> +
> +     unset GREP_OPTIONS
> +     while IFS= read -r dir; do
> +             dirlist+=("/${dir%/}")
> +     done < <(grep -h '/$' "$dbroot"/local/*/files | sort -u)

This sort needs to be reversed.  If a path contains multiple symlinks,
the longer one needs to come first, otherwise awk will replace the
shorter symlink and miss the longer one. For example:

 symlink1/
 symlink1/symlink2/
 ...

> +
> +     mapfile -t dirlist < <(find "${dirlist[@]}" -maxdepth 0 -type l)
> +
> +     if [[ ${#dirlist[@]} != 0 ]]; then
> +             msg "$(gettext "Pre-4.2 database format detected - 
> upgrading...")"
> +             for dir in "${dirlist[@]}"; do
> +                     realdir="$(cd $dir; pwd -P)"
> +                     for f in "$dbroot"/local/*/files; do
> +                             awk -v "dir=${dir#/}/" -v 
> "realdir=${realdir#/}/" '
> +                                     BEGIN {
> +                                             i = length(dir) + 1
> +                                     }
> +                                     {
> +                                             if (index($0, dir) == 1) {
> +                                                     printf("%s%s\n", 
> realdir, substr($0, i))
> +                                             } else {
> +                                                     print
> +                                             }
> +                                     }' $f > $f.tmp
> +                             mv $f.tmp $f

$f will include $dbroot, so it needs to be quoted as well.  

Depending on the file list, this may leave out parent directories of
$realdir or leave behind parent directories of $dir that are no longer
relevant.  For example:

 path/
 path/to/
 path/to/symlink/
 ...

gives:

 path/
 path/to/
 other/path/to/realdir/
 ...

I don't think the leftover directories will hurt anything, but the
missing parent directories will break -Qo.

> +                     done
> +             done
> +     fi
> +fi
> +
> +echo "9" > "$dbroot"/local/.alpm_db_version
> +
>  # remove the lock file
>  rm -f "$lockfile"
>  
> -- 
> 1.8.4

Reply via email to