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