[pacman-dev] [PATCH v2] Extend database upgrade script to handle alpm db version 9

Andrew Gregory andrew.gregory.8 at gmail.com
Fri Sep 27 09:45:05 EDT 2013


On 09/18/13 at 06:59pm, Allan McRae wrote:
> Signed-off-by: Allan McRae <allan at archlinux.org>
> ---
> 
> 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


More information about the pacman-dev mailing list