]> git.xonotic.org Git - xonotic/xonotic.git/blob - all
more help
[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="$d0/fteqcc/fteqcc.bin" "$@" $MAKEFLAGS clean
807                 fi
808                 verbose make FTEQCC="$d0/fteqcc/fteqcc.bin" "$@" $MAKEFLAGS
809
810                 enter "$d0/darkplaces" verbose
811                 if [ x"$BAD_TARGETS" = x" " ]; then
812                         echo "Warning: invalid empty client, default clients will be used."
813                 fi
814                 if $cleandp; then
815                         verbose make $MAKEFLAGS clean
816                 fi
817                 for T in $TARGETS; do
818                         verbose make $MAKEFLAGS STRIP=: "$@" "$T"
819                 done
820                 for T in $BAD_TARGETS; do
821                         echo "Warning: discarded invalid client $T."
822                 done
823
824                 verbose "$SELF" update-maps
825                 ;;
826         run)
827                 if [ -n "$WE_HATE_OUR_USERS" ]; then
828                         client=
829                         export PATH="$d0/misc/buildfiles/win32:$d0/d0_blind_id/.libs:$PATH"
830                 elif [ x"`uname`" = x"Darwin" ]; then
831                         export DYLD_LIBRARY_PATH="$d0/misc/buildfiles/osx/Xonotic-SDL.app/Contents/MacOS:$d0/d0_blind_id/.libs"
832                         export DYLD_FRAMEWORK_PATH="$d0/misc/buildfiles/osx/Xonotic-SDL.app/Contents/Frameworks"
833                         client=-sdl
834                 else
835                         export LD_LIBRARY_PATH="$d0/d0_blind_id/.libs"
836                         client=-sdl
837                 fi
838                 case "$1" in
839                         sdl|glx|agl|dedicated)
840                                 client=-$1
841                                 shift
842                                 ;;
843                         wgl)
844                                 client=
845                                 shift
846                                 ;;
847                 esac
848                 if ! [ -x "darkplaces/darkplaces$client" ]; then
849                         if [ -x "darkplaces/darkplaces$client.exe" ]; then
850                                 client=$client.exe
851                         else
852                                 echo "Client darkplaces/darkplaces$client not found, aborting"
853                                 exit 1
854                         fi
855                 fi
856                 set -- "darkplaces/darkplaces$client" -xonotic -mygames "$@"
857
858                 # if pulseaudio is running: USE IT
859                 if [ -z "$SDL_AUDIODRIVER" ] && ! [ -n "$WE_HATE_OUR_USERS" ] && ! [ x"`uname`" = x"Darwin" ]; then
860                         if ps -C pulseaudio >/dev/null; then
861                                 if ldd /usr/lib/libSDL.so 2>/dev/null | grep pulse >/dev/null; then
862                                         export SDL_AUDIODRIVER=pulse
863                                 fi
864                         fi
865                 fi
866
867                 binary=$1
868
869                 if [ -n "$USE_GDB" ]; then
870                         set -- gdb --args "$@"
871                 elif which gdb >/dev/null 2>&1; then
872                         set -- gdb --batch -x savecore.gdb --args "$@"
873                 elif which catchsegv >/dev/null 2>&1; then
874                         set -- catchsegv "$@"
875                 fi
876                 rm -f xonotic.core
877                 "$@" || true
878                 if [ -f xonotic.core ]; then
879                         if yesno "The program has CRASHED. Do you want to examine the core dump?"; then
880                                 gdb "$binary" xonotic.core
881                         #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
882                         #       tar cvzf xonotic.core.tar.gz xonotic.core darkplaces/*.c darkplaces/*.h
883                         #       # somehow send it
884                         #       rm -f xonotic.core.tar.gz
885                         else
886                                 echo "The core dump can be examined later by"
887                                 echo "  gdb $binary xonotic.core"
888                         fi
889                 fi
890                 ;;
891         each|foreach)
892                 keep_going=false
893                 if [ x"$1" = x"-k" ]; then
894                         keep_going=true
895                         shift
896                 fi
897                 for d in $repos; do
898                         if verbose cd "$d0/$d"; then
899                                 if $keep_going; then
900                                         verbose "$@" || true
901                                 else
902                                         verbose "$@"
903                                 fi
904                                 cd "$d0"
905                         fi
906                 done
907                 ;;
908         save-patches)
909                 outfile=$1
910                 patchdir=`mktemp -d -t save-patches.XXXXXX`
911                 for d in $repos; do
912                         enter "$d0/$d" verbose
913                         git branch -v -v | cut -c 3- | {
914                                 i=0
915                                 while read -r BRANCH REV UPSTREAM TEXT; do
916                                         case "$UPSTREAM" in
917                                                 \[*)
918                                                         UPSTREAM=${UPSTREAM#\[}
919                                                         UPSTREAM=${UPSTREAM%\]}
920                                                         UPSTREAM=${UPSTREAM%:*}
921                                                         TRACK=true
922                                                         ;;
923                                                 *)
924                                                         UPSTREAM=origin/"`repobranch "$d"`"
925                                                         TRACK=false
926                                                         ;;
927                                         esac
928                                         if [ x"$REV" = x"->" ]; then
929                                                 continue
930                                         fi
931                                         if git format-patch -o "$patchdir/$i" "$UPSTREAM".."$BRANCH"; then
932                                                 echo "$d" > "$patchdir/$i/info.txt"
933                                                 echo "$BRANCH" >> "$patchdir/$i/info.txt"
934                                                 echo "$UPSTREAM" >> "$patchdir/$i/info.txt"
935                                                 echo "$TRACK" >> "$patchdir/$i/info.txt"
936                                                 i=$(($i+1))
937                                         else
938                                                 rm -rf "$patchdir/$i"
939                                         fi
940                                 done
941                         }
942                 done
943                 ( cd "$patchdir" && tar cvzf - . ) > "$outfile"
944                 rm -rf "$patchdir"
945                 ;;
946         restore-patches)
947                 infile=$1
948                 patchdir=`mktemp -d -t restore-patches.XXXXXX`
949                 ( cd "$patchdir" && tar xvzf - ) < "$infile"
950                 # detach the head
951                 for P in "$patchdir"/*/info.txt; do
952                         D=${P%/info.txt}
953                         exec 3<"$P"
954                         read -r d <&3
955                         read -r BRANCH <&3
956                         read -r UPSTREAM <&3
957                         read -r TRACK <&3
958                         verbose git checkout HEAD^0
959                         verbose git branch -D "$BRANCH"
960                         if [ x"$TRACK" = x"true" ]; then
961                                 verbose git checkout --track -b "$BRANCH" "$UPSTREAM"
962                         else
963                                 verbose git branch -b "$BRANCH" "$UPSTREAM"
964                         fi
965                         verbose git am "$D"
966                 done
967                 rm -rf "$patchdir"
968                 ;;
969         admin-merge)
970                 branch=$1
971                 t=`mktemp`
972                 report=""
973                 reportecho()
974                 {
975                         report=$report"$*$LF"
976                         echo "$*"
977                 }
978                 reportecho4()
979                 {
980                         report=$report"    $*$LF"
981                         echo "    $*"
982                 }
983                 reportdo4()
984                 {
985                         o=`"$@" | sed 's/^/    /' || true`
986                         reportecho "$o"
987                 }
988                 for d in $repos; do
989                         enter "$d0/$d" verbose
990                         base="`repobranch "$d"`"
991                         reportecho "In $d:"
992                         for ref in `git for-each-ref --format='%(refname)' refs/remotes/origin/`; do
993                                 case "${ref#refs/remotes/origin/}" in
994                                         "$base")
995                                                 continue
996                                                 ;;
997                                         HEAD|master)
998                                                 continue
999                                                 ;;
1000                                         */*)
1001                                                 ;;
1002                                         *)
1003                                                 continue
1004                                                 ;;
1005                                 esac
1006                                 if [ -n "$branch" ]; then
1007                                         if [ x"$branch" != x"${ref#refs/remotes/origin/}" ]; then
1008                                                 continue
1009                                         fi
1010                                 fi
1011                                 case "$base" in
1012                                         master)
1013                                                 realbase=$base
1014                                                 ;;
1015                                         *)
1016                                                 l0=`git rev-list "$base".."$ref" | wc -l`
1017                                                 l1=`git rev-list master.."$ref" | wc -l`
1018                                                 if [ $l0 -gt $l1 ]; then
1019                                                         realbase=master
1020                                                 else
1021                                                         realbase=$base
1022                                                 fi
1023                                                 ;;
1024                                 esac
1025                                 reportecho "  Branch $ref:"
1026                                 note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1027                                 logdata=`git log --color "$realbase".."$ref"`
1028                                 if [ -z "$logdata" ]; then
1029                                         reportecho4 "--> not merging, no changes vs master"
1030                                         if yesno "Branch \"$ref\" probably should get deleted. Do it?" ''; then
1031                                                 git push origin :"${ref#refs/remotes/origin/}"
1032                                                 reportecho4 "--> branch deleted"
1033                                         fi
1034                                 else
1035                                         diffdata=`git diff --color --find-copies-harder --ignore-space-change "$realbase"..."$ref"`
1036                                         if [ -z "$diffdata" ]; then
1037                                                 reportecho4 "--> not merging, no changes vs master, branch contains redundant history"
1038                                                 if yesno "Branch \"$ref\" probably should get deleted. Do it?" '{ echo "$logdata"; } | less -r'; then
1039                                                         git push origin :"${ref#refs/remotes/origin/}"
1040                                                         reportecho4 "--> branch deleted"
1041                                                 fi
1042                                         elif [ -z "$branch" ] && [ -n "$note" ]; then
1043                                                 reportdo4 echo "$note"
1044                                                 reportecho4 "--> not merging, already had this one rejected before"
1045                                         elif yesno "Branch \"$ref\" may want to get merged. Do it?" '{ echo "$logdata"; echo "$diffdata"; } | less -r'; then
1046                                                 git checkout "$realbase"
1047                                                 org=`git rev-parse HEAD`
1048                                                 if ! git merge --no-ff "$ref" 2>&1 | tee "$t" && ! { git ls-files -u | grep ' 1 ' >/dev/null; }; then
1049                                                         git reset --hard "$org"
1050                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit -m "Merge failed:$LF`cat "$t"`" "$ref"
1051                                                         reportdo4 cat "$t"
1052                                                         reportecho4 "--> merge failed"
1053                                                 elif ! "$SELF" compile 2>&1 | tee "$t"; then
1054                                                         git reset --hard "$org"
1055                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit -m "Compile failed:$LF`cat "$t"`" "$ref"
1056                                                         reportdo4 cat "$t"
1057                                                         reportecho4 "--> compile failed"
1058                                                 elif ! yesno "Still merge \"$ref\" into `git symbolic-ref HEAD` of $d? Maybe you want to test first."; then
1059                                                         git reset --hard "$org"
1060                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit "$ref"
1061                                                         note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1062                                                         if [ x"$note" = x"del" ]; then
1063                                                                 git push origin :"${ref#refs/remotes/origin/}"
1064                                                                 reportecho4 "--> test failed, branch deleted"
1065                                                         elif [ -n "$note" ]; then
1066                                                                 reportdo4 echo "$note"
1067                                                                 reportecho4 "--> test failed"
1068                                                         else
1069                                                                 reportecho4 "--> test failed, postponed"
1070                                                         fi
1071                                                 else
1072                                                         echo "MERGING"
1073                                                         case ",`repoflags "$d"`," in
1074                                                                 *,svn,*)
1075                                                                         # we do quite a mess here... luckily we know $org
1076                                                                         git fetch # svn needs to be current
1077                                                                         git rebase -i --onto origin/master "$org"
1078                                                                         git svn dcommit --add-author-from
1079                                                                         git reset --hard "$org"
1080                                                                         ;;
1081                                                                 *)
1082                                                                         git push origin HEAD
1083                                                                         ;;
1084                                                         esac
1085                                                         reportecho4 "--> MERGED"
1086                                                         if yesno "Delete original branch \"$ref\"?"; then
1087                                                                 git push origin :"${ref#refs/remotes/origin/}"
1088                                                                 reportecho4 "--> branch deleted"
1089                                                         fi
1090                                                 fi
1091                                         else
1092                                                 GIT_NOTES_REF=refs/notes/admin-merge git notes edit "$ref"
1093                                                 note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1094                                                 if [ x"$note" = x"del" ]; then
1095                                                         git push origin :"${ref#refs/remotes/origin/}"
1096                                                         reportecho4 "--> branch deleted"
1097                                                 elif [ -n "$note" ]; then
1098                                                         reportdo4 echo "$note"
1099                                                         reportecho4 "--> rejected"
1100                                                 else
1101                                                         reportecho4 "--> postponed"
1102                                                 fi
1103                                         fi
1104                                 fi
1105                                 reportecho ""
1106                         done
1107                         reportecho ""
1108                 done
1109                 rm -f "$t"
1110                 echo "$report" | ssh nexuiz@rm.endoftheinternet.org cat '>>' public_html/xonotic-merge-notes.txt
1111                 ;;
1112         clean)
1113                 "$SELF" fix_config
1114                 "$SELF" update -N
1115                 force=false
1116                 gotoupstream=false
1117                 fetchupstream=false
1118                 gotomaster=false
1119                 rmuntracked=false
1120                 killbranches=false
1121                 # usage:
1122                 #   ./all clean [-m] [-f | -fu | -fU] [-r] [-D]
1123                 #   ./all clean --reclone
1124                 found=false
1125                 while :; do
1126                         if [ x"$1" = x"--reclone" ]; then
1127                                 force=true
1128                                 fetchupstream=true
1129                                 gotoupstream=true
1130                                 gotomaster=true
1131                                 rmuntracked=true
1132                                 killbranches=true
1133                         elif [ x"$1" = x"-f" ]; then
1134                                 force=true
1135                         elif [ x"$1" = x"-u" ]; then
1136                                 gotoupstream=true
1137                         elif [ x"$1" = x"-U" ]; then
1138                                 gotoupstream=true
1139                                 fetchupstream=true
1140                         elif [ x"$1" = x"-fu" ]; then
1141                                 force=true
1142                                 gotoupstream=true
1143                         elif [ x"$1" = x"-fU" ]; then
1144                                 force=true
1145                                 gotoupstream=true
1146                                 fetchupstream=true
1147                         elif [ x"$1" = x"-m" ]; then
1148                                 gotomaster=true
1149                         elif [ x"$1" = x"-r" ]; then
1150                                 rmuntracked=true
1151                         elif [ x"$1" = x"-D" ]; then
1152                                 killbranches=true
1153                         else
1154                                 break
1155                         fi
1156                         found=true
1157                         shift
1158                 done
1159                 if ! $found; then
1160                         rmuntracked=true
1161                 fi
1162                 for d in $repos; do
1163                         verbose cd "$d0/$d"
1164                         if $gotoupstream; then
1165                                 if ! $force; then
1166                                         msg "Must also use -f (delete local changes) when using -u"
1167                                         exit 1
1168                                 fi
1169                                 if $gotomaster; then
1170                                         if $fetchupstream; then
1171                                                 verbose git fetch origin
1172                                                 verbose git remote prune origin
1173                                         fi
1174                                         verbose git checkout -f "`repobranch "$d"`"
1175                                         verbose git reset --hard origin/"`repobranch "$d"`"
1176                                 else
1177                                         r=`git symbolic-ref HEAD`
1178                                         r=${r#refs/heads/}
1179                                         rem=`git config "branch.$r.remote" || echo origin`
1180                                         bra=`git config "branch.$r.merge" || echo "$r"`
1181                                         upstream="$rem/${bra#refs/heads/}"
1182                                         if $fetchupstream; then
1183                                                 verbose git fetch "$rem"
1184                                                 verbose git remote prune "$rem"
1185                                         fi
1186                                         if ! git rev-parse "$upstream" >/dev/null 2>&1; then
1187                                                 upstream="origin/`repobranch "$d"`"
1188                                         fi
1189                                         verbose git reset --hard "$upstream"
1190                                 fi
1191                         elif $gotomaster; then
1192                                 if $force; then
1193                                         verbose git checkout -f "`repobranch "$d"`"
1194                                         verbose git reset --hard
1195                                 else
1196                                         verbose git checkout "`repobranch "$d"`"
1197                                 fi
1198                         elif $force; then
1199                                 verbose git reset --hard
1200                         fi
1201                         if $rmuntracked; then
1202                                 case "$d" in
1203                                         .)
1204                                                 verbose git clean -df
1205                                                 ;;
1206                                         *)
1207                                                 verbose git clean -xdf
1208                                                 ;;
1209                                 esac
1210                         fi
1211                         if $killbranches; then
1212                                 git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
1213                                         if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
1214                                                 verbose git branch -D "${B#refs/heads/}"
1215                                         fi
1216                                 done
1217                                 git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch -t master origin/master || true
1218                                 git rev-parse "refs/heads/`repobranch "$d"`" >/dev/null 2>&1 || verbose git branch -t "`repobranch "$d"`" origin/"`repobranch "$d"`" || true
1219                         fi
1220                 done
1221                 ;;
1222
1223         # release building goes here
1224         release-prepare)
1225                 #"$SELF" each git clean -fxd
1226                 case "$RELEASETYPE" in
1227                         beta)
1228                                 msg "Building a BETA"
1229                                 ;;
1230                         release)
1231                                 msg "Building a RELEASE"
1232                                 ;;
1233                         *)
1234                                 echo >&2 -n "$ESC[2J$ESC[H"
1235                                 msg ""
1236                                 msg ""
1237                                 msg ""
1238                                 msg ""
1239                                 msg ""
1240                                 msg ""
1241                                 msg "        +---------------------------------------------------------.---+"
1242                                 msg "        | NOTE                                                    | X |"
1243                                 msg "        +---------------------------------------------------------^---+"
1244                                 msg "        |   ____                                                      |"
1245                                 msg "        |  /    \  This is the official release build system.         |"
1246                                 msg "        | |      | If you are not a member of the Xonotic Core Team,  |"
1247                                 msg "        | | STOP | you are not supposed to use this script and should |"
1248                                 msg "        | |      | instead use ./all compile to compile the engine    |"
1249                                 msg "        |  \____/  and game code.                                     |"
1250                                 msg "        |                                                             |"
1251                                 msg "        |                      [ I understand ]                       |"
1252                                 msg "        +-------------------------------------------------------------+"
1253                                 sleep 10
1254                                 # A LOT of build infrastructure is required:
1255                                 # - vorbis-tools
1256                                 # - ImageMagick
1257                                 # - .ssh/config must be configured so the following
1258                                 #   host names are reachable and have a compile
1259                                 #   infrastructure set up:
1260                                 #   - xonotic-build-linux32 (with gcc on x86)
1261                                 #   - xonotic-build-linux64 (with gcc on x86_64)
1262                                 #   - xonotic-build-win32 (with i586-mingw32msvc-g++)
1263                                 #   - xonotic-build-win64 (with amd64-mingw32msvc-g++
1264                                 #     and x86_64-w64-mingw32-g++)
1265                                 #   - xonotic-build-osx (with Xcode and SDL.framework)
1266                                 # - AMD Compressonator installed in WINE
1267                                 # - ResEdit installed in WINE
1268                                 # - a lot of other requirements you will figure out
1269                                 #   while reading the error messages
1270                                 # - environment variable RELEASETYPE set
1271                                 # - optionally, environment variable RELEASEDATE set
1272                                 #   (YYYYMMDD)
1273                                 exit 1
1274                                 ;;
1275                 esac
1276                 verbose rm -rf Xonotic Xonotic*.zip
1277                 verbose mkdir -p Xonotic
1278                 if [ -n "$RELEASEDATE" ]; then
1279                         verbose echo "$RELEASEDATE" > Xonotic/stamp.txt
1280                 else
1281                         verbose date +%Y%m%d > Xonotic/stamp.txt
1282                 fi
1283                 verbose git archive --format=tar HEAD -- Docs misc server xonotic-linux-glx.sh xonotic-linux-sdl.sh misc/buildfiles key_0.d0pk | {
1284                         verbose cd Xonotic
1285                         verbose mkdir data fteqcc source source/darkplaces source/fteqcc
1286                         verbose tar xvf -
1287                         verbose rm -rf misc/builddeps
1288                         verbose mv misc/buildfiles/win32/* . || true
1289                         verbose mv misc/buildfiles/win64 bin64 || true
1290                         verbose mv misc/buildfiles/osx/* . || true
1291                         verbose rm -rf misc/buildfiles
1292                         verbose rm -rf misc/pki
1293                 }
1294                 {
1295                         verbose cd darkplaces
1296                         verbose git archive --format=tar HEAD
1297                 } | {
1298                         verbose cd Xonotic/source/darkplaces
1299                         verbose tar xvf -
1300                 }
1301                 {
1302                         verbose cd fteqcc
1303                         verbose git archive --format=tar HEAD
1304                 } | {
1305                         verbose cd Xonotic/source/fteqcc
1306                         verbose tar xvf -
1307                 }
1308                 {
1309                         verbose cd data/xonotic-data.pk3dir
1310                         verbose git archive --format=tar HEAD -- qcsrc Makefile
1311                 } | {
1312                         verbose cd Xonotic/source
1313                         verbose tar xvf -
1314                 }
1315                 rm -f Xonotic/key_15.d0pk
1316                 ;;
1317         release-compile-run)
1318                 host=$1
1319                 buildpath=$2
1320                 maketargets=$3
1321                 makeflags=$4
1322                 srcdir=$5
1323                 depsdir=$6
1324                 targetfiles=$7
1325                 set -x
1326                 if [ -n "$targetfiles" ]; then
1327                         case " $HOSTS_THAT_ARE_DISABLED " in
1328                                 *\ $host\ *)
1329                                         exit
1330                                         ;;
1331                         esac
1332                         case " $HOSTS_THAT_ARE_MYSELF " in
1333                                 *\ $host\ *)
1334                                         verbose rsync --delete -zLvaSHP "$srcdir"/ "$buildpath/"
1335                                         verbose rsync --delete -zLvaSHP "$depsdir"/ "$buildpath.deps/"
1336                                         verbose ln -snf "$buildpath.deps" "$buildpath/.deps"
1337                                         verbose eval make -C "$buildpath" clean $maketargets $makeflags
1338                                         for f in $targetfiles; do
1339                                                 verbose mv "$buildpath/${f%:*}" "${f##*:}" || true
1340                                         done
1341                                         ;;
1342                                 *)
1343                                         verbose rsync --delete -zLvaSHP "$srcdir"/ "$host:$buildpath/"
1344                                         verbose rsync --delete -zLvaSHP "$depsdir"/ "$host:$buildpath.deps/"
1345                                         verbose ssh "$host" "ln -snf $buildpath.deps $buildpath/.deps && cd $buildpath && nice -`nice` make clean $maketargets $makeflags"
1346                                         for f in $targetfiles; do
1347                                                 verbose rsync -zvaSHP "$host:$buildpath/${f%:*}" "${f##*:}" || true
1348                                         done
1349                                         ;;
1350                         esac
1351                         # now rebrand the binaries...
1352                         for f in $targetfiles; do
1353                                 #verbose "$d0/misc/tools/rebrand-darkplaces-engine.sh" "${XONOTIC_BRAND:-$d0/misc/tools/xonotic.brand}" "${f##*:}" || true
1354                                 case "$f" in
1355                                         xonotic*.exe)
1356                                                 verbose "$d0/misc/tools/change-icon-of-exe.sh" "$d0/misc/logos/icons_ico/xonotic.ico" "$f"
1357                                                 (
1358                                                         d=`mktemp -d -t rebrand.XXXXXX`
1359                                                         cd "$d"
1360                                                         echo "-mygames" > darkplaces.opt
1361                                                         zip -9r darkplaces.zip darkplaces.opt
1362                                                         cat darkplaces.zip
1363                                                         cd "$d0"
1364                                                         rm -rf "$d"
1365                                                 ) >> "$f"
1366                                                 ;;
1367                                 esac
1368                         done
1369                 fi
1370                 ;;
1371         release-compile)
1372                 suffix=$1
1373                 makeflags=$2
1374                 fteqcc_maketargets=$3
1375                 fteqcc_files=$4
1376                 darkplaces_maketargets=$5
1377                 darkplaces_files=$6
1378                 host=xonotic-build-$suffix
1379                 verbose "$SELF" release-compile-run "$host" /tmp/fteqcc.build."$suffix" "$fteqcc_maketargets" "$makeflags" "Xonotic/source/fteqcc" "$d0/misc/builddeps/dp.$suffix" "$fteqcc_files"
1380                 verbose "$SELF" release-compile-run "$host" /tmp/Darkplaces.build."$suffix" "$darkplaces_maketargets" "$makeflags" "Xonotic/source/darkplaces" "$d0/misc/builddeps/dp.$suffix" "$darkplaces_files"
1381                 ;;
1382         release-engine-win32)
1383                 verbose "$SELF" release-compile win32 \
1384                         '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' \
1385                         win 'fteqcc.exe:Xonotic/fteqcc/fteqcc.exe' \
1386                         '' ''
1387                 verbose "$SELF" release-compile win32 \
1388                         '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' \
1389                         '' '' \
1390                         release 'darkplaces.exe:Xonotic/xonotic.exe darkplaces-sdl.exe:Xonotic/xonotic-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-dedicated.exe'
1391                 ;;
1392         release-engine-win64)
1393                 verbose "$SELF" release-compile win64 \
1394                         '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' \
1395                         win 'fteqcc.exe:Xonotic/fteqcc/fteqcc-x64.exe' \
1396                         'sv-release sdl-release' 'darkplaces-sdl.exe:Xonotic/xonotic-x64-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-x64-dedicated.exe'
1397                 verbose "$SELF" release-compile win64 \
1398                         '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' \
1399                         '' '' \
1400                         cl-release 'darkplaces.exe:Xonotic/xonotic-x64.exe'
1401                 ;;
1402         release-engine-osx)
1403                 # gcc on OSX is buggy, needs -fno-reorder-blocks for a release build to succeed
1404                 verbose "$SELF" release-compile osx \
1405                         '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"' \
1406                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.osx' \
1407                         'sv-release sdl-release' 'darkplaces-sdl:Xonotic/Xonotic-SDL.app/Contents/MacOS/xonotic-osx-sdl-bin darkplaces-dedicated:Xonotic/xonotic-osx-dedicated'
1408                 verbose "$SELF" release-compile osx \
1409                         '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"' \
1410                         '' '' \
1411                         'cl-release' 'darkplaces-agl:Xonotic/Xonotic.app/Contents/MacOS/xonotic-osx-agl-bin'
1412                 ;;
1413         release-engine-linux32)
1414                 verbose "$SELF" release-compile linux32 \
1415                         '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' \
1416                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux32' \
1417                         release 'darkplaces-glx:Xonotic/xonotic-linux32-glx darkplaces-sdl:Xonotic/xonotic-linux32-sdl darkplaces-dedicated:Xonotic/xonotic-linux32-dedicated'
1418                 ;;
1419         release-engine-linux64)
1420                 verbose "$SELF" release-compile linux64 \
1421                         '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' \
1422                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux64' \
1423                         release 'darkplaces-glx:Xonotic/xonotic-linux64-glx darkplaces-sdl:Xonotic/xonotic-linux64-sdl darkplaces-dedicated:Xonotic/xonotic-linux64-dedicated'
1424                 ;;
1425         release-engine)
1426                 verbose "$SELF" release-engine-linux32 &
1427                 verbose "$SELF" release-engine-linux64 &
1428                 verbose "$SELF" release-engine-win32 &
1429                 verbose "$SELF" release-engine-win64 &
1430                 verbose "$SELF" release-engine-osx &
1431                 wait %1
1432                 wait %2
1433                 wait %3
1434                 wait %4
1435                 wait %5
1436                 wait
1437                 ;;
1438         release-maps)
1439                 verbose "$SELF" update-maps
1440                 ;;
1441         release-qc)
1442                 case "$RELEASETYPE" in
1443                         beta)
1444                                 verbose make -C Xonotic/source FTEQCC="$d0/Xonotic/fteqcc/fteqcc.linux32" XON_BUILDSYSTEM=1 clean all
1445                                 ;;
1446                         release)
1447                                 verbose make -C Xonotic/source FTEQCC="$d0/Xonotic/fteqcc/fteqcc.linux32" XON_BUILDSYSTEM=1 FTEQCCFLAGS_WATERMARK= clean all
1448                                 ;;
1449                 esac
1450                 verbose rm -f Xonotic/source/*/fteqcc.log
1451                 ;;
1452         release-buildpk3-transform-raw)
1453                 dir=$1
1454                 ;;
1455         release-buildpk3-transform-normal)
1456                 dir=$1
1457                 verbose cd "$dir"
1458                 # texture: convert to jpeg and dds
1459                 verbose export do_jpeg=true
1460                 verbose export jpeg_qual_rgb=95
1461                 verbose export jpeg_qual_a=99
1462                 verbose export do_dds=true
1463                 verbose export dds_flags=
1464                 verbose export do_ogg=false
1465                 verbose export del_src=true
1466                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1467                 ;;
1468         release-buildpk3-transform-low)
1469                 dir=$1
1470                 verbose cd "$dir"
1471                 # texture: convert to jpeg and dds
1472                 # music: reduce bitrate
1473                 verbose export do_jpeg=true
1474                 verbose export jpeg_qual_rgb=80
1475                 verbose export jpeg_qual_a=95
1476                 verbose export do_dds=false
1477                 verbose export do_ogg=true
1478                 verbose export ogg_qual=1
1479                 verbose export del_src=true
1480                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1481                 ;;
1482         release-buildpk3-transform-lowdds)
1483                 dir=$1
1484                 verbose cd "$dir"
1485                 # texture: convert to jpeg and dds
1486                 # music: reduce bitrate
1487                 verbose export do_jpeg=false
1488                 verbose export do_jpeg_if_not_dds=true
1489                 verbose export jpeg_qual_rgb=80
1490                 verbose export jpeg_qual_a=95
1491                 verbose export do_dds=true
1492                 verbose export dds_flags=
1493                 verbose export do_ogg=true
1494                 verbose export ogg_qual=1
1495                 verbose export del_src=true
1496                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1497                 ;;
1498         release-buildpk3)
1499                 src=$1
1500                 dst=$2
1501                 transform=$3
1502                 case "$dst" in
1503                         /*)
1504                                 ;;
1505                         */)
1506                                 dst="$PWD/$dst"
1507                                 ;;
1508                 esac
1509                 verbose rm -rf Xonotic/temp
1510                 verbose mkdir -p Xonotic/temp
1511                 {
1512                         verbose cd "$src"
1513                         verbose git archive --format=tar HEAD
1514                 } | {
1515                         verbose cd Xonotic/temp
1516                         verbose tar xvf -
1517                 }
1518                 verbose cd Xonotic/temp
1519                 if [ x"$src" = x"data/xonotic-data.pk3dir" ]; then
1520                         verbose cp ../source/progs.dat .
1521                         verbose cp ../source/csprogs.dat .
1522                         verbose cp ../source/menu.dat .
1523                         verbose rm -rf qcsrc
1524                         gv=`grep "^gameversion " "defaultXonotic.cfg" | awk '{ print $2 }'`
1525                         major=$(($gv / 10000))
1526                         minor=$(($gv / 100 - $major * 100))
1527                         patch=$(($gv - $major * 10000 - $minor * 100))
1528                         versionstr="$major.$minor.$patch"
1529                         case "$RELEASETYPE" in
1530                                 beta)
1531                                         versionstr="$versionstr""beta"
1532                                         ;;
1533                         esac
1534                         verbose sed -i "
1535                                 s/^set g_xonoticversion [^ ]* /set g_xonoticversion $versionstr /;
1536                                 s/^gameversion_min [0-9]*/gameversion_min $(( ($gv / 100) * 100 - 100 ))/;
1537                                 s/^gameversion_max [0-9]*/gameversion_max $(( ($gv / 100) * 100 + 199 ))/;
1538                         " defaultXonotic.cfg
1539                         (
1540                                 verbose cd gfx/menu/luminos
1541                                 verbose cp "$d0"/mediasource/gfx/menu/luminos_versionbuilder/background_l2.svg .
1542                                 verbose "$d0"/mediasource/gfx/menu/luminos_versionbuilder/versionbuilder "$versionstr"
1543                                 verbose rm background_l2.svg
1544                         )
1545                 fi
1546                 if [ x"$src" = x"data/xonotic-maps.pk3dir" ]; then
1547                         for X in ../../data/*-????????????????????????????????????????-????????????????????????????????????????.pk3; do
1548                                 if [ -f "$X" ]; then
1549                                         verbose unzip "$X"
1550                                         verbose rm -f maps/*.log maps/*.irc maps/*.lin
1551                                 fi
1552                         done
1553                 fi
1554                 verbose export git_src_repo="$d0/$src" # skip hash-object
1555                 verbose "$SELF" release-buildpk3-transform-$transform "Xonotic/temp"
1556                 verbose mkzip "../../$dst" *
1557                 verbose cd ../..
1558                 verbose rm -rf Xonotic/temp
1559                 ;;
1560         release-buildpk3s)
1561                 stamp=`cat Xonotic/stamp.txt`
1562                 src=$1
1563                 shift
1564                 dst=${src%.pk3dir}
1565                 case "$dst" in
1566                         data/xonotic-*)
1567                                 dst="data/xonotic-$stamp-${dst#data/xonotic-}"
1568                                 ;;
1569                         *)
1570                                 dst="$dst-$stamp"
1571                                 ;;
1572                 esac
1573                 while [ "$#" -gt 1 ]; do
1574                         verbose "$SELF" release-buildpk3 "$src" "Xonotic/$dst$2.pk3" "$1"
1575                         shift
1576                         shift
1577                 done
1578                 ;;
1579         release-pack)
1580                 verbose "$SELF" release-buildpk3s data/font-nimbussansl.pk3dir             raw ''
1581                 verbose "$SELF" release-buildpk3s data/xonotic-data.pk3dir       normal '' raw '-raw' low '-low' lowdds '-lowdds'
1582                 verbose "$SELF" release-buildpk3s data/xonotic-maps.pk3dir       normal '' raw '-raw' low '-low' lowdds '-lowdds'
1583                 verbose "$SELF" release-buildpk3s data/xonotic-music.pk3dir                raw ''     low '-low'
1584                 verbose "$SELF" release-buildpk3s data/xonotic-nexcompat.pk3dir                       low ''
1585                 ;;
1586         release-pack-needsx11)
1587                 case "$DISPLAY" in
1588                         '')
1589                                 verbose startx "$SELF" release-pack -- /usr/bin/Xvfb :7
1590                                 ;;
1591                         *)
1592                                 verbose "$SELF" release-pack
1593                                 ;;
1594                 esac
1595                 ;;
1596         release-zip)
1597                 stamp=`cat Xonotic/stamp.txt`
1598                 # exe and dll files do not need +x, so this makes them eligible for 7zip compression too
1599                 chmod a-x Xonotic/*.exe Xonotic/*.dll || true
1600                 # let's pass crypto import laws of some nasty countries
1601                 crypto_libs=`find Xonotic -name \*d0_rijndael\*`
1602                 if [ -n "$crypto_libs" ]; then
1603                         verbose mkzip Xonotic-$stamp-crypto.zip \
1604                                 $crypto_libs
1605                         rm -f $crypto_libs
1606                 fi
1607                 # build the archives
1608                 verbose mkzip Xonotic-$stamp-engine.zip \
1609                         Xonotic/*.dll \
1610                         Xonotic/bin64/*.dll \
1611                         Xonotic/*.app \
1612                         Xonotic/xonotic-* \
1613                         Xonotic/xonotic.exe \
1614                         Xonotic/source/darkplaces/
1615                 verbose cp Xonotic-$stamp-engine.zip Xonotic-$stamp-common.zip
1616                 verbose mkzip Xonotic-$stamp-common.zip \
1617                         Xonotic/source/fteqcc/ \
1618                         Xonotic/source/qcsrc/ \
1619                         Xonotic/Docs \
1620                         Xonotic/misc \
1621                         Xonotic/fteqcc \
1622                         Xonotic/server \
1623                         Xonotic/key_0.d0pk \
1624                         Xonotic/data/font-nimbussansl-$stamp.pk3
1625                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp.zip
1626                 verbose mkzip0 Xonotic-$stamp.zip \
1627                         Xonotic/data/xonotic-$stamp-data.pk3 \
1628                         Xonotic/data/xonotic-$stamp-maps.pk3 \
1629                         Xonotic/data/xonotic-$stamp-music.pk3 \
1630                         Xonotic/data/xonotic-$stamp-nexcompat.pk3
1631                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp-low.zip
1632                 verbose mkzip0 Xonotic-$stamp-low.zip \
1633                         Xonotic/data/xonotic-$stamp-data-low.pk3 \
1634                         Xonotic/data/xonotic-$stamp-maps-low.pk3 \
1635                         Xonotic/data/xonotic-$stamp-music-low.pk3
1636                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp-lowdds.zip
1637                 verbose mkzip0 Xonotic-$stamp-lowdds.zip \
1638                         Xonotic/data/xonotic-$stamp-data-lowdds.pk3 \
1639                         Xonotic/data/xonotic-$stamp-maps-lowdds.pk3 \
1640                         Xonotic/data/xonotic-$stamp-music-low.pk3
1641                 verbose mv Xonotic-$stamp-common.zip Xonotic-$stamp-high.zip
1642                 verbose mkzip0 Xonotic-$stamp-high.zip \
1643                         Xonotic/data/xonotic-$stamp-data-raw.pk3 \
1644                         Xonotic/data/xonotic-$stamp-maps-raw.pk3 \
1645                         Xonotic/data/xonotic-$stamp-music.pk3 \
1646                         Xonotic/data/xonotic-$stamp-nexcompat.pk3
1647                 ;;
1648         release)
1649                 verbose "$SELF" release-prepare
1650                 verbose "$SELF" release-maps
1651                 verbose "$SELF" release-engine
1652                 verbose "$SELF" release-qc
1653                 verbose "$SELF" release-pack-needsx11
1654                 verbose "$SELF" release-zip
1655                 ;;
1656
1657         *)
1658                 echo "Usage:"
1659                 echo "  $SELF admin-merge [<branch>]"
1660                 echo "  $SELF branch <branch>"
1661                 echo "  $SELF branch <remote> <branch> [<srcbranch>]"
1662                 echo "  $SELF branches"
1663                 echo "  $SELF checkout|switch <branch>"
1664                 echo "  $SELF checkout|switch <remote>/<branch>"
1665                 echo "  $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
1666                 echo "  $SELF clean --reclone"
1667                 echo "  $SELF compile [-c] [-r] [-0]"
1668                 echo "  $SELF each|foreach [-k] command..."
1669                 echo "  $SELF fix_upstream_rebase"
1670                 echo "  $SELF keygen"
1671                 echo "  $SELF merge"
1672                 echo "  $SELF push|commit [-s]"
1673                 echo "  $SELF release"
1674                 echo "  $SELF restore-patches"
1675                 echo "  $SELF run [sdl|glx|wgl|agl|dedicated] options..."
1676                 echo "  $SELF save-patches"
1677                 echo "  $SELF update-maps"
1678                 echo "  $SELF update|pull [-N] [-s | -h [-p] | -g [-p]]"
1679                 ;;
1680 esac