-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathupdate
executable file
·167 lines (131 loc) · 4.04 KB
/
update
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/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