1
0
Fork 0
mirror of https://github.com/notwa/rc synced 2024-12-21 21:49:40 -08:00
rc/update

167 lines
4 KiB
Bash
Executable file

#!/usr/bin/env sh
here="$(readlink -f "$0")" && here="${here%/*}" && CDPATH= cd "$here" || exit
#remote="https://github.com/notwa/rc/archive/master.tar.gz"
remote="https://eaguru.guru/git/notwa/rc/archive/master.tar.gz"
# NOTE: this script only updates files in subdirectories.
# it does not update itself!
warn() {
printf >&2 %s\\n "$*"
}
do_clean() { true; }
clean() {
do_clean || warn 'update: failed to remove temporary files'
do_clean() { true; }
}
die() {
warn "update:" "$@"
clean
exit 1
}
! [ -d .git ] || die "you don't need this script when you have .git!"
! [ -e _new ] || die '"_new" already exists, please remove it before updating'
backup="backup-$(date -u +%s)" || die 'failed to determine date'
if ! [ -e sh/obtain ]; then
url=https://eaguru.guru/git/notwa/rc/raw/branch/master/sh/obtain
if curl 2>&-; [ $? = 2 ]; then acquire() { curl -fsS -m45 -o- "$*"; }
elif wget 2>&-; [ $? = 1 ]; then acquire() { wget -qt1 -T45 -O- "$*"; }
else die '"sh/obtain" missing, curl and wget missing as well'
fi
mkdir -p sh || die 'failed to create "sh" directory'
acquire "$url" > sh/obtain && chmod +x sh/obtain ||
die 'failed to acquire "sh/obtain"'
fi
dummy() { :; }
preload=dummy
(. sh/obtain) || die 'failed to import "sh/obtain"'
. sh/obtain || exit
__obtain_prep
do_clean() { rm dummy; }
if ! __obtain_url https://eaguru.guru/t/dummy > dummy; then
__obtain_bootstrap || die
__obtain_url https://eaguru.guru/t/dummy > dummy || die
fi
do_clean() { rm dummy dummy.sha256sum; }
printf >dummy.sha256sum '%s *%s\n' \
1b577383bcfb9f191c785497f4ac34a8fb546807bd1094ef65d0ce9a5a63423e dummy ||
die 'failed to write file'
sha256sum -c dummy.sha256sum >/dev/null ||
die 'failed to validate dummy file'
clean
do_clean() { rm update.tar.gz; }
__obtain_url "$remote" > update.tar.gz ||
die 'failed to download new version'
do_clean() { rm -r update.tar.gz _new_$$; }
mkdir _new_$$ || die 'failed to create temporary directory'
tar zxf update.tar.gz -C _new_$$ || die 'failed to extract update files'
rm update.tar.gz || die 'failed to remove archive file'
rename() {
if [ -d _new_$$/rc-master ]
then mv _new_$$/rc-master _new
else mv _new_$$/rc _new
fi
}
do_clean() { if [ -d _new ]; then rm -r _new_$$ _new; else rm -r _new_$$; fi; }
rename || die 'failed to move update files'
do_clean() { rm -r _new _new_$$; }
rmdir _new_$$ || die
discover() {
find "$1" "_new/$1" -type f -exec sha256sum -- {} +
}
different() {
awk '
{
k = substr($0, 67)
sub("^_new/", "", k)
if (a[k]) {
if (a[k] != $1) print k
delete a[k]
} else a[k] = $1
}
END {for (k in a) print k}'
}
do_clean() { rm -r _new; }
desire() {
case "$1" in
(*.bak) false;;
(*/.git/*) false;;
(vim/.netrwhist/*) false;;
(vim/backup/*) false;;
(vim/bundle/*) false;;
(vim/swp/*) false;;
(vim/undo/*) false;;
(*) true
esac
}
backup() {
for f; do
if ! [ -d "$backup/${f%/*}" ]; then
mkdir -p -- "$backup/${f%/*}" ||
die 'failed to create backup directory'
fi
! [ -f "$backup/$f" ] || die 'backup file already exists'
cp -- "$f" "$backup/$f" || die 'failed to create backup file'
done
}
for d in home sh vim; do
discover "$d" > _new/hashes.txt ||
die 'failed to find new files'
different < _new/hashes.txt >> _new/updates.txt ||
die 'failed to compare files'
done
LC_ALL=C sort < _new/updates.txt > _new/sorted.txt ||
die 'failed to sort file paths'
while read -r f; do
desire "$f" || continue
if [ -f "_new/$f" ] && ! [ -f "$f" ]; then
warn " + $f"
cp -p "_new/$f" "$f"
elif ! [ -f "_new/$f" ] && [ -f "$f" ]; then
warn " - $f"
elif [ "_new/$f" -nt "$f" ]; then
# NOTE: this does not play well with git --patch.
# don't use this script when you have git!
warn " * $f"
backup "$f"
cp -p "_new/$f" "$f"
elif [ "_new/$f" -ot "$f" ]; then
warn " / $f"
#else warn " = $f"
fi
done < _new/sorted.txt
clean