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