]> git.xonotic.org Git - xonotic/xonotic.git/blob - all
mirror selection: bail out if "time" does not exist
[xonotic/xonotic.git] / all
1 #!/bin/sh
2 # vim: filetype=zsh
3
4 set -e
5
6 # I use this in EVERY shell script ;)
7 LF="
8 "
9 ESC="\e"
10
11 d00=`pwd`
12 while ! [ -f ./all ]; do
13         if [ x"`pwd`" = x"/" ]; then
14                 echo "Cannot find myself."
15                 echo "Please run this script with the working directory inside a Xonotic checkout."
16                 exit 1
17         fi
18         cd ..
19 done
20 export d0=`pwd`
21 SELF="$d0/all"
22
23 # If we are on WINDOWS:
24 case "$0" in
25         all|*/all)
26                 case "`uname`" in
27                         MINGW*|Win*)
28                                 # Windows hates users. So this script has to copy itself elsewhere first...
29                                 cp "$SELF" ../all.xonotic.sh
30                                 export WE_HATE_OUR_USERS=1
31                                 exec ../all.xonotic.sh "$@"
32                                 ;;
33                 esac
34                 ;;
35 esac
36
37 msg()
38 {
39         echo >&2 "$ESC[1m$*$ESC[m"
40 }
41
42 self=`git hash-object "$SELF"`
43 checkself()
44 {
45         self_new=`git hash-object "$SELF"`
46         if [ x"$self" != x"$self_new" ]; then
47                 msg "./all has changed."
48                 if [ -z "$XONOTIC_FORBID_RERUN_ALL" ]; then
49                         msg "Rerunning the requested operation to make sure."
50                         export XONOTIC_FORBID_RERUN_ALL=1
51                         exec "$SELF" "$@"
52                 else
53                         msg "Please try $SELF update, and then retry your requested operation."
54                         exit 1
55                 fi
56         fi
57         return 0
58 }
59
60 verbose()
61 {
62         msg "+ $*"
63         "$@"
64 }
65
66 visible_repo_name()
67 {
68         case "$1" in
69                 .)
70                         echo "the root directory"
71                         ;;
72                 *)
73                         echo "\"$1\""
74                         ;;
75         esac
76 }
77
78 check_mergeconflict()
79 {
80         if git ls-files -u | grep ' 1   '; then
81                 echo
82                 echo "MERGE CONFLICT."
83                 echo "change into the \"$1\" project directory, and then:"
84                 echo "- edit the files mentioned above with your favorite editor,"
85                 echo "  and fix the conflicts (marked with <<<<<<< blocks)"
86                 echo "- for binary files, you can select the files using"
87                 echo "  git checkout --ours or git checkout --theirs"
88                 echo "- when done with a file, 'git add' the file"
89                 echo "- when done, 'git commit'"
90                 echo
91                 exit 1
92         fi
93 }
94
95 yesno()
96 {
97         yesno=
98         while [ x"$yesno" != x"y" -a x"$yesno" != x"n" ]; do
99                 eval "$2"
100                 echo "$1"
101                 IFS= read -r yesno
102         done
103         [ x"$yesno" = x"y" ]
104 }
105
106 enter()
107 {
108         $2 cd "$1" || exit 1
109         check_mergeconflict "$1"
110 }
111
112 repos_urls="
113 .                             |                                                   | master         |
114 data/xonotic-data.pk3dir      |                                                   | master         |
115 data/xonotic-music.pk3dir     |                                                   | master         |
116 data/xonotic-nexcompat.pk3dir |                                                   | master         | no
117 darkplaces                    |                                                   | div0-stable    | svn
118 netradiant                    |                                                   | master         |
119 div0-gittools                 |                                                   | master         | no
120 d0_blind_id                   |                                                   | master         |
121 data/xonotic-maps.pk3dir      |                                                   | master         |
122 mediasource                   |                                                   | master         | no
123 fteqcc                        |                                                   | xonotic-stable | noautocrlf
124 "
125 # todo: in darkplaces, change repobranch to div0-stable
126
127 repos=`echo "$repos_urls" | grep . | cut -d '|' -f 1 | tr -d ' '`
128
129 base=`git config remote.origin.url`
130 case "$base" in
131         */xonotic.git)
132                 base=${base%xonotic.git}
133                 ;;
134         *)
135                 echo "The main repo is not xonotic.git, what have you done?"
136                 exit 1
137                 ;;
138 esac
139 pushbase=`git config remote.origin.pushurl || true`
140 case "$pushbase" in
141         */xonotic.git)
142                 pushbase=${pushbase%xonotic.git}
143                 ;;
144         '')
145                 ;;
146         *)
147                 echo "The main repo is not xonotic.git, what have you done?"
148                 exit 1
149                 ;;
150 esac
151
152 repourl()
153 {
154         repo_t=`echo "$repos_urls" | grep "^$1 " | cut -d '|' -f 2 | tr -d ' '`
155         if [ -n "$repo_t" ]; then
156                 case "$repo_t" in
157                         *://*)
158                                 echo "$repo_t"
159                                 ;;
160                         *)
161                                 echo "$base$repo_t"
162                                 ;;
163                 esac
164         else
165                 if [ x"$1" = x"." ]; then
166                         echo "$base""xonotic.git"
167                 else
168                         echo "$base${1##*/}.git"
169                 fi
170         fi
171 }
172
173 repopushurl()
174 {
175         [ -n "$pushbase" ] || return 0
176         repo_t=`echo "$repos_urls" | grep "^$1 " | cut -d '|' -f 2 | tr -d ' '`
177         if [ -n "$repo_t" ]; then
178                 case "$repo_t" in
179                         *://*)
180                                 ;;
181                         *)
182                                 echo "$pushbase$repo_t"
183                                 ;;
184                 esac
185         else
186                 if [ x"$1" = x"." ]; then
187                         echo "$pushbase""xonotic.git"
188                 else
189                         echo "$pushbase${1##*/}.git"
190                 fi
191         fi
192 }
193
194 repobranch()
195 {
196         repo_t=`echo "$repos_urls" | grep "^$1 " | cut -d '|' -f 3 | tr -d ' '`
197         if [ -n "$repo_t" ]; then
198                 echo "$repo_t"
199         else
200                 echo "master"
201         fi
202 }
203
204 repoflags()
205 {
206         echo "$repos_urls" | grep "^$1 " | cut -d '|' -f 4 | tr -d ' '
207 }
208
209 listrepos()
210 {
211         for d in $repos; do
212                 p="${d%dir}"
213                 f="`repoflags "$d"`"
214                 # if we have the dir, always keep it
215                 if [ -d "$d" ]; then
216                         msg "Repository $d enabled because it already exists"
217                         echo "$d"
218                         continue
219                 fi
220                 # if .yes file exists, always keep it
221                 if [ -f "$d.yes" ]; then
222                         msg "Repository $d enabled by a .yes file"
223                         echo "$d"
224                         continue
225                 fi
226                 # if we have .no file, skip
227                 if [ -f "$d.no" ]; then
228                         msg "Repository $d disabled by a .no file, delete $p.no to enable"
229                         continue
230                 fi
231                 # if we have matching pk3, skip
232                 if [ x"$p" != x"$d" ] && [ -f "$p" ]; then
233                         msg "Repository $d disabled by matching .pk3 file, delete $p or create $d.yes to enable"
234                         continue
235                 fi
236                 # if "no" flag is set, skip
237                 case ",$f," in
238                         *,no,*)
239                                 msg "Repository $d disabled by default, create $d.yes to enable"
240                                 continue
241                                 ;;
242                 esac
243                 # default: enable
244                 msg "Repository $d enabled by default"
245                 echo "$d"
246         done
247 }
248
249 repos=`listrepos`
250
251 if [ "$#" = 0 ]; then
252         set -- help
253 fi
254 cmd=$1
255 shift
256
257 fix_upstream_rebase()
258 {
259         if [ -z "$r_me" ] || [ -z "$r_other" ]; then
260                 return
261         fi
262         r_base=`git merge-base "$r_me" "$r_other"`
263
264         # no merge-base? upstream did filter-branch
265         if [ -n "$r_base" ]; then
266                 # otherwise, check if the two histories are "similar"
267                 r_l_me=`git log --pretty="format:%s" "$r_other".."$r_me" | grep -v "^Merge" | sort -u`
268                 r_l_other=`git log --pretty="format:%s" "$r_me".."$r_other" | grep -v "^Merge" | sort -u`
269
270                 # heuristics: upstream rebase/filter-branch if more than 50% of the commits of one of the sides are in the other too
271                 r_lc_me=`echo "$r_l_me" | wc -l`
272                 r_lc_other=`echo "$r_l_other" | wc -l`
273                 r_lc_together=`{ echo "$r_l_me"; echo "$r_l_other"; } | sort -u | wc -l`
274                 r_lc_same=$(($r_lc_me + $r_lc_other - $r_lc_together))
275
276                 if [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_me )) ] || [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_other )) ]; then
277                         if yesno "Probable upstream rebase detected, automatically fix?" 'git log --oneline --graph --date-order --left-right "$r_other"..."$r_me"'; then
278                                 git reset --hard "$r_me"
279                                 git pull --rebase
280                                 return 1
281                         fi
282                 fi
283         fi
284
285         return 0
286 }
287
288 fix_upstream_rebase_mergeok()
289 {
290         r_me=`git rev-parse --revs-only HEAD^1 2>/dev/null || true`
291         r_other=`git rev-parse --revs-only HEAD^2 2>/dev/null || true`
292         fix_upstream_rebase
293 }
294
295 fix_upstream_rebase_mergefail()
296 {
297         r_me=`git rev-parse --revs-only HEAD 2>/dev/null || true`
298         r_other=`git rev-parse --revs-only MERGE_HEAD 2>/dev/null || true`
299         fix_upstream_rebase
300 }
301
302 fix_git_config()
303 {
304         verbose git config remote.origin.url "$1"
305         if [ -n "$2" ]; then
306                 verbose git config remote.origin.pushurl "$2"
307         else
308                 verbose git config --unset remote.origin.pushurl || true
309         fi
310         verbose git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
311         case ",`repoflags "$d"`," in
312                 *,noautocrlf,*)
313                         verbose git config --unset core.autocrlf || true
314                         ;;
315                 *)
316                         verbose git config core.autocrlf input
317                         ;;
318         esac
319         if [ -z "`git config push.default || true`" ]; then
320                 verbose git config push.default current # or is tracking better?
321         fi
322         verbose git config filter.mapclean.clean "tr -d '\r' | grep '^[^/]'"
323         verbose git config filter.mapclean.smudge "cat"
324 }
325
326 mkzip()
327 {
328         archive=$1
329         shift
330         ziplist=`mktemp`
331         find "$@" -xtype f \( -executable -or -type l \) -print > "$ziplist"
332         7za a -tzip -mx=9 -x@"$ziplist" "$archive" "$@" || true
333         zip         -9y   -@<"$ziplist" "$archive"      || true
334         rm -f "$ziplist"
335 }
336
337 mkzip0()
338 {
339         zip -0y "$@"
340 }
341
342 mirrorspeed()
343 {
344         # first result is to be ignored, but we use it to check status
345         git ls-remote "$1" refs/heads/master >/dev/null 2>&1 || return 1
346         { time -p git ls-remote "$1" refs/heads/master; } 2>&1 >/dev/null | head -n 1 | cut -d ' ' -f 2 | tr -d . | sed 's,^0*,,'
347                 # unit: clock ticks (depends on what "time" returns
348 }
349
350 bestmirror()
351 {
352         pre=$1; shift
353         suf=$1; shift
354
355         if ! { time -p true; } >/dev/null 2>&1; then
356                 return 1
357         fi
358
359         bestin=
360         bestt=
361         for in in "$@"; do
362                 m=$pre$in$suf
363                 if t=`mirrorspeed "$m"`; then
364                         msg "$m -> $t ticks"
365                         if [ -n "$t" ]; then
366                                 if [ -z "$bestt" ] || [ "$t" -lt "$bestt" ]; then
367                                         bestin=$in
368                                         bestt=$t
369                                 fi
370                         fi
371                 else
372                         msg "$m -> FAIL"
373                 fi
374         done
375         if [ -n "$bestin" ]; then
376                 msg "Best mirror seems to be $pre$bestin$suf"
377                 echo "$bestin"
378         else
379                 return 1
380         fi
381 }
382
383 case "$cmd" in
384         fix_upstream_rebase)
385                 for d in $repos; do
386                         enter "$d0/$d" verbose
387                         verbose fix_upstream_rebase_mergefail && verbose fix_upstream_rebase_mergeok
388                 done
389                 ;;
390         fix_config)
391                 for d in $repos; do
392                         url=`repourl "$d"`
393                         pushurl=`repopushurl "$d"`
394                         branch=`repobranch "$d"`
395                         if [ -d "$d0/$d" ]; then
396                                 verbose cd "$d0/$d"
397                                 fix_git_config "$url" "$pushurl"
398                                 cd "$d0"
399                         fi
400                 done
401                 ;;
402         keygen)
403                 # enable the ssh URL for pushing
404                 "$SELF" update -N -p
405
406                 if [ -f ~/.ssh/id_rsa.pub ]; then
407                         msg ""
408                         msg "A key already exists and no new one will be generated. If you"
409                         msg "already have done the procedure for getting your key approved, you"
410                         msg "can skip the following paragraph and already use the repository."
411                         msg ""
412                         msg "To get access, your key has to be approved first. For that, visit"
413                         msg "http://dev.xonotic.org/, then log in, create a \"New Issue\" on"
414                         msg "the \"Support\" tracker in the \"Repository\" category where you"
415                         msg "apply for access and paste the following output into the issue:"
416                         msg ""
417                         msg "`cat ~/.ssh/id_rsa.pub`"
418                         msg ""
419                         msg "Note that you will only have write access to branches that start"
420                         msg "with your user name."
421                 elif [ -f ~/.ssh/id_dsa.pub ]; then
422                         msg ""
423                         msg "A key already exists and no new one will be generated. If you"
424                         msg "already have done the procedure for getting your key approved, you"
425                         msg "can skip the following paragraph and already use the repository."
426                         msg ""
427                         msg "To get access, your key has to be approved first. For that, visit"
428                         msg "http://dev.xonotic.org/, then log in, create a \"New Issue\" on"
429                         msg "the \"Support\" tracker in the \"Repository\" category where you"
430                         msg "apply for access and paste the following output into the issue:"
431                         msg ""
432                         msg "`cat ~/.ssh/id_dsa.pub`"
433                         msg ""
434                         msg "Note that you will only have write access to branches that start"
435                         msg "with your user name."
436                 else
437                         msg ""
438                         msg "No key has been generated yet. One will be generated now."
439                         msg "If other people are using your computer, it is recommended"
440                         msg "to specify a passphrase. Otherwise you can simply hit ENTER"
441                         msg "when asked for a passphrase."
442                         msg ""
443                         ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
444                         msg ""
445                         msg "To get access, your key has to be approved first. For that, visit"
446                         msg "http://dev.xonotic.org/, then log in, create a \"New Issue\" on"
447                         msg "the \"Support\" tracker in the \"Repository\" category where you"
448                         msg "apply for access and paste the following output into the issue:"
449                         msg ""
450                         msg "`cat ~/.ssh/id_rsa.pub`"
451                         msg ""
452                         msg "Note that you will only have write access to branches that start"
453                         msg "with your user name."
454                 fi
455                 ;;
456         update|pull)
457                 allow_pull=true
458                 fix_config=false
459                 location=current
460                 while :; do
461                         if [ x"$1" = x"-N" ]; then
462                                 allow_pull=false
463                         elif [ x"$1" = x"-p" ]; then
464                                 fix_config=true
465                                 if [ x"$base" != x"ssh://xonotic@git.xonotic.org/" ]; then
466                                         pushbase=ssh://xonotic@git.xonotic.org/
467                                 fi
468                         elif [ x"$1" = x"-s" ]; then
469                                 fix_config=true
470                                 base=ssh://xonotic@git.xonotic.org/
471                                 pushbase=
472                         elif [ x"$1" = x"-g" ]; then
473                                 fix_config=true
474                                 base=git://git.xonotic.org/xonotic/
475                         elif [ x"$1" = x"-h" ]; then
476                                 fix_config=true
477                                 base=http://git.xonotic.org/xonotic/
478                         elif [ x"$1" = x"-l" ]; then
479                                 case "$2" in
480                                         nl) ;;
481                                         de) ;;
482                                         best) ;;
483                                         default) ;;
484                                         *)
485                                                 msg "Invalid location!"
486                                                 msg "Possible locations for the -l option:"
487                                                 msg "  nl (Netherlands, run by merlijn)"
488                                                 msg "  de (Germany, run by divVerent)"
489                                                 msg "  best (find automatically)"
490                                                 msg "  default (currently nl)"
491                                                 exit 1
492                                                 ;;
493                                 esac
494                                 fix_config=true
495                                 location=$2
496                                 shift
497                         else
498                                 break
499                         fi
500                         shift
501                 done
502                 case "$location" in
503                         default)
504                                 location=
505                                 ;;
506                         current)
507                                 case "$base" in
508                                         *://*.git.xonotic.org/*)
509                                                 location=${base%%.git.xonotic.org/*}
510                                                 location=${location##*://}
511                                                 ;;
512                                         *)
513                                                 location=
514                                                 ;;
515                                 esac
516                                 ;;
517                         best)
518                                 base=`echo "$base" | sed "s,://\(.*\.\)\?git.xonotic.org/,:// .git.xonotic.org/,"`
519                                 case "$base" in
520                                         *\ *)
521                                                 if location=`bestmirror $base"xonotic.git" de nl`; then
522                                                         :
523                                                 else
524                                                         location=
525                                                 fi
526                                                 ;;
527                                         *)
528                                                 location=
529                                                 ;;
530                                 esac
531                                 ;;
532                 esac
533                 if [ -n "$location" ]; then
534                         base=`echo "$base" | sed "s,://\(.*\.\)\?git.xonotic.org/,://$location.git.xonotic.org/,"`
535                         pushbase=`echo "$pushbase" | sed "s,://\(.*\.\)\?git.xonotic.org/,://$location.git.xonotic.org/,"`
536                 else
537                         base=`echo "$base" | sed "s,://\(.*\.\)\?git.xonotic.org/,://git.xonotic.org/,"`
538                         pushbase=`echo "$pushbase" | sed "s,://\(.*\.\)\?git.xonotic.org/,://git.xonotic.org/,"`
539                 fi
540                 if $fix_config; then
541                         url=`repourl .`
542                         pushurl=`repopushurl .`
543                         fix_git_config "$url" "$pushurl"
544                 fi
545                 if $allow_pull || $fix_config; then
546                         "$SELF" fix_config
547                 fi
548                 for d in $repos; do
549                         url=`repourl "$d"`
550                         pushurl=`repopushurl "$d"`
551                         branch=`repobranch "$d"`
552                         if [ -d "$d0/$d" ]; then
553                                 if $allow_pull; then
554                                         enter "$d0/$d" verbose
555                                         r=`git symbolic-ref HEAD`
556                                         r=${r#refs/heads/}
557                                         if git config branch.$r.remote >/dev/null 2>&1; then
558                                                 if ! verbose git pull; then
559                                                         fix_upstream_rebase_mergefail || true
560                                                         check_mergeconflict "$d"
561                                                         echo "Pulling failed. Press ENTER to continue, or Ctrl-C to abort."
562                                                         read -r DUMMY
563                                                 else
564                                                         fix_upstream_rebase_mergeok || true
565                                                 fi
566                                         fi
567
568                                         cd "$d00"
569                                         checkself "$cmd" "$@"
570                                         cd "$d0/$d"
571                                         verbose git remote prune origin
572                                         cd "$d0"
573                                 fi
574                         else
575                                 verbose git clone "$url" "$d0/$d"
576                                 enter "$d0/$d" verbose
577                                 fix_git_config "$url" "$pushurl"
578                                 if [ "$branch" != "master" ]; then
579                                         verbose git checkout --track -b "$branch" origin/"$branch"
580                                 fi
581                                 cd "$d0"
582                         fi
583                 done
584                 ;;
585         update-maps)
586                 misc/tools/xonotic-map-compiler-autobuild download
587                 ;;
588         checkout|switch)
589                 checkoutflags=
590                 if [ x"$1" = x"-f" ]; then
591                         checkoutflags=-f
592                         shift
593                 fi
594                 remote=$1
595                 branch=$2
596                 if [ -z "$branch" ]; then
597                         case "$remote" in
598                                 origin/*)
599                                         branch=${remote#origin/}
600                                         remote=origin
601                                         ;;
602                                 *)
603                                         branch=$remote
604                                         remote=origin
605                                         ;;
606                         esac
607                 fi
608                 exists=false
609                 for d in $repos; do
610                         enter "$d0/$d" verbose
611                         b=$branch
612                         if [ -n "$b" ] && git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
613                                 exists=true
614                                 verbose git checkout $checkoutflags "$b"
615                         elif [ -n "$b" ] && git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
616                                 exists=true
617                                 verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
618                         else
619                                 b=`repobranch "$d"`
620                                 if git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
621                                         exists=true
622                                         verbose git checkout $checkoutflags "$b"
623                                 elif git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
624                                         exists=true
625                                         verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
626                                 else
627                                         echo "WTF? Not even branch $b doesn't exist in $d"
628                                         exit 1
629                                 fi
630                         fi
631                         cd "$d00"
632                         checkself "$cmd" "$@"
633                         cd "$d0"
634                 done
635                 if ! $exists; then
636                         echo "The requested branch was not found in any repository."
637                 fi
638                 exec "$SELF" branch
639                 ;;
640         branch)
641                 remote=$1
642                 branch=$2
643                 srcbranch=$3
644                 if [ -z "$branch" ]; then
645                         branch=$remote
646                         remote=origin
647                 fi
648                 if [ -z "$branch" ]; then
649                         for d in $repos; do
650                                 enter "$d0/$d"
651                                 r=`git symbolic-ref HEAD`
652                                 r=${r#refs/heads/}
653                                 echo "$d is at $r"
654                                 cd "$d0"
655                         done
656                 else
657                         for d in $repos; do
658                                 dv=`visible_repo_name "$d"`
659                                 enter "$d0/$d" verbose
660                                 if git rev-parse "refs/heads/$branch" >/dev/null 2>&1; then
661                                         echo "Already having this branch in $dv."
662                                 else
663                                         if yesno "Branch in $dv?"; then
664                                                 if [ -n "$srcbranch" ]; then
665                                                         b=$srcbranch
666                                                 else
667                                                         b=origin/"`repobranch "$d"`"
668                                                         verbose git fetch origin || true
669                                                 fi
670                                                 # TODO do this without pushing
671                                                 verbose git checkout -b "$branch" "$b"
672                                                 verbose git config "branch.$branch.remote" "$remote"
673                                                 verbose git config "branch.$branch.merge" "refs/heads/$branch"
674                                         fi
675                                 fi
676                                 cd "$d0"
677                         done
678                         "$SELF" branch
679                 fi
680                 ;;
681         branches)
682                 for d in $repos; do
683                         cd "$d0/$d" # am in a pipe, shouldn't use enter
684                         git branch -r -v -v | cut -c 3- | sed "s/^(no branch)/(no_branch)/" | sed "s,^,$d ,"
685                         cd "$d0"
686                 done | {
687                         branches_list=
688                         # branches_repos_*=
689                         while read -r d BRANCH REV TEXT; do
690                                 if [ x"$BRANCH" = x"`repobranch "$d"`" ]; then
691                                         continue
692                                 fi
693                                 if [ x"$REV" = x"->" ]; then
694                                         continue
695                                 fi
696                                 BRANCH=${BRANCH#remotes/}
697                                 ID=`echo "$BRANCH" | tr -c "A-Za-z0-9." "_"`
698                                 branches_list="$branches_list $BRANCH" # TEH SORT MAKEZ IT UNIEQ
699                                 eval "r=\$branches_repos_$ID"
700                                 r="$r $d"
701                                 eval "branches_repos_$ID=\$r"
702                         done
703                         echo -n "$branches_list" | xargs -n 1 echo | sort -u | while IFS= read -r BRANCH; do
704                                 ID=`echo "$BRANCH" | tr -c "A-Za-z0-9." "_"`
705                                 eval "r=\$branches_repos_$ID"
706                                 printf "%-60s %s\n" "$BRANCH" "$r"
707                                 #echo "$BRANCH: $r"
708                         done
709                 }
710                 ;;
711         merge)
712                 for d in $repos; do
713                         dv=`visible_repo_name "$d"`
714                         enter "$d0/$d" verbose
715                         r=`git symbolic-ref HEAD`
716                         r=${r#refs/heads/}
717                         if git log HEAD..origin/"`repobranch "$d"`" | grep .; then
718                                 # we have uncommitted changes
719                                 if yesno "Could merge from \"`repobranch "$d"`\" into \"$r\" in $dv. Do it?"; then
720                                         if ! verbose git merge origin/"`repobranch "$d"`"; then
721                                                 check_mergeconflict "$d"
722                                                 exit 1 # this should ALWAYS be fatal
723                                         fi
724                                 fi
725                         fi
726                         cd "$d0"
727                 done
728                 ;;
729         push|commit)
730                 submit=$1
731                 for d in $repos; do
732                         dv=`visible_repo_name "$d"`
733                         enter "$d0/$d" verbose
734                         r=`git symbolic-ref HEAD`
735                         r=${r#refs/heads/}
736                         diffdata=`git diff --color HEAD`
737                         if [ -n "$diffdata" ]; then
738                                 # we have uncommitted changes
739                                 if yesno "Uncommitted changes in \"$r\" in $dv. Commit?" 'echo "$diffdata" | less -r'; then
740                                         verbose git commit -a
741                                 fi
742                         fi
743                         rem=`git config "branch.$r.remote" || echo origin`
744                         bra=`git config "branch.$r.merge" || echo "$r"`
745                         upstream="$rem/${bra#refs/heads/}"
746                         if ! git rev-parse "$upstream" >/dev/null 2>&1; then
747                                 upstream="origin/`repobranch "$d"`"
748                         fi
749                         logdata=`git log --color "$upstream".."$r"`
750                         if [ -n "$logdata" ]; then
751                                 if yesno "Push \"$r\" in $dv?" 'echo "$logdata" | less -r'; then
752                                         verbose git push "$rem" HEAD
753                                 fi
754                         fi
755                         if [ x"$submit" = x"-s" ]; then
756                                 case "$r" in
757                                         */*)
758                                                 verbose git push "$rem" HEAD:"${bra%%/*}/finished/${bra#*/}"
759                                                 ;;
760                                 esac
761                         fi
762                         cd "$d0"
763                 done
764                 ;;
765         compile)
766                 cleand0=false
767                 cleandp=false
768                 cleanqcc=false
769                 cleanqc=false
770                 compiled0=false
771                 debug=debug
772                 snowleopardhack=false
773                 if [ -z "$CC" ]; then
774                         export CC="gcc -DSUPPORTIPV6"
775                 fi
776                 while :; do
777                         case "$1" in
778                                 -0)
779                                         compiled0=true
780                                         shift
781                                         ;;
782                                 -c)
783                                         cleand0=true
784                                         cleandp=true
785                                         cleanqcc=true
786                                         cleanqc=true
787                                         shift
788                                         ;;
789                                 -r)
790                                         debug=release
791                                         export CC="$CC -g -mtune=native -march=native"
792                                         shift
793                                         ;;
794                                 *)
795                                         break
796                                         ;;
797                         esac
798                 done
799                 if [ -n "$WE_HATE_OUR_USERS" ]; then
800                         TARGETS="sv-$debug cl-$debug"
801                 elif [ x"`uname`" = x"Darwin" ]; then
802                         case "`uname -r`" in
803                                 ?.*)
804                                         TARGETS="sv-$debug cl-$debug sdl-$debug"
805                                         ;;
806                                 *)
807                                         # AGL cannot be compiled on systems with a kernel > 10.x (Snow Leopard)
808                                         snowleopardhack=true
809                                         TARGETS="sv-$debug sdl-$debug"
810                                         ;;
811                         esac
812                         export CC="$CC -I$PWD/misc/buildfiles/osx/Xonotic-SDL.app/Contents/Frameworks/SDL.framework/Headers -F$PWD/misc/buildfiles/osx/Xonotic-SDL.app/Contents/Frameworks"
813                 else
814                         TARGETS="sv-$debug cl-$debug sdl-$debug"
815                 fi
816                 if [ $# -gt 0 ] && [ x"$1" = x"" ]; then
817                         # if we give the command make the arg "", it will surely fail (invalid filename),
818                         # so better handle it as an empty client option
819                         BAD_TARGETS=" "
820                         shift
821                 elif [ -n "$1" ]; then
822                         BAD_TARGETS=
823                         TARGETS_SAVE=$TARGETS
824                         TARGETS=
825                         for X in $1; do
826                                 case "$X" in
827                                         sdl)
828                                                 TARGETS="$TARGETS sdl-debug"
829                                                 ;;
830                                         agl)
831                                                 TARGETS="$TARGETS cl-debug"
832                                                 if $snowleopardhack; then
833                                                         export CC="$CC -arch i386"
834                                                 fi
835                                                 ;;
836                                         glx|wgl)
837                                                 TARGETS="$TARGETS cl-debug"
838                                                 ;;
839                                         dedicated)
840                                                 TARGETS="$TARGETS sv-debug"
841                                                 ;;
842                                         *)
843                                                 BAD_TARGETS="$BAD_TARGETS $X"
844                                                 ;;
845                                 esac
846                         done
847                         if [ -n "$TARGETS" ]; then # at least a valid client
848                                 shift
849                         else # no valid client, let's assume this option is not meant to be a client then
850                                 TARGETS=$TARGETS_SAVE
851                                 BAD_TARGETS=
852                         fi
853                 fi
854                 if [ -z "$MAKEFLAGS" ]; then
855                         if [ -f /proc/cpuinfo ]; then
856                                 ncpus=$((`grep -c '^processor   :' /proc/cpuinfo`+0))
857                                 if [ $ncpus -gt 1 ]; then
858                                         MAKEFLAGS=-j$ncpus
859                                 fi
860                         fi
861                         if [ -n "$WE_HATE_OUR_USERS" ]; then
862                                 MAKEFLAGS="$MAKEFLAGS DP_MAKE_TARGET=mingw LIB_JPEG= CFLAGS_LIBJPEG="
863                         fi
864                 fi
865
866                 enter "$d0/d0_blind_id" verbose
867                 if ! $compiled0; then
868                         # compilation of crypto library failed
869                         # use binaries then, if we can...
870                         mkdir -p .libs
871                         if [ -n "$WE_HATE_OUR_USERS" ]; then
872                                 verbose cp "$d0/misc/buildfiles/win32/libd0_blind_id"-* .libs/
873                                 verbose cp "$d0/misc/buildfiles/win32/libgmp"-* .libs/
874                         else
875                                 case "`uname`" in
876                                         Linux)
877                                                 case `uname -m` in
878                                                         x86_64)
879                                                                 verbose cp "$d0/misc/builddeps/dp.linux64/lib/libd0_blind_id".* .libs/
880                                                                 verbose cp "$d0/misc/builddeps/dp.linux64/lib/libgmp".* .libs/
881                                                                 MAKEFLAGS="$MAKEFLAGS DP_CRYPTO_STATIC_LIBDIR=../misc/builddeps/dp.linux64/lib/"
882                                                                 ;;
883                                                         *86)
884                                                                 verbose cp "$d0/misc/builddeps/dp.linux32/lib/libd0_blind_id".* .libs/
885                                                                 verbose cp "$d0/misc/builddeps/dp.linux32/lib/libgmp".* .libs/
886                                                                 MAKEFLAGS="$MAKEFLAGS DP_CRYPTO_STATIC_LIBDIR=../misc/builddeps/dp.linux32/lib/"
887                                                                 ;;
888                                                         *)
889                                                                 compiled0=true
890                                                                 ;;
891                                                 esac
892                                                 ;;
893                                         Darwin)
894                                                 verbose cp "$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_blind_id".* .libs/
895                                                 ;;
896                                         *)
897                                                 compiled0=true
898                                                 ;;
899                                 esac
900                         fi
901                 fi
902                 if $compiled0; then
903                         if $cleand0; then
904                                 if [ -f Makefile ]; then
905                                         verbose make $MAKEFLAGS distclean
906                                 fi
907                         fi
908                         if ! [ -f Makefile ]; then
909                                 verbose sh autogen.sh
910                                 verbose ./configure
911                         fi
912                         verbose make $MAKEFLAGS
913                 fi
914
915                 enter "$d0/fteqcc" verbose
916                 if $cleanqcc; then
917                         verbose make $MAKEFLAGS clean
918                 fi
919                 verbose make $MAKEFLAGS
920
921                 enter "$d0/data/xonotic-data.pk3dir" verbose
922                 if $cleanqc; then
923                         verbose make FTEQCC="../../../../fteqcc/fteqcc.bin" "$@" $MAKEFLAGS clean
924                 fi
925                 verbose make FTEQCC="../../../../fteqcc/fteqcc.bin" "$@" $MAKEFLAGS
926                 # 4 levels up: data, xonotic-data, qcsrc, server
927
928                 enter "$d0/darkplaces" verbose
929                 if [ x"$BAD_TARGETS" = x" " ]; then
930                         echo "Warning: invalid empty client, default clients will be used."
931                 fi
932                 if $cleandp; then
933                         verbose make $MAKEFLAGS clean
934                 fi
935                 for T in $TARGETS; do
936                         verbose make $MAKEFLAGS STRIP=: "$@" "$T"
937                 done
938                 for T in $BAD_TARGETS; do
939                         echo "Warning: discarded invalid client $T."
940                 done
941
942                 verbose "$SELF" update-maps
943                 ;;
944         run)
945                 if [ -n "$WE_HATE_OUR_USERS" ]; then
946                         client=
947                         export PATH="$d0/misc/buildfiles/win32:$d0/d0_blind_id/.libs:$PATH"
948                 elif [ x"`uname`" = x"Darwin" ]; then
949                         export DYLD_LIBRARY_PATH="$d0/misc/buildfiles/osx/Xonotic-SDL.app/Contents/MacOS:$d0/d0_blind_id/.libs"
950                         export DYLD_FRAMEWORK_PATH="$d0/misc/buildfiles/osx/Xonotic-SDL.app/Contents/Frameworks"
951                         client=-sdl
952                 else
953                         export LD_LIBRARY_PATH="$d0/d0_blind_id/.libs"
954                         client=-sdl
955                 fi
956                 case "$1" in
957                         sdl|glx|agl|dedicated)
958                                 client=-$1
959                                 shift
960                                 ;;
961                         wgl)
962                                 client=
963                                 shift
964                                 ;;
965                 esac
966                 if ! [ -x "darkplaces/darkplaces$client" ]; then
967                         if [ -x "darkplaces/darkplaces$client.exe" ]; then
968                                 client=$client.exe
969                         else
970                                 echo "Client darkplaces/darkplaces$client not found, aborting"
971                                 exit 1
972                         fi
973                 fi
974                 set -- "darkplaces/darkplaces$client" -xonotic -mygames "$@"
975
976                 # if pulseaudio is running: USE IT
977                 if [ -z "$SDL_AUDIODRIVER" ] && ! [ -n "$WE_HATE_OUR_USERS" ] && ! [ x"`uname`" = x"Darwin" ]; then
978                         if ps -C pulseaudio >/dev/null; then
979                                 if ldd /usr/lib/libSDL.so 2>/dev/null | grep pulse >/dev/null; then
980                                         export SDL_AUDIODRIVER=pulse
981                                 fi
982                         fi
983                 fi
984
985                 binary=$1
986
987                 if [ -n "$USE_GDB" ]; then
988                         set -- gdb --args "$@"
989                 elif which gdb >/dev/null 2>&1; then
990                         set -- gdb --batch -x savecore.gdb --args "$@"
991                 elif which catchsegv >/dev/null 2>&1; then
992                         set -- catchsegv "$@"
993                 fi
994                 rm -f xonotic.core
995                 "$@" || true
996                 if [ -f xonotic.core ]; then
997                         if yesno "The program has CRASHED. Do you want to examine the core dump?"; then
998                                 gdb "$binary" xonotic.core
999                         #elif yesno "You did not want to examine the core dump. Do you want to provide it - including your DarkPlaces checkout - to the Xonotic developers?"; then
1000                         #       tar cvzf xonotic.core.tar.gz xonotic.core darkplaces/*.c darkplaces/*.h
1001                         #       # somehow send it
1002                         #       rm -f xonotic.core.tar.gz
1003                         else
1004                                 echo "The core dump can be examined later by"
1005                                 echo "  gdb $binary xonotic.core"
1006                         fi
1007                 fi
1008                 ;;
1009         each|foreach)
1010                 keep_going=false
1011                 if [ x"$1" = x"-k" ]; then
1012                         keep_going=true
1013                         shift
1014                 fi
1015                 for d in $repos; do
1016                         if verbose cd "$d0/$d"; then
1017                                 if $keep_going; then
1018                                         verbose "$@" || true
1019                                 else
1020                                         verbose "$@"
1021                                 fi
1022                                 cd "$d0"
1023                         fi
1024                 done
1025                 ;;
1026         save-patches)
1027                 outfile=$1
1028                 patchdir=`mktemp -d -t save-patches.XXXXXX`
1029                 for d in $repos; do
1030                         enter "$d0/$d" verbose
1031                         git branch -v -v | cut -c 3- | {
1032                                 i=0
1033                                 while read -r BRANCH REV UPSTREAM TEXT; do
1034                                         case "$UPSTREAM" in
1035                                                 \[*)
1036                                                         UPSTREAM=${UPSTREAM#\[}
1037                                                         UPSTREAM=${UPSTREAM%\]}
1038                                                         UPSTREAM=${UPSTREAM%:*}
1039                                                         TRACK=true
1040                                                         ;;
1041                                                 *)
1042                                                         UPSTREAM=origin/"`repobranch "$d"`"
1043                                                         TRACK=false
1044                                                         ;;
1045                                         esac
1046                                         if [ x"$REV" = x"->" ]; then
1047                                                 continue
1048                                         fi
1049                                         if git format-patch -o "$patchdir/$i" "$UPSTREAM".."$BRANCH"; then
1050                                                 echo "$d" > "$patchdir/$i/info.txt"
1051                                                 echo "$BRANCH" >> "$patchdir/$i/info.txt"
1052                                                 echo "$UPSTREAM" >> "$patchdir/$i/info.txt"
1053                                                 echo "$TRACK" >> "$patchdir/$i/info.txt"
1054                                                 i=$(($i+1))
1055                                         else
1056                                                 rm -rf "$patchdir/$i"
1057                                         fi
1058                                 done
1059                         }
1060                 done
1061                 ( cd "$patchdir" && tar cvzf - . ) > "$outfile"
1062                 rm -rf "$patchdir"
1063                 ;;
1064         restore-patches)
1065                 infile=$1
1066                 patchdir=`mktemp -d -t restore-patches.XXXXXX`
1067                 ( cd "$patchdir" && tar xvzf - ) < "$infile"
1068                 # detach the head
1069                 for P in "$patchdir"/*/info.txt; do
1070                         D=${P%/info.txt}
1071                         exec 3<"$P"
1072                         read -r d <&3
1073                         read -r BRANCH <&3
1074                         read -r UPSTREAM <&3
1075                         read -r TRACK <&3
1076                         verbose git checkout HEAD^0
1077                         verbose git branch -D "$BRANCH"
1078                         if [ x"$TRACK" = x"true" ]; then
1079                                 verbose git checkout --track -b "$BRANCH" "$UPSTREAM"
1080                         else
1081                                 verbose git branch -b "$BRANCH" "$UPSTREAM"
1082                         fi
1083                         verbose git am "$D"
1084                 done
1085                 rm -rf "$patchdir"
1086                 ;;
1087         admin-merge)
1088                 branch=$1
1089                 t=`mktemp`
1090                 report=""
1091                 reportecho()
1092                 {
1093                         report=$report"$*$LF"
1094                         echo "$*"
1095                 }
1096                 reportecho4()
1097                 {
1098                         report=$report"    $*$LF"
1099                         echo "    $*"
1100                 }
1101                 reportdo4()
1102                 {
1103                         o=`"$@" | sed 's/^/    /' || true`
1104                         reportecho "$o"
1105                 }
1106                 for d in $repos; do
1107                         case "$d" in
1108                                 fteqcc)
1109                                         # sorry, fteqcc repo is managed manually
1110                                         continue
1111                                         ;;
1112                         esac
1113                         enter "$d0/$d" verbose
1114                         base="`repobranch "$d"`"
1115                         reportecho "In $d:"
1116                         for ref in `git for-each-ref --format='%(refname)' refs/remotes/origin/`; do
1117                                 case "${ref#refs/remotes/origin/}" in
1118                                         "$base")
1119                                                 continue
1120                                                 ;;
1121                                         HEAD|master)
1122                                                 continue
1123                                                 ;;
1124                                         */*)
1125                                                 ;;
1126                                         *)
1127                                                 continue
1128                                                 ;;
1129                                 esac
1130                                 if [ -n "$branch" ]; then
1131                                         if [ x"$branch" != x"${ref#refs/remotes/origin/}" ]; then
1132                                                 continue
1133                                         fi
1134                                 fi
1135                                 case "$base" in
1136                                         master)
1137                                                 realbase=$base
1138                                                 ;;
1139                                         *)
1140                                                 l0=`git rev-list "$base".."$ref" | wc -l`
1141                                                 l1=`git rev-list master.."$ref" | wc -l`
1142                                                 if [ $l0 -gt $l1 ]; then
1143                                                         realbase=master
1144                                                 else
1145                                                         realbase=$base
1146                                                 fi
1147                                                 ;;
1148                                 esac
1149                                 reportecho "  Branch $ref:"
1150                                 note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1151                                 logdata=`git log --color "$realbase".."$ref"`
1152                                 if [ -z "$logdata" ]; then
1153                                         reportecho4 "--> not merging, no changes vs master"
1154                                         if yesno "Branch \"$ref\" probably should get deleted. Do it?" ''; then
1155                                                 git push origin :"${ref#refs/remotes/origin/}"
1156                                                 reportecho4 "--> branch deleted"
1157                                         fi
1158                                 else
1159                                         diffdata=`git diff --color --find-copies-harder --ignore-space-change "$realbase"..."$ref"`
1160                                         if [ -z "$diffdata" ]; then
1161                                                 reportecho4 "--> not merging, no changes vs master, branch contains redundant history"
1162                                                 if yesno "Branch \"$ref\" probably should get deleted. Do it?" '{ echo "$logdata"; } | less -r'; then
1163                                                         git push origin :"${ref#refs/remotes/origin/}"
1164                                                         reportecho4 "--> branch deleted"
1165                                                 fi
1166                                         elif [ -z "$branch" ] && [ -n "$note" ]; then
1167                                                 reportdo4 echo "$note"
1168                                                 reportecho4 "--> not merging, already had this one rejected before"
1169                                         elif yesno "Branch \"$ref\" may want to get merged. Do it?" '{ echo "$logdata"; echo "$diffdata"; } | less -r'; then
1170                                                 git checkout "$realbase"
1171                                                 org=`git rev-parse HEAD`
1172                                                 if ! git merge --no-ff "$ref" 2>&1 | tee "$t" && ! { git ls-files -u | grep ' 1 ' >/dev/null; }; then
1173                                                         git reset --hard "$org"
1174                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit -m "Merge failed:$LF`cat "$t"`" "$ref"
1175                                                         reportdo4 cat "$t"
1176                                                         reportecho4 "--> merge failed"
1177                                                 elif ! "$SELF" compile 2>&1 | tee "$t"; then
1178                                                         git reset --hard "$org"
1179                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit -m "Compile failed:$LF`cat "$t"`" "$ref"
1180                                                         reportdo4 cat "$t"
1181                                                         reportecho4 "--> compile failed"
1182                                                 elif ! yesno "Still merge \"$ref\" into `git symbolic-ref HEAD` of $d? Maybe you want to test first."; then
1183                                                         git reset --hard "$org"
1184                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit "$ref"
1185                                                         note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1186                                                         if [ x"$note" = x"del" ]; then
1187                                                                 git push origin :"${ref#refs/remotes/origin/}"
1188                                                                 reportecho4 "--> test failed, branch deleted"
1189                                                         elif [ -n "$note" ]; then
1190                                                                 reportdo4 echo "$note"
1191                                                                 reportecho4 "--> test failed"
1192                                                         else
1193                                                                 reportecho4 "--> test failed, postponed"
1194                                                         fi
1195                                                 else
1196                                                         # apply crlf, or other cleanup filters (non-behavioural changes)
1197                                                         git reset --hard
1198                                                         find . -type f -exec touch {} \;
1199                                                         git commit -a --amend -C HEAD || true # don't fail if nothing to commit
1200
1201                                                         echo "MERGING"
1202                                                         case ",`repoflags "$d"`," in
1203                                                                 *,svn,*)
1204                                                                         # we do quite a mess here... luckily we know $org
1205                                                                         git fetch # svn needs to be current
1206                                                                         git rebase -i --onto origin/master "$org"
1207                                                                         git svn dcommit --add-author-from
1208                                                                         git reset --hard "$org"
1209                                                                         ;;
1210                                                                 *)
1211                                                                         git push origin HEAD
1212                                                                         ;;
1213                                                         esac
1214                                                         reportecho4 "--> MERGED"
1215                                                         if yesno "Delete original branch \"$ref\"?"; then
1216                                                                 git push origin :"${ref#refs/remotes/origin/}"
1217                                                                 reportecho4 "--> branch deleted"
1218                                                         fi
1219                                                 fi
1220                                         else
1221                                                 GIT_NOTES_REF=refs/notes/admin-merge git notes edit "$ref"
1222                                                 note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1223                                                 if [ x"$note" = x"del" ]; then
1224                                                         git push origin :"${ref#refs/remotes/origin/}"
1225                                                         reportecho4 "--> branch deleted"
1226                                                 elif [ -n "$note" ]; then
1227                                                         reportdo4 echo "$note"
1228                                                         reportecho4 "--> rejected"
1229                                                 else
1230                                                         reportecho4 "--> postponed"
1231                                                 fi
1232                                         fi
1233                                 fi
1234                                 reportecho ""
1235                         done
1236                         reportecho ""
1237                 done
1238                 rm -f "$t"
1239                 echo "$report" | ssh nexuiz@rm.endoftheinternet.org cat '>>' public_html/xonotic-merge-notes.txt
1240                 ;;
1241         clean)
1242                 "$SELF" fix_config
1243                 "$SELF" update -N
1244                 force=false
1245                 gotoupstream=false
1246                 fetchupstream=false
1247                 gotomaster=false
1248                 rmuntracked=false
1249                 killbranches=false
1250                 # usage:
1251                 #   ./all clean [-m] [-f | -fu | -fU] [-r] [-D]
1252                 #   ./all clean --reclone
1253                 found=false
1254                 for X in "$@"; do
1255                         if [ x"$X" = x"--reclone" ]; then
1256                                 force=true
1257                                 fetchupstream=true
1258                                 gotoupstream=true
1259                                 gotomaster=true
1260                                 rmuntracked=true
1261                                 killbranches=true
1262                         elif [ x"$X" = x"-f" ]; then
1263                                 force=true
1264                         elif [ x"$X" = x"-u" ]; then
1265                                 gotoupstream=true
1266                         elif [ x"$X" = x"-U" ]; then
1267                                 gotoupstream=true
1268                                 fetchupstream=true
1269                         elif [ x"$X" = x"-fu" ]; then
1270                                 force=true
1271                                 gotoupstream=true
1272                         elif [ x"$X" = x"-fU" ]; then
1273                                 force=true
1274                                 gotoupstream=true
1275                                 fetchupstream=true
1276                         elif [ x"$X" = x"-m" ]; then
1277                                 gotomaster=true
1278                         elif [ x"$X" = x"-r" ]; then
1279                                 rmuntracked=true
1280                         elif [ x"$X" = x"-D" ]; then
1281                                 killbranches=true
1282                         elif echo "$X" | grep '^-FFFF*UUUU*$' >/dev/null; then
1283                                 msg ''
1284                                 msg '        _____'
1285                                 msg '    ,--'\''-\\P/`\\  FFFFFFF'
1286                                 msg ' __/_    B/,-.\\  FFFFFFF'
1287                                 msg ' /  _\\  (//  O\\\\  FFFFFF'
1288                                 msg '| (O  `) _\\._ _)\\  FFFUU'
1289                                 msg '| |___/.^d0~~"\\  \\ UUUU'
1290                                 msg '|     |`~'\''     \\ |  UUUU'
1291                                 msg '|     |    __,C>|| UUUU'
1292                                 msg '\\    /_ ,-/,-'\''   |  UUUU'
1293                                 msg ' \\\\_ \\_>~'\''      /  UUUU-'
1294                                 msg ''
1295                         else
1296                                 msg "Unknown arg: $X"
1297                         fi
1298                         found=true
1299                         shift
1300                 done
1301                 if ! $found; then
1302                         rmuntracked=true
1303                 fi
1304                 for d in $repos; do
1305                         verbose cd "$d0/$d"
1306                         if $gotoupstream; then
1307                                 if ! $force; then
1308                                         msg "Must also use -f (delete local changes) when using -u"
1309                                         exit 1
1310                                 fi
1311                                 if $gotomaster; then
1312                                         if $fetchupstream; then
1313                                                 verbose git fetch origin
1314                                                 verbose git remote prune origin
1315                                         fi
1316                                         verbose git checkout -f "`repobranch "$d"`"
1317                                         verbose git reset --hard origin/"`repobranch "$d"`"
1318                                 else
1319                                         r=`git symbolic-ref HEAD`
1320                                         r=${r#refs/heads/}
1321                                         rem=`git config "branch.$r.remote" || echo origin`
1322                                         bra=`git config "branch.$r.merge" || echo "$r"`
1323                                         upstream="$rem/${bra#refs/heads/}"
1324                                         if $fetchupstream; then
1325                                                 verbose git fetch "$rem"
1326                                                 verbose git remote prune "$rem"
1327                                         fi
1328                                         if ! git rev-parse "$upstream" >/dev/null 2>&1; then
1329                                                 upstream="origin/`repobranch "$d"`"
1330                                         fi
1331                                         verbose git reset --hard "$upstream"
1332                                 fi
1333                         elif $gotomaster; then
1334                                 if $force; then
1335                                         verbose git checkout -f "`repobranch "$d"`"
1336                                         verbose git reset --hard
1337                                 else
1338                                         verbose git checkout "`repobranch "$d"`"
1339                                 fi
1340                         elif $force; then
1341                                 verbose git reset --hard
1342                         fi
1343                         if $rmuntracked; then
1344                                 case "$d" in
1345                                         .)
1346                                                 verbose git clean -df
1347                                                 ;;
1348                                         *)
1349                                                 verbose git clean -xdf
1350                                                 ;;
1351                                 esac
1352                         fi
1353                         if $killbranches; then
1354                                 git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
1355                                         if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
1356                                                 verbose git branch -D "${B#refs/heads/}"
1357                                         fi
1358                                 done
1359                                 git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch -t master origin/master || true
1360                                 git rev-parse "refs/heads/`repobranch "$d"`" >/dev/null 2>&1 || verbose git branch -t "`repobranch "$d"`" origin/"`repobranch "$d"`" || true
1361                         fi
1362                         checkself "$cmd" "$@"
1363                 done
1364                 ;;
1365
1366         # release building goes here
1367         release-prepare)
1368                 #"$SELF" each git clean -fxd
1369                 case "$RELEASETYPE" in
1370                         beta)
1371                                 msg "Building a BETA"
1372                                 ;;
1373                         release)
1374                                 msg "Building a RELEASE"
1375                                 ;;
1376                         *)
1377                                 echo >&2 -n "$ESC[2J$ESC[H"
1378                                 msg ""
1379                                 msg ""
1380                                 msg ""
1381                                 msg ""
1382                                 msg ""
1383                                 msg ""
1384                                 msg "        +---------------------------------------------------------.---+"
1385                                 msg "        | NOTE                                                    | X |"
1386                                 msg "        +---------------------------------------------------------^---+"
1387                                 msg "        |   ____                                                      |"
1388                                 msg "        |  /    \  This is the official release build system.         |"
1389                                 msg "        | |      | If you are not a member of the Xonotic Core Team,  |"
1390                                 msg "        | | STOP | you are not supposed to use this script and should |"
1391                                 msg "        | |      | instead use ./all compile to compile the engine    |"
1392                                 msg "        |  \____/  and game code.                                     |"
1393                                 msg "        |                                                             |"
1394                                 msg "        |                      [ I understand ]                       |"
1395                                 msg "        +-------------------------------------------------------------+"
1396                                 sleep 10
1397                                 # A LOT of build infrastructure is required:
1398                                 # - vorbis-tools
1399                                 # - ImageMagick
1400                                 # - .ssh/config must be configured so the following
1401                                 #   host names are reachable and have a compile
1402                                 #   infrastructure set up:
1403                                 #   - xonotic-build-linux32 (with gcc on x86)
1404                                 #   - xonotic-build-linux64 (with gcc on x86_64)
1405                                 #   - xonotic-build-win32 (with i586-mingw32msvc-g++)
1406                                 #   - xonotic-build-win64 (with amd64-mingw32msvc-g++
1407                                 #     and x86_64-w64-mingw32-g++)
1408                                 #   - xonotic-build-osx (with Xcode and SDL.framework)
1409                                 # - AMD Compressonator installed in WINE
1410                                 # - ResEdit installed in WINE
1411                                 # - a lot of other requirements you will figure out
1412                                 #   while reading the error messages
1413                                 # - environment variable RELEASETYPE set
1414                                 # - optionally, environment variable RELEASEDATE set
1415                                 #   (YYYYMMDD)
1416                                 exit 1
1417                                 ;;
1418                 esac
1419                 verbose rm -rf Xonotic Xonotic*.zip
1420                 verbose mkdir -p Xonotic
1421                 if [ -n "$RELEASEDATE" ]; then
1422                         verbose echo "$RELEASEDATE" > Xonotic/stamp.txt
1423                 else
1424                         verbose date +%Y%m%d > Xonotic/stamp.txt
1425                 fi
1426                 verbose git archive --format=tar HEAD -- Docs misc server xonotic-linux-glx.sh xonotic-linux-sdl.sh misc/buildfiles key_0.d0pk | {
1427                         verbose cd Xonotic
1428                         verbose mkdir data fteqcc source source/darkplaces source/fteqcc
1429                         verbose tar xvf -
1430                         verbose rm -rf misc/builddeps
1431                         verbose mv misc/buildfiles/win32/* . || true
1432                         verbose mv misc/buildfiles/win64 bin64 || true
1433                         verbose mv misc/buildfiles/osx/* . || true
1434                         verbose rm -rf misc/buildfiles
1435                         verbose rm -rf misc/pki
1436                 }
1437                 {
1438                         verbose cd darkplaces
1439                         verbose git archive --format=tar HEAD
1440                 } | {
1441                         verbose cd Xonotic/source/darkplaces
1442                         verbose tar xvf -
1443                 }
1444                 {
1445                         verbose cd fteqcc
1446                         verbose git archive --format=tar HEAD
1447                 } | {
1448                         verbose cd Xonotic/source/fteqcc
1449                         verbose tar xvf -
1450                 }
1451                 {
1452                         verbose cd data/xonotic-data.pk3dir
1453                         verbose git archive --format=tar HEAD -- qcsrc Makefile
1454                 } | {
1455                         verbose cd Xonotic/source
1456                         verbose tar xvf -
1457                 }
1458                 rm -f Xonotic/key_15.d0pk
1459                 ;;
1460         release-compile-run)
1461                 host=$1
1462                 buildpath=$2
1463                 maketargets=$3
1464                 makeflags=$4
1465                 srcdir=$5
1466                 depsdir=$6
1467                 targetfiles=$7
1468                 set -x
1469                 if [ -n "$targetfiles" ]; then
1470                         case " $HOSTS_THAT_ARE_DISABLED " in
1471                                 *\ $host\ *)
1472                                         exit
1473                                         ;;
1474                         esac
1475                         case " $HOSTS_THAT_ARE_MYSELF " in
1476                                 *\ $host\ *)
1477                                         verbose rsync --delete -zLvaSHP "$srcdir"/ "$buildpath/"
1478                                         verbose rsync --delete -zLvaSHP "$depsdir"/ "$buildpath.deps/"
1479                                         verbose ln -snf "$buildpath.deps" "$buildpath/.deps"
1480                                         verbose eval make -C "$buildpath" clean $maketargets $makeflags
1481                                         for f in $targetfiles; do
1482                                                 verbose mv "$buildpath/${f%:*}" "${f##*:}" || true
1483                                         done
1484                                         ;;
1485                                 *)
1486                                         verbose rsync --delete -zLvaSHP "$srcdir"/ "$host:$buildpath/"
1487                                         verbose rsync --delete -zLvaSHP "$depsdir"/ "$host:$buildpath.deps/"
1488                                         verbose ssh "$host" "ln -snf $buildpath.deps $buildpath/.deps && cd $buildpath && nice -`nice` make clean $maketargets $makeflags"
1489                                         for f in $targetfiles; do
1490                                                 verbose rsync -zvaSHP "$host:$buildpath/${f%:*}" "${f##*:}" || true
1491                                         done
1492                                         ;;
1493                         esac
1494                         # now rebrand the binaries...
1495                         for f in $targetfiles; do
1496                                 #verbose "$d0/misc/tools/rebrand-darkplaces-engine.sh" "${XONOTIC_BRAND:-$d0/misc/tools/xonotic.brand}" "${f##*:}" || true
1497                                 case "${f##*:}" in
1498                                         xonotic*.exe)
1499                                                 verbose "$d0/misc/tools/change-icon-of-exe.sh" "$d0/misc/logos/icons_ico/xonotic.ico" "${f##*:}"
1500                                                 (
1501                                                         d=`mktemp -d -t rebrand.XXXXXX`
1502                                                         cd "$d"
1503                                                         echo "-mygames" > darkplaces.opt
1504                                                         zip -9r darkplaces.zip darkplaces.opt
1505                                                         cat darkplaces.zip
1506                                                         cd "$d0"
1507                                                         rm -rf "$d"
1508                                                 ) >> "${f##*:}"
1509                                                 ;;
1510                                 esac
1511                         done
1512                 fi
1513                 ;;
1514         release-compile)
1515                 suffix=$1
1516                 makeflags=$2
1517                 fteqcc_maketargets=$3
1518                 fteqcc_files=$4
1519                 darkplaces_maketargets=$5
1520                 darkplaces_files=$6
1521                 host=xonotic-build-$suffix
1522                 verbose "$SELF" release-compile-run "$host" /tmp/fteqcc.build."$suffix" "$fteqcc_maketargets" "$makeflags" "Xonotic/source/fteqcc" "$d0/misc/builddeps/dp.$suffix" "$fteqcc_files"
1523                 verbose "$SELF" release-compile-run "$host" /tmp/Darkplaces.build."$suffix" "$darkplaces_maketargets" "$makeflags" "Xonotic/source/darkplaces" "$d0/misc/builddeps/dp.$suffix" "$darkplaces_files"
1524                 ;;
1525         release-engine-win32)
1526                 verbose "$SELF" release-compile win32 \
1527                         'STRIP=: DP_MAKE_TARGET=mingw CC="i586-mingw32msvc-gcc -march=i686 -g -Wl,--dynamicbase -Wl,--nxcompat -I.deps/include -L.deps/lib -DUSE_WSPIAPI_H -DSUPPORTIPV6" WINDRES="i586-mingw32msvc-windres" SDL_CONFIG=".deps/bin/sdl-config" LIB_JPEG= CFLAGS_LIBJPEG= WIN32RELEASE=1 D3D=0' \
1528                         win 'fteqcc.exe:Xonotic/fteqcc/fteqcc.exe' \
1529                         '' ''
1530                 verbose "$SELF" release-compile win32 \
1531                         'STRIP=: DP_MAKE_TARGET=mingw CC="i586-mingw32msvc-gcc -g -Wl,--dynamicbase -Wl,--nxcompat -I.deps/include -L.deps/lib -DUSE_WSPIAPI_H -DSUPPORTIPV6" WINDRES="i586-mingw32msvc-windres" SDL_CONFIG=".deps/bin/sdl-config" LIB_JPEG= CFLAGS_LIBJPEG= WIN32RELEASE=1 D3D=0' \
1532                         '' '' \
1533                         release 'darkplaces.exe:Xonotic/xonotic.exe darkplaces-sdl.exe:Xonotic/xonotic-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-dedicated.exe'
1534                 ;;
1535         release-engine-win64)
1536                 verbose "$SELF" release-compile win64 \
1537                         'STRIP=: DP_MAKE_TARGET=mingw CC="amd64-mingw32msvc-gcc -g -Wl,--dynamicbase -Wl,--nxcompat -I.deps/include -L.deps/lib -DSUPPORTIPV6" WINDRES="amd64-mingw32msvc-windres" SDL_CONFIG=".deps/bin/sdl-config" LIB_JPEG= CFLAGS_LIBJPEG= WIN64RELEASE=1 D3D=0' \
1538                         win 'fteqcc.exe:Xonotic/fteqcc/fteqcc-x64.exe' \
1539                         'sv-release sdl-release' 'darkplaces-sdl.exe:Xonotic/xonotic-x64-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-x64-dedicated.exe'
1540                 verbose "$SELF" release-compile win64 \
1541                         'STRIP=: DP_MAKE_TARGET=mingw CC="x86_64-w64-mingw32-gcc -g -Wl,--dynamicbase -Wl,--nxcompat -I.deps/include -L.deps/lib -DSUPPORTIPV6" WINDRES="x86_64-w64-mingw32-windres" SDL_CONFIG=".deps/bin/sdl-config" LIB_JPEG= CFLAGS_LIBJPEG= WIN64RELEASE=1 D3D=0' \
1542                         '' '' \
1543                         cl-release 'darkplaces.exe:Xonotic/xonotic-x64.exe'
1544                 ;;
1545         release-engine-osx)
1546                 # gcc on OSX is buggy, needs -fno-reorder-blocks for a release build to succeed
1547                 verbose "$SELF" release-compile osx \
1548                         'STRIP=: CC="gcc -g -arch i386 -arch ppc -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.4 -I.deps/include -L.deps/lib -fno-reorder-blocks -DSUPPORTIPV6"' \
1549                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.osx' \
1550                         'sv-release sdl-release' 'darkplaces-sdl:Xonotic/Xonotic-SDL.app/Contents/MacOS/xonotic-osx-sdl-bin darkplaces-dedicated:Xonotic/xonotic-osx-dedicated'
1551                 verbose "$SELF" release-compile osx \
1552                         'STRIP=: CC="gcc -g -arch i386 -arch ppc -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.4 -I.deps/include -L.deps/lib -fno-reorder-blocks -DSUPPORTIPV6"' \
1553                         '' '' \
1554                         'cl-release' 'darkplaces-agl:Xonotic/Xonotic.app/Contents/MacOS/xonotic-osx-agl-bin'
1555                 ;;
1556         release-engine-linux32)
1557                 verbose "$SELF" release-compile linux32 \
1558                         'STRIP=: CC="gcc -m32 -march=i686 -g -I.deps/include -L.deps/lib -DSUPPORTIPV6" DP_MODPLUG_STATIC_LIBDIR=.deps/lib LIB_JPEG=.deps/lib/libjpeg.a DP_CRYPTO_STATIC_LIBDIR=.deps/lib' \
1559                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux32' \
1560                         release 'darkplaces-glx:Xonotic/xonotic-linux32-glx darkplaces-sdl:Xonotic/xonotic-linux32-sdl darkplaces-dedicated:Xonotic/xonotic-linux32-dedicated'
1561                 ;;
1562         release-engine-linux64)
1563                 verbose "$SELF" release-compile linux64 \
1564                         'STRIP=: CC="gcc -m64 -g -I.deps/include -L.deps/lib -DSUPPORTIPV6" DP_MODPLUG_STATIC_LIBDIR=.deps/lib LIB_JPEG=.deps/lib/libjpeg.a DP_CRYPTO_STATIC_LIBDIR=.deps/lib' \
1565                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux64' \
1566                         release 'darkplaces-glx:Xonotic/xonotic-linux64-glx darkplaces-sdl:Xonotic/xonotic-linux64-sdl darkplaces-dedicated:Xonotic/xonotic-linux64-dedicated'
1567                 ;;
1568         release-engine)
1569                 verbose "$SELF" release-engine-linux32 &
1570                 verbose "$SELF" release-engine-linux64 &
1571                 verbose "$SELF" release-engine-win32 &
1572                 verbose "$SELF" release-engine-win64 &
1573                 verbose "$SELF" release-engine-osx &
1574                 wait %1
1575                 wait %2
1576                 wait %3
1577                 wait %4
1578                 wait %5
1579                 wait
1580                 ;;
1581         release-maps)
1582                 verbose "$SELF" update-maps
1583                 ;;
1584         release-qc)
1585                 case "$RELEASETYPE" in
1586                         beta)
1587                                 verbose make -C Xonotic/source FTEQCC="../../../fteqcc/fteqcc.linux32" XON_BUILDSYSTEM=1 clean all
1588                                 # back out of: source/qcsrc/server
1589                                 ;;
1590                         release)
1591                                 verbose make -C Xonotic/source FTEQCC="../../../fteqcc/fteqcc.linux32" XON_BUILDSYSTEM=1 FTEQCCFLAGS_WATERMARK= clean all
1592                                 ;;
1593                 esac
1594                 verbose rm -f Xonotic/source/*/fteqcc.log
1595                 ;;
1596         release-buildpk3-transform-raw)
1597                 dir=$1
1598                 ;;
1599         release-buildpk3-transform-normal)
1600                 dir=$1
1601                 verbose cd "$dir"
1602                 # texture: convert to jpeg and dds
1603                 verbose export do_jpeg=true
1604                 verbose export jpeg_qual_rgb=95
1605                 verbose export jpeg_qual_a=99
1606                 verbose export do_dds=true
1607                 verbose export dds_flags=
1608                 verbose export do_ogg=false
1609                 verbose export del_src=true
1610                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1611                 ;;
1612         release-buildpk3-transform-low)
1613                 dir=$1
1614                 verbose cd "$dir"
1615                 # texture: convert to jpeg and dds
1616                 # music: reduce bitrate
1617                 verbose export do_jpeg=true
1618                 verbose export jpeg_qual_rgb=80
1619                 verbose export jpeg_qual_a=97
1620                 verbose export do_dds=false
1621                 verbose export do_ogg=true
1622                 verbose export ogg_qual=1
1623                 verbose export del_src=true
1624                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1625                 ;;
1626         release-buildpk3-transform-lowdds)
1627                 dir=$1
1628                 verbose cd "$dir"
1629                 # texture: convert to jpeg and dds
1630                 # music: reduce bitrate
1631                 verbose export do_jpeg=false
1632                 verbose export do_jpeg_if_not_dds=true
1633                 verbose export jpeg_qual_rgb=80
1634                 verbose export jpeg_qual_a=99
1635                 verbose export do_dds=true
1636                 verbose export dds_flags=
1637                 verbose export do_ogg=true
1638                 verbose export ogg_qual=1
1639                 verbose export del_src=true
1640                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1641                 ;;
1642         release-buildpk3)
1643                 src=$1
1644                 dst=$2
1645                 transform=$3
1646                 case "$dst" in
1647                         /*)
1648                                 ;;
1649                         */)
1650                                 dst="$PWD/$dst"
1651                                 ;;
1652                 esac
1653                 verbose rm -rf Xonotic/temp
1654                 verbose mkdir -p Xonotic/temp
1655                 {
1656                         verbose cd "$src"
1657                         verbose git archive --format=tar HEAD
1658                 } | {
1659                         verbose cd Xonotic/temp
1660                         verbose tar xvf -
1661                 }
1662                 verbose cd Xonotic/temp
1663                 if [ x"$src" = x"data/xonotic-data.pk3dir" ]; then
1664                         verbose cp ../source/progs.dat .
1665                         verbose cp ../source/csprogs.dat .
1666                         verbose cp ../source/menu.dat .
1667                         verbose rm -rf qcsrc
1668                         gv=`grep "^gameversion " "defaultXonotic.cfg" | awk '{ print $2 }'`
1669                         major=$(($gv / 10000))
1670                         minor=$(($gv / 100 - $major * 100))
1671                         patch=$(($gv - $major * 10000 - $minor * 100))
1672                         versionstr="$major.$minor.$patch"
1673                         case "$RELEASETYPE" in
1674                                 beta)
1675                                         versionstr="$versionstr""beta"
1676                                         ;;
1677                         esac
1678                         verbose sed -i "
1679                                 s/^set g_xonoticversion [^ ]* /set g_xonoticversion $versionstr /;
1680                                 s/^gameversion_min [0-9]*/gameversion_min $(( ($gv / 100) * 100 - 100 ))/;
1681                                 s/^gameversion_max [0-9]*/gameversion_max $(( ($gv / 100) * 100 + 199 ))/;
1682                         " defaultXonotic.cfg
1683                         (
1684                                 verbose cd gfx/menu/luminos
1685                                 verbose cp "$d0"/mediasource/gfx/menu/luminos_versionbuilder/background_l2.svg .
1686                                 verbose "$d0"/mediasource/gfx/menu/luminos_versionbuilder/versionbuilder "$versionstr"
1687                                 verbose rm background_l2.svg
1688                         )
1689                 fi
1690                 if [ x"$src" = x"data/xonotic-maps.pk3dir" ]; then
1691                         for X in ../../data/*-????????????????????????????????????????-????????????????????????????????????????.pk3; do
1692                                 if [ -f "$X" ]; then
1693                                         verbose unzip "$X"
1694                                         verbose rm -f maps/*.log maps/*.irc maps/*.lin
1695                                 fi
1696                         done
1697                 fi
1698                 verbose export git_src_repo="$d0/$src" # skip hash-object
1699                 verbose "$SELF" release-buildpk3-transform-$transform "Xonotic/temp"
1700                 verbose mkzip "../../$dst" *
1701                 verbose cd ../..
1702                 verbose rm -rf Xonotic/temp
1703                 ;;
1704         release-buildpk3s)
1705                 stamp=`cat Xonotic/stamp.txt`
1706                 src=$1
1707                 shift
1708                 dst=${src%.pk3dir}
1709                 case "$dst" in
1710                         data/xonotic-*)
1711                                 dst="data/xonotic-$stamp-${dst#data/xonotic-}"
1712                                 ;;
1713                         *)
1714                                 dst="$dst-$stamp"
1715                                 ;;
1716                 esac
1717                 while [ "$#" -gt 1 ]; do
1718                         verbose "$SELF" release-buildpk3 "$src" "Xonotic/$dst$2.pk3" "$1"
1719                         shift
1720                         shift
1721                 done
1722                 ;;
1723         release-pack)
1724                 verbose "$SELF" release-buildpk3s data/font-nimbussansl.pk3dir             raw ''
1725                 verbose "$SELF" release-buildpk3s data/xonotic-data.pk3dir       normal ''            low '-low' lowdds '-lowdds'
1726                 verbose "$SELF" release-buildpk3s data/xonotic-maps.pk3dir       normal ''            low '-low' lowdds '-lowdds'
1727                 verbose "$SELF" release-buildpk3s data/xonotic-music.pk3dir                raw ''     low '-low'
1728                 verbose "$SELF" release-buildpk3s data/xonotic-nexcompat.pk3dir                       low ''
1729                 ;;
1730         release-pack-needsx11)
1731                 case "$DISPLAY" in
1732                         '')
1733                                 verbose startx "$SELF" release-pack -- /usr/bin/Xvfb :7
1734                                 ;;
1735                         *)
1736                                 verbose "$SELF" release-pack
1737                                 ;;
1738                 esac
1739                 ;;
1740         release-zip)
1741                 stamp=`cat Xonotic/stamp.txt`
1742                 # exe and dll files do not need +x, so this makes them eligible for 7zip compression too
1743                 chmod a-x Xonotic/*.exe Xonotic/*.dll || true
1744                 # let's pass crypto import laws of some nasty countries
1745                 crypto_libs=`find Xonotic -name \*d0_rijndael\*`
1746                 if [ -n "$crypto_libs" ]; then
1747                         verbose mkzip Xonotic-$stamp-crypto.zip \
1748                                 $crypto_libs
1749                         rm -f $crypto_libs
1750                 fi
1751                 # build the archives
1752                 verbose mkzip Xonotic-$stamp-engine.zip \
1753                         Xonotic/*.dll \
1754                         Xonotic/bin64/*.dll \
1755                         Xonotic/*.app \
1756                         Xonotic/xonotic-* \
1757                         Xonotic/xonotic.exe \
1758                         Xonotic/source/darkplaces/
1759                 verbose cp Xonotic-$stamp-engine.zip Xonotic-$stamp-common.zip
1760                 verbose mkzip Xonotic-$stamp-common.zip \
1761                         Xonotic/source/fteqcc/ \
1762                         Xonotic/source/qcsrc/ \
1763                         Xonotic/Docs \
1764                         Xonotic/misc \
1765                         Xonotic/fteqcc \
1766                         Xonotic/server \
1767                         Xonotic/key_0.d0pk \
1768                         Xonotic/data/font-nimbussansl-$stamp.pk3
1769                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp.zip
1770                 verbose mkzip0 Xonotic-$stamp.zip \
1771                         Xonotic/data/xonotic-$stamp-data.pk3 \
1772                         Xonotic/data/xonotic-$stamp-maps.pk3 \
1773                         Xonotic/data/xonotic-$stamp-music.pk3 \
1774                         Xonotic/data/xonotic-$stamp-nexcompat.pk3
1775                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp-low.zip
1776                 verbose mkzip0 Xonotic-$stamp-low.zip \
1777                         Xonotic/data/xonotic-$stamp-data-low.pk3 \
1778                         Xonotic/data/xonotic-$stamp-maps-low.pk3 \
1779                         Xonotic/data/xonotic-$stamp-music-low.pk3
1780 #               verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp-high.zip
1781 #               verbose mkzip0 Xonotic-$stamp-high.zip \
1782 #                       Xonotic/data/xonotic-$stamp-data-raw.pk3 \
1783 #                       Xonotic/data/xonotic-$stamp-maps-raw.pk3 \
1784 #                       Xonotic/data/xonotic-$stamp-music.pk3 \
1785 #                       Xonotic/data/xonotic-$stamp-nexcompat.pk3
1786                 verbose mv Xonotic-$stamp-common.zip Xonotic-$stamp-lowdds.zip
1787                 verbose mkzip0 Xonotic-$stamp-lowdds.zip \
1788                         Xonotic/data/xonotic-$stamp-data-lowdds.pk3 \
1789                         Xonotic/data/xonotic-$stamp-maps-lowdds.pk3 \
1790                         Xonotic/data/xonotic-$stamp-music-low.pk3
1791                 ;;
1792         release)
1793                 verbose "$SELF" release-prepare
1794                 verbose "$SELF" release-maps
1795                 verbose "$SELF" release-engine
1796                 verbose "$SELF" release-qc
1797                 verbose "$SELF" release-pack-needsx11
1798                 verbose "$SELF" release-zip
1799                 ;;
1800
1801         *)
1802                 echo "Usage:"
1803                 echo "  $SELF admin-merge [<branch>]"
1804                 echo "  $SELF branch <branch>"
1805                 echo "  $SELF branch <remote> <branch> [<srcbranch>]"
1806                 echo "  $SELF branches"
1807                 echo "  $SELF checkout|switch <branch>"
1808                 echo "  $SELF checkout|switch <remote>/<branch>"
1809                 echo "  $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
1810                 echo "  $SELF clean --reclone"
1811                 echo "  $SELF compile [-c] [-r] [-0]"
1812                 echo "  $SELF each|foreach [-k] command..."
1813                 echo "  $SELF fix_upstream_rebase"
1814                 echo "  $SELF keygen"
1815                 echo "  $SELF merge"
1816                 echo "  $SELF push|commit [-s]"
1817                 echo "  $SELF release"
1818                 echo "  $SELF restore-patches"
1819                 echo "  $SELF run [sdl|glx|wgl|agl|dedicated] options..."
1820                 echo "  $SELF save-patches"
1821                 echo "  $SELF update-maps"
1822                 echo "  $SELF update|pull [-N] [-s | -h [-p] | -g [-p]] [-l de|nl|default]"
1823                 ;;
1824 esac