On 08/10/14 at 01:16pm, Allan McRae wrote:
On 03/08/14 15:31, Andrew Gregory wrote:
Original-work-by: Allan McRae <allan@archlinux.org> Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com> ---
Big thanks for doing this!
Changes: * set alternate root with PACROOT environment variable
As you have pointed out, that needs to be a -r/--root flag and not an environmental variable
* filter results through grep and sort to remove empty lines and duplicates * add parent directories (duplicates filtered out by sort) * verify that the resolved directory is inside our root * replace longer symlinks first * handle conflict between resolved directory and existing filelist entry
scripts/pacman-db-upgrade.sh.in | 92 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 10 deletions(-)
diff --git a/scripts/pacman-db-upgrade.sh.in b/scripts/pacman-db-upgrade.sh.in index b0b0ac8..7ea4077 100644 --- a/scripts/pacman-db-upgrade.sh.in +++ b/scripts/pacman-db-upgrade.sh.in
<snip>
+ # construct the parents of the new directory + parents="" + parent="$(dirname "$newdir")"
use bash: parent=${newdir%/*}
+ while [[ $parent != "." ]]; do
Should that be != '/' ?
$ dirname /usr /
Anyway, using the bash above this becomes while [[ -n "$parent" ]]; do
This won't work. $newdir has a trailing slash that would need to be removed and it's relative to $pacroot, so ${parent%/*} would eventually result in the base directory, not an empty string (which is why dirname eventually gives '.'). If the symlink points to $pacroot, $newdir could even be empty. My attempts to account for all of that in pure bash have been overly convoluted, but I'm open to suggestions.
+ parents+="$parent/\n" + parent="$(dirname "$parent")" + done +
My awk is suboptimal... So I'll comment my understanding as I go...
+ for f in "$dbroot"/local/*/files; do + awk -v "olddir=$olddir" -v "newdir=$newdir" -v "parents=$parents" '
"parents=${parents[@]}"
$parents is actually a string rather than an array because I don't think there's a way to pass an array to awk without mangling something.
+ BEGIN { + i = length(olddir) + 1 + file = substr(newdir, 0, length(newdir) - 1) + } + { + if ($0 == olddir) { + printf("%s", parents) + printf("%s\n", newdir)
OK (replacing old dir with newdir and its parents)
+ } else if ($0 == file) { + # skip
I do not understand what this bit is achieving!
If the newdir already exists in the file list as a file (i.e. somebody replaced a symlink with a directory) this will prevent a duplicate entry. I'll expand that comment so it's clearer.
+ } else if (index($0, olddir) == 1) { + printf("%s%s\n", newdir, substr($0, i))
OK ("moving" file in olddir to "newdir")
+ } else { + print
OK (not touching files outside of olddir)
+ } + }' "$f" | grep . | LC_ALL=C sort -u > "$f.tmp"
Why the grep?
Removes blank lines in case $newdir has no parents or equals $pacroot.
+ mv "$f.tmp" "$f" + done + done + fi +fi + +echo "9" > "$dbroot"/local/.alpm_db_version +
OK
# remove the lock file rm -f "$lockfile"