... | ... |
@@ -1,30 +1,75 @@ |
1 | 1 |
#!/bin/bash |
2 | 2 |
|
3 |
+set -e |
|
4 |
+ |
|
5 |
+declare -A data=( |
|
6 |
+ [/sim/description]=text |
|
7 |
+ [/sim/long-description]=text |
|
8 |
+ [/sim/author]=text |
|
9 |
+ [/sim/flight-model]=text |
|
10 |
+ [/sim/type]=text |
|
11 |
+ [/sim/model/path]=text |
|
12 |
+) |
|
3 | 13 |
fgaddon_url=https://sourceforge.net/p/flightgear/fgaddon/HEAD/tree/trunk/Aircraft |
4 | 14 |
fgaddon_svn=https://svn.code.sf.net/p/flightgear/fgaddon/trunk/Aircraft |
5 | 15 |
fgaddon_path=$HOME/.fgfs/flightgear-fgaddon/Aircraft |
16 |
+database=${DB:-$0.db} |
|
17 |
+#locale=fr |
|
18 |
+ |
|
19 |
+test -r "$0.conf" && source $0.conf && echo config red |
|
20 |
+ |
|
6 | 21 |
|
7 | 22 |
aircrafts=$(mktemp --dry-run /dev/shm/Aircraft-XXXXXXXXX) |
8 | 23 |
aircraft=$(mktemp --dry-run /dev/shm/aircraft-XXXXXXX) |
9 | 24 |
setxml=$(mktemp --dry-run /dev/shm/setxml-XXXXXXXX) |
10 | 25 |
in_ram_database=$(mktemp --dry-run /dev/shm/XXXXXXX) |
11 |
-database=${DB:-$0.db} |
|
12 | 26 |
|
13 |
-attributes=(description long-description author flight-model type) |
|
14 | 27 |
|
15 |
-xmlgetnext () { |
|
16 |
- local IFS='>' |
|
17 |
- read -d '<' TAG VALUE |
|
18 |
- TAG=$(tr '\n' ' ' <<< $TAG | sed 's/ */ /g; s/ *$//') |
|
28 |
+function xmlgetnext () { |
|
29 |
+ local IFS='>' |
|
30 |
+ read -d '<' TAG VALUE |
|
31 |
+ # by design, the first TAG/VALUE pair is empty |
|
32 |
+ # to avoid infinite loops at end of file parsing we return an error |
|
33 |
+ # the next time we find an empty TAG |
|
34 |
+ if test -z "$TAG"; then |
|
35 |
+ test ${xmlgetnext_firstentry:-1} -eq 1 && xmlgetnext_firstentry=0 || return 1; |
|
36 |
+ fi |
|
37 |
+ # process $TAG only if necessary |
|
38 |
+ local _TAG=$(printf '%q' $TAG) |
|
39 |
+ if test ${_TAG:0:1} = '$'; then |
|
40 |
+ TAG=$(tr '\n' ' ' <<< $TAG | sed 's/ */ /g; s/ *$//') |
|
41 |
+ fi |
|
19 | 42 |
} |
20 | 43 |
|
21 | 44 |
function sqlite_request () { |
22 |
- sqlite3 "$in_ram_database" <<< "$1" |
|
45 |
+ if ! sqlite3 "$in_ram_database" <<< "$1"; then |
|
46 |
+ register_state |
|
47 |
+ fi |
|
48 |
+} |
|
49 |
+ |
|
50 |
+function xmlremovecomments () { |
|
51 |
+ sed -ri 's/<(!--|script>)/\n&/;s/(<\/script|--)>/&\n/' $setxml |
|
52 |
+ sed -ri '/<(script>|!--).*(<\/script|--)>/d;/<(script>|!--)/,/(<\/script|--)>/d' $setxml |
|
53 |
+} |
|
54 |
+ |
|
55 |
+function trap_break () { |
|
56 |
+ trap '' INT |
|
57 |
+ echo "stop requested" |
|
58 |
+ register_state |
|
23 | 59 |
} |
24 | 60 |
|
25 | 61 |
function trap_exit () { |
62 |
+ trapped_rc=$? |
|
63 |
+ trap '' INT |
|
64 |
+ rm -f $aircrafts $aircraft $setxml |
|
65 |
+ if test ! -e $in_ram_database; then |
|
66 |
+ exit |
|
67 |
+ fi |
|
68 |
+ test $trapped_rc -ne 0 && register_state |
|
26 | 69 |
echo "updating installation status" |
27 |
- for ac in $(sqlite_request 'select printf("%i:%s/%s", aircrafts.id, aircrafts.name, setxml.file) from aircrafts inner join setxml where aircrafts.id = setxml.variantof and setxml.installed != 0;'); do |
|
70 |
+ for ac in $(sqlite_request 'select printf("%i:%s/%s", aircrafts.id, aircrafts.name, setxml.file) |
|
71 |
+ from aircrafts inner join setxml |
|
72 |
+ where aircrafts.id = setxml.variantof and setxml.installed != 0;'); do |
|
28 | 73 |
ac_path=${ac#*:} |
29 | 74 |
if test ! -e $fgaddon_path/$ac_path-set.xml; then |
30 | 75 |
sqlite_request "update setxml set installed = 0 where file = '${ac_path#*/}' and variantof = ${ac%:*}" |
... | ... |
@@ -43,9 +88,15 @@ function trap_exit () { |
43 | 88 |
fi |
44 | 89 |
sqlite_request "update setxml set installed = $install_type |
45 | 90 |
where exists ( |
46 |
- select 1 from aircrafts where name = '${ac/\/}' and setxml.variantof = id |
|
91 |
+ select 1 |
|
92 |
+ from aircrafts |
|
93 |
+ where name = '${ac/\/}' and setxml.variantof = id |
|
47 | 94 |
)" |
48 | 95 |
done |
96 |
+ missing_setxml=$(sqlite_request "select name from aircrafts where id not in (select variantof from setxml)") |
|
97 |
+ if test -n "$missing_setxml"; then |
|
98 |
+ echo "missing setxml config: $missing_setxml" |
|
99 |
+ fi |
|
49 | 100 |
if test -r "$database" && md5sum $in_ram_database | sed "s,$in_ram_database,$database," | md5sum --status -c -; then |
50 | 101 |
rm -f $in_ram_database |
51 | 102 |
echo "no changes in $database" |
... | ... |
@@ -60,146 +111,317 @@ function trap_exit () { |
60 | 111 |
rm -f $in_ram_database |
61 | 112 |
echo "nothing can be done with $database !" |
62 | 113 |
fi |
63 |
- rm -f $aircrafts $aircraft $setxml |
|
64 | 114 |
} |
65 | 115 |
|
66 |
-update_database () { |
|
67 |
- let progress++ |
|
68 |
- echo "[ ${progress}${total:+/$total} ] $ac" |
|
116 |
+function register_state () { |
|
117 |
+set +x |
|
118 |
+ sqlite_request "drop table if exists recover_rev" |
|
119 |
+ sqlite_request "create table recover_rev ( |
|
120 |
+ revkey text, |
|
121 |
+ revision integer, |
|
122 |
+ revauthor text, |
|
123 |
+ revdate integer |
|
124 |
+ )" |
|
125 |
+ for revkey in ${!revision[@]}; do |
|
126 |
+ sqlite_request "insert into recover_rev values ( |
|
127 |
+ '$revkey', |
|
128 |
+ ${revision[$revkey]:-0}, |
|
129 |
+ '${revauthor[$revkey]}', |
|
130 |
+ ${revdate[$revkey]:-0} |
|
131 |
+ )" |
|
132 |
+ done |
|
133 |
+ sqlite_request "drop table if exists recover_setxmlmodified" |
|
134 |
+ sqlite_request "create table if not exists recover_setxmlmodified ( |
|
135 |
+ sx text |
|
136 |
+ )" |
|
137 |
+ for sx in ${!setxmlmodified[@]}; do |
|
138 |
+ sqlite_request "insert into recover_setxmlmodified values ( |
|
139 |
+ '$sx' |
|
140 |
+ )" |
|
141 |
+ done |
|
142 |
+ set +x |
|
143 |
+ exit |
|
144 |
+} |
|
145 |
+ |
|
146 |
+function update_database () { |
|
147 |
+ echo "[ ${#revision[@]} ] ${ac:1}" |
|
69 | 148 |
|
70 |
- dbupdate=$(sqlite_request "select revision from aircrafts where name is '$ac'") |
|
149 |
+ dbupdate=$(sqlite_request "select revision from aircrafts where name is '${ac:1}'") |
|
71 | 150 |
if test -z "$dbupdate"; then |
72 | 151 |
sqlite_request "insert into aircrafts (name, revision, date, author) |
73 |
- values ('$ac', ${revision[$ac]}, ${revdate[$ac]}, '${revauthor[$ac]}')" |
|
152 |
+ values ('${ac:1}', ${revision[$ac]}, ${revdate[$ac]}, '${revauthor[$ac]}')" |
|
74 | 153 |
elif test $dbupdate -lt ${revision[$ac]}; then |
75 | 154 |
sqlite_request "update aircrafts set |
76 | 155 |
revision = ${revision[$ac]}, |
77 | 156 |
author = '${revauthor[$ac]}', |
78 | 157 |
date = ${revdate[$ac]} |
79 |
- where name is '$ac'" |
|
158 |
+ where name is '${ac:1}'" |
|
80 | 159 |
fi |
81 |
- id=$(sqlite_request "select id from aircrafts where name is '$ac'") |
|
160 |
+ id=$(sqlite_request "select id from aircrafts where name is '${ac:1}'") |
|
82 | 161 |
|
83 |
- for sx in ${setxmlmodified[$ac]}; do |
|
84 |
- test -n "${_sx[$ac/$sx]}" && continue |
|
85 |
- _sx[$ac/$sx]="already done" |
|
86 |
- unset description long_description author flight_model in_sim |
|
162 |
+ for sx in ${!setxmlmodified[@]}; do |
|
163 |
+ unset include include_rootpath |
|
164 |
+ [[ "$sx" =~ ^"${ac:1}/" ]] || continue |
|
165 |
+ for col in ${!data[@]}; do |
|
166 |
+ data[$col]= |
|
167 |
+ done |
|
168 |
+ sx=${sx#*/} |
|
87 | 169 |
echo " -> $sx" |
88 |
- svn export --quiet --force --revision ${revision[$ac]} $fgaddon_svn/$ac/$sx-set.xml $setxml |
|
170 |
+ if ! svn export --quiet --force $fgaddon_svn/${ac:1}/$sx-set.xml $setxml; then |
|
171 |
+ register_state |
|
172 |
+ fi |
|
173 |
+ xmlremovecomments |
|
174 |
+ unset xmlgetnext_firstentry property |
|
89 | 175 |
while xmlgetnext; do |
90 |
- if [[ "$TAG" = @($attributes_case) ]]; then |
|
91 |
- test -n "$in_sim" && eval "${TAG//-/_}=\"$VALUE\"" |
|
92 |
- test -n "$description" \ |
|
93 |
- -a -n "$long_description" \ |
|
94 |
- -a -n "$author" \ |
|
95 |
- -a -n "$flight_model" \ |
|
96 |
- -a -n "$type" && break |
|
97 |
- elif test "$TAG" = 'sim'; then |
|
98 |
- in_sim=1 |
|
99 |
- elif test "$TAG" = '/sim'; then |
|
100 |
- break |
|
176 |
+ case "${TAG:0:1}" in |
|
177 |
+ ''|'?'|'!') |
|
178 |
+ continue;; |
|
179 |
+ /) |
|
180 |
+ property=${property%/*};; |
|
181 |
+ *) |
|
182 |
+ if test "${TAG: -1}" != '/'; then |
|
183 |
+ property+=/${TAG%% *} |
|
184 |
+ fi |
|
185 |
+# property+=/${TAG%% *} |
|
186 |
+# if test "${TAG: -1}" = '/'; then |
|
187 |
+# _TAG=${TAG:0:-1} |
|
188 |
+# test "${_TAG#* }" != "${_TAG}" && eval "${_TAG#* }" |
|
189 |
+# property=${property%/*} |
|
190 |
+# fi;; |
|
191 |
+ esac |
|
192 |
+ |
|
193 |
+ if [[ "$TAG" =~ ^"PropertyList include=" ]]; then |
|
194 |
+ include_rootpath=${include%/*} |
|
195 |
+ test $include = $include_rootpath && unset include_rootpath |
|
196 |
+ eval $(echo ${TAG#* }) |
|
197 |
+ [[ "$include" =~ ^Aircraft/Generic/ ]] && unset include include_rootpath && continue |
|
198 |
+ if [[ "$include" =~ ^'../' ]]; then |
|
199 |
+ if test -n "$include_rootpath"; then |
|
200 |
+ if [[ "$include_rootpath" =~ '/' ]]; then |
|
201 |
+ include_rootpath=${include_rootpath%/*} |
|
202 |
+ else |
|
203 |
+ unset include_rootpath |
|
204 |
+ fi |
|
205 |
+ else |
|
206 |
+ ac_save=$ac |
|
207 |
+ unset ac |
|
208 |
+ fi |
|
209 |
+ include=${include/\.\.\/} |
|
210 |
+ fi |
|
211 |
+ if ! svn cat $fgaddon_svn/${ac:1}/${include_rootpath:+$include_rootpath/}$include >> $setxml; then |
|
212 |
+ register_state |
|
213 |
+ fi |
|
214 |
+ xmlremovecomments |
|
215 |
+ fi |
|
216 |
+ |
|
217 |
+ if [[ "$property" = /PropertyList@($data_pattern) ]]; then |
|
218 |
+ eval "data[${property/\/PropertyList}]=\"${VALUE//\"/\\\"}\"" |
|
219 |
+ data[${property/\/PropertyList}]=$(tr '\n' ' ' <<< ${data[${property/\/PropertyList}]} | sed -r 's/^\s*//;s/\s+/ /g;s/\s*$//') |
|
101 | 220 |
fi |
102 |
- done < $setxml |
|
103 | 221 |
|
104 |
- test -z "$description" \ |
|
105 |
- -a -z "$long_description" \ |
|
106 |
- -a -z "$author" \ |
|
107 |
- -a -z "$flight_model" \ |
|
108 |
- -a -z "$type" && echo "WARNING: no info found, skipping" && continue |
|
222 |
+ if test -n "$_TAG"; then |
|
223 |
+ # _TAG non-null means xml props ends with / |
|
224 |
+ # need to go back of last property |
|
225 |
+ property=${property/%\/${_TAG%% *}} |
|
226 |
+ unset _TAG |
|
227 |
+ fi |
|
109 | 228 |
|
110 |
- if test -n "$description" -a -z "$flight_model"; then |
|
111 |
- grep -qi 'jsbsim' <<< "$description" && flight_model='jsb' |
|
112 |
- grep -qi 'yasim' <<< "$description" && flight_model='yasim' |
|
113 |
- fi |
|
229 |
+ # continue parsing (while loop) until everything's found |
|
230 |
+ for col in ${!data[@]}; do |
|
231 |
+ test -z "${data[$col]}" && continue 2 |
|
232 |
+ done |
|
233 |
+ break # everything's found |
|
234 |
+ done < $setxml |
|
114 | 235 |
|
115 |
- if test -n "$long_description"; then |
|
116 |
- long_description=$(sed 's/^\s*//g' <<< $long_description | tr '\n' ' ') |
|
236 |
+ if eval "test -z \"$data_test_null\""; then |
|
237 |
+ echo "WARNING: no info found, skipping" |
|
238 |
+ continue |
|
117 | 239 |
fi |
118 | 240 |
|
119 | 241 |
known=$(sqlite_request "select variantof from setxml where file is '$sx'") |
120 | 242 |
if test -n "$known"; then |
121 |
- for attribute in ${attributes[@]}; do |
|
122 |
- dbvalue=$(sqlite_request "select $attribute from setxml where file is '$sx'") |
|
123 |
- eval "wgvalue=\$$attribute" |
|
124 |
- if test "$dbvalue" != "$wgvalue" -a -n "$wgvalue"; then |
|
125 |
- sqlite_request "update setxml set $attribute = '$wgvalue' where file is '$sx'" |
|
243 |
+ for col in ${!data[@]}; do |
|
244 |
+ dbvalue=$(sqlite_request "select '$col' |
|
245 |
+ from setxml |
|
246 |
+ where file is '$sx' and variantof = $known") |
|
247 |
+ if test "$dbvalue" != "${data[$col]}" -a -n "${data[$col]}"; then |
|
248 |
+ sqlite_request "update setxml |
|
249 |
+ set '$col' = '${data[$col]//\'/\'\'}' |
|
250 |
+ where file is '$sx' and variantof = $known" |
|
126 | 251 |
fi |
127 | 252 |
done |
128 | 253 |
else |
129 |
- sqlite_request "insert into setxml values ('$sx', $id, '$description', '$long_description', '$author', '$type', '$flight_model', 0)" |
|
254 |
+ values="'$sx', $id, " |
|
255 |
+ for col in ${!data[@]}; do |
|
256 |
+ values+="'${data[$col]//\'/\'\'}', " |
|
257 |
+ done |
|
258 |
+ values+=0 |
|
259 |
+ sqlite_request "insert into setxml values ($values)" |
|
260 |
+ fi |
|
261 |
+ test -n "$ac_save" && ac=$ac_save |
|
262 |
+ unset setxmlmodified[${ac:1}/$sx] |
|
263 |
+ done |
|
264 |
+ unset revision[$ac] |
|
265 |
+} |
|
266 |
+ |
|
267 |
+function apply_revision () { |
|
268 |
+ for ac in "${!revision[@]}"; do |
|
269 |
+ update_database |
|
270 |
+ if test -d $fgaddon_path/${ac:1}/.svn \ |
|
271 |
+ && test "$(svn info --show-item=url $fgaddon_path/${ac:1})" != "$fgaddon_svn/${ac:1}" \ |
|
272 |
+ || test -d $fgaddon_path/${ac:1} -a ! -d $fgaddon_path/${ac:1}/.svn; then |
|
273 |
+ echo "INFO: local ${ac:1} installed out from repo" >&2 |
|
130 | 274 |
fi |
131 | 275 |
done |
132 | 276 |
} |
133 | 277 |
|
278 |
+trap trap_break INT |
|
134 | 279 |
trap trap_exit EXIT |
135 | 280 |
|
136 |
-test -e $database && cp $database $in_ram_database |
|
281 |
+stty -echoctl |
|
282 |
+ |
|
283 |
+declare -A revision revauthor revdate setxmlmodified files revpath |
|
284 |
+data_pattern=$(printf "%s|" ${!data[@]}) |
|
285 |
+data_pattern=${data_pattern:0:-1} |
|
286 |
+data_test_null=$(printf '${data[%s]}' ${!data[@]}) |
|
287 |
+ |
|
288 |
+if test -e $database; then |
|
289 |
+ cp $database $in_ram_database |
|
290 |
+ sql_cols=$(sqlite_request "pragma table_info(setxml)" | awk -F'|' '{printf("%s %s ", $2, $3)}') |
|
291 |
+ script_cols="file text variantof integer " |
|
292 |
+ for col in ${!data[@]}; do |
|
293 |
+ script_cols+="$col ${data["$col"]} " |
|
294 |
+ done |
|
295 |
+ script_cols+="installed integer " # last space is important |
|
296 |
+ if test "$sql_cols" != "$script_cols"; then |
|
297 |
+ echo "ALERT: datbase version mismatch !" |
|
298 |
+ exit 1 |
|
299 |
+ fi |
|
300 |
+ if sqlite_request '.tables' | grep -q 'recover_' && test -z "$1"; then |
|
301 |
+ echo "recovering from previous saved state" |
|
302 |
+ eval $(sqlite_request "select printf('revision[%s]=%u;revauthor[%s]=%s;revdate[%s]=%u;', |
|
303 |
+ revkey, revision, |
|
304 |
+ revkey, revauthor, |
|
305 |
+ revkey, revdate) |
|
306 |
+ from recover_rev") |
|
307 |
+ eval $(sqlite_request "select printf('setxmlmodified[%s]=1;', sx) |
|
308 |
+ from recover_setxmlmodified") |
|
309 |
+ sqlite_request "drop table recover_rev" |
|
310 |
+ sqlite_request "drop table recover_setxmlmodified" |
|
311 |
+ apply_revision |
|
312 |
+ exit |
|
313 |
+ fi |
|
314 |
+fi |
|
315 |
+ |
|
316 |
+sqlite_request "create table if not exists aircrafts ( |
|
317 |
+ id integer primary key, |
|
318 |
+ name text, |
|
319 |
+ revision integer, |
|
320 |
+ date integer, |
|
321 |
+ author text)" |
|
137 | 322 |
|
138 |
-sqlite_request "create table if not exists aircrafts (id integer primary key, name text, revision integer, date integer, author text)" |
|
139 |
-sqlite_request "create table if not exists setxml (file text, variantof integer, description text, long_description text, author text, type text, flight_model text, installed integer)" |
|
323 |
+sqlite_request "create table if not exists setxml ( |
|
324 |
+ file text, |
|
325 |
+ variantof integer, |
|
326 |
+ $(for col in ${!data[@]}; do printf "'%s' %s, " $col ${data[$col]}; done) |
|
327 |
+ installed integer)" |
|
140 | 328 |
|
141 |
-attributes_case=$(printf "%s|" "${attributes[@]}") |
|
142 |
-attributes_case=${attributes_case:0:-1} |
|
143 | 329 |
latest_revision=$(sqlite_request "select max(revision) from aircrafts") |
144 | 330 |
|
331 |
+# for debugging purpose |
|
332 |
+if test -n "$2"; then |
|
333 |
+ ac=_${1%/*} |
|
334 |
+ revision[$ac]=1 |
|
335 |
+ revdate[$ac]=0 |
|
336 |
+ revauthor[$ac]=foobar |
|
337 |
+ setxmlmodified[${ac:1}/${1#*/}]=1 |
|
338 |
+ set -x |
|
339 |
+ update_database |
|
340 |
+ set +x |
|
341 |
+ exit |
|
342 |
+elif test -n "$1"; then |
|
343 |
+ ac=_${1%/*} |
|
344 |
+ eval $(sqlite_request "select printf('revision[_%s]=%s;revdate[_%s]=%i;revauthor[_%s]=%s;', |
|
345 |
+ name, revision, |
|
346 |
+ name, date, |
|
347 |
+ name, author) |
|
348 |
+ from aircrafts |
|
349 |
+ where name = '${ac:1}'") |
|
350 |
+ setxmlmodified[${ac:1}/${1#*/}]=1 |
|
351 |
+ if test -z "${revision[$ac]}"; then |
|
352 |
+ echo "aircraft ${ac:1} not found" |
|
353 |
+ rm $in_ram_database |
|
354 |
+ exit |
|
355 |
+ fi |
|
356 |
+ update_database |
|
357 |
+ exit |
|
358 |
+fi |
|
359 |
+ |
|
145 | 360 |
echo "downloading FGADDON history from revision ${latest_revision:-0}" |
146 | 361 |
svn log --revision ${latest_revision:-0}:HEAD --xml --verbose $fgaddon_svn > $aircrafts |
147 | 362 |
|
363 |
+total=$(grep -c '<logentry' $aircrafts) |
|
364 |
+progress=0 |
|
365 |
+ |
|
366 |
+echo parsing history |
|
367 |
+ |
|
148 | 368 |
while xmlgetnext; do |
149 | 369 |
case "$TAG" in |
150 | 370 |
'logentry revision='*) |
151 | 371 |
eval $(echo ${TAG#* }) |
152 |
- unset revdate revauthor ac path_list setxmlmodified |
|
372 |
+ for action in ${!revpath[@]}; do |
|
373 |
+ unset revpath[$action] |
|
374 |
+ done |
|
153 | 375 |
;; |
154 | 376 |
'author') |
155 |
- revauthor=$VALUE |
|
377 |
+ revauthor=${VALUE//\'/\'\'} |
|
156 | 378 |
;; |
157 | 379 |
'date') |
158 | 380 |
revdate=$(date +%s -d "$VALUE") |
159 | 381 |
;; |
160 | 382 |
'path '*) |
161 |
- path_list[${#path_list[@]}]="$VALUE" |
|
383 |
+ TAG=${TAG#* } |
|
384 |
+ TAG=${TAG// /;} |
|
385 |
+ TAG=${TAG//-/_} |
|
386 |
+ eval $(echo ${TAG// /;}) |
|
387 |
+ path=(${VALUE//\// }) |
|
388 |
+ if test $kind = 'file' -a ${#path[@]} -gt 3; then |
|
389 |
+ revpath[$action]+="$VALUE " |
|
390 |
+ elif test $kind = 'dir' -a ${#path[@]} -eq 3 -a $action = 'D'; then |
|
391 |
+ files[_${path[2]}]=0 |
|
392 |
+ unset revision[_${path[2]}] revauthor[_${path[2]}] revdate[_${path[2]}] |
|
393 |
+ for sx in ${!setxmlmodified[@]}; do |
|
394 |
+ [[ "$sx" =~ "${path[2]}/" ]] && unset setxmlmodified[$sx] |
|
395 |
+ done |
|
396 |
+ fi |
|
162 | 397 |
;; |
163 | 398 |
'/logentry') |
164 |
- revlog[${#revlog[@]}]=$( |
|
165 |
- printf '%s\n' "${path_list[@]}" | awk -F/ -v revision=$revision -v revauthor=$revauthor -v revdate=$revdate -v dq='"' ' |
|
166 |
- { |
|
167 |
- a[$4]++ |
|
168 |
- if ($5 ~ "-set.xml$") b[$4]=b[$4] " " gensub("-set.xml$", "", "1", $5) |
|
169 |
- } |
|
170 |
- END { |
|
171 |
- for (i in a) |
|
172 |
- printf("<revision[%s]=%i;revauthor[%s]=%s;revdate[%s]=%i;%s>", |
|
173 |
- i, revision, |
|
174 |
- i, revauthor, |
|
175 |
- i, revdate, |
|
176 |
- b[i] != "" ? "setxmlmodified[" i "]=" dq gensub("^ ", "", "g", b[i]) " ${setxmlmodified[" i "]}" dq ";" : "") |
|
177 |
- }') |
|
178 |
- ;; |
|
179 |
- '/log') |
|
180 |
- unset revision revauthor revdate setxmlmodified |
|
181 |
- declare -A revision revauthor revdate setxmlmodified |
|
182 |
- analyse () { |
|
183 |
- while xmlgetnext; do |
|
184 |
- test -z "$TAG" -a ${#revision[@]} -eq 0 && continue |
|
185 |
- case $TAG in |
|
186 |
- 'BEGIN') continue;; |
|
187 |
- 'END' ) break 2;; |
|
188 |
- esac |
|
189 |
- echo $TAG |
|
190 |
- done <<< "<BEGIN>${revlog[@]}<END>" |
|
191 |
- } |
|
192 |
- eval $(analyse) |
|
193 |
- total=${#revision[@]} |
|
194 |
- declare -A _sx |
|
195 |
- for ac in "${!revision[@]}"; do |
|
196 |
- update_database |
|
197 |
- if test -d $fgaddon_path/$ac/.svn \ |
|
198 |
- && test "$(svn info --show-item=url $fgaddon_path/$ac)" != "$fgaddon_svn/$ac" \ |
|
199 |
- || test -d $fgaddon_path/$ac -a ! -d $fgaddon_path/$ac/.svn; then |
|
200 |
- echo "INFO: local $ac installed out from repo" >&2 |
|
399 |
+ for item in ${revpath[D]}; do |
|
400 |
+ path=(${item//\// }) |
|
401 |
+ [[ "${path[3]}" =~ "-set.xml" ]] && unset setxmlmodified[${path[2]}/${path[3]/-set.xml}] |
|
402 |
+ files[_${path[2]}]=$(( --files[_${path[2]}] )) |
|
403 |
+ if test ${files[_${path[2]}]} -le 0; then |
|
404 |
+ unset revision[_${path[2]}] revauthor[_${path[2]}] revdate[_${path[2]}] |
|
201 | 405 |
fi |
202 | 406 |
done |
407 |
+ for action in A M R; do |
|
408 |
+ for item in ${revpath[$action]}; do |
|
409 |
+ path=(${item//\// }) |
|
410 |
+ revision[_${path[2]}]=$revision |
|
411 |
+ revauthor[_${path[2]}]=$revauthor |
|
412 |
+ revdate[_${path[2]}]=$revdate |
|
413 |
+ [[ "${path[3]}" =~ "-set.xml" ]] && setxmlmodified[${path[2]}/${path[3]/-set.xml}]=1 |
|
414 |
+ test $action = 'A' && files[_${path[2]}]=$(( ++files[_${path[2]}] )) |
|
415 |
+ done |
|
416 |
+ done |
|
417 |
+ newprogress=$((++logentry * 100 / $total)) |
|
418 |
+ if test $(( $newprogress - $progress )) -ge ${progress_granularity:-1}; then |
|
419 |
+ progress=$newprogress |
|
420 |
+ echo "$progress% (${#revision[@]})" |
|
421 |
+ fi |
|
422 |
+ ;; |
|
423 |
+ '/log') |
|
424 |
+ apply_revision |
|
203 | 425 |
break |
204 | 426 |
;; |
205 | 427 |
esac |
... | ... |
@@ -157,9 +157,8 @@ function fgfs () { |
157 | 157 |
elif which sqlite3 > /dev/null 2>&1 \ |
158 | 158 |
&& test -r $FGADDON/fgaddon.db \ |
159 | 159 |
&& test $(sqlite3 $FGADDON/fgaddon.db <<< "select count(file) from setxml where file is '${fgfs_arg}'") -eq 1; then |
160 |
- model=$(sqlite3 $FGADDON/fgaddon.db <<< "select name from aircrafts inner join setxml on aircrafts.id = setxml.variantof where setxml.file is '${fgfs_arg}-set.xml'") |
|
160 |
+ model=$(sqlite3 $FGADDON/fgaddon.db <<< "select name from aircrafts inner join setxml on aircrafts.id = setxml.variantof where setxml.file is '${fgfs_arg}'") |
|
161 | 161 |
read -q "REPLY?download $model ? (y/N) " |
162 |
- read |
|
163 | 162 |
if test -n "$REPLY" && test ${REPLY:l} = "y"; then |
164 | 163 |
svn co https://svn.code.sf.net/p/flightgear/fgaddon/trunk/Aircraft/$model $FGADDON/Aircraft/$model |
165 | 164 |
fgfs_args+=("--aircraft=$fgfs_arg") |