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