remove the common spog
[xonotic/xonotic.git] / all
1 #!/bin/sh
2 # vim: filetype=zsh
3
4 set -e
5
6 d00=`pwd`
7 while ! [ -f ./all ]; do
8         if [ x"`pwd`" = x"/" ]; then
9                 echo "Cannot find myself."
10                 echo "Please run this script with the working directory inside a Xonotic checkout."
11                 exit 1
12         fi
13         cd ..
14 done
15 d0=`pwd`
16 SELF="$d0/all"
17
18 # If we are on WINDOWS:
19 case "$0" in
20         all|*/all)
21                 case "`uname`" in
22                         MINGW*|Win*)
23                                 # Windows hates users. So this script has to copy itself elsewhere first...
24                                 tname=
25                                 cp "$SELF" ../all.xonotic.sh
26                                 export WE_HATE_OUR_USERS=1
27                                 exec ../all.xonotic.sh "$@"
28                                 ;;
29                 esac
30                 ;;
31 esac
32
33 msg()
34 {
35         echo "\e[1m$*\e[m"
36 }
37
38 checksum()
39 {
40         if [ -x /usr/bin/md5sum ]; then
41                 /usr/bin/md5sum "$@"
42         elif [ -x /bin/md5sum ]; then
43                 /bin/md5sum "$@"
44         elif [ -x /usr/bin/cksum ]; then
45                 /usr/bin/cksum "$@"
46         else
47                 echo "NOCHECKSUM"
48         fi
49 }
50
51 self=`checksum "$SELF"`
52 checkself()
53 {
54         self_new=`checksum "$SELF"`
55         if [ x"$self" != x"$self_new" ]; then
56                 msg "./all has changed."
57                 if [ -z "$XONOTIC_FORBID_RERUN_ALL" ]; then
58                         msg "Rerunning the requested operation to make sure."
59                         export XONOTIC_FORBID_RERUN_ALL=1
60                         exec "$SELF" "$@"
61                 else
62                         msg "Please try $SELF update, and then retry your requested operation."
63                         exit 1
64                 fi
65         fi
66         return 0
67 }
68
69 verbose()
70 {
71         msg "+ $*"
72         "$@"
73 }
74
75 visible_repo_name()
76 {
77         case "$1" in
78                 .)
79                         echo "the root directory"
80                         ;;
81                 *)
82                         echo "\"$1\""
83                         ;;
84         esac
85 }
86
87 check_mergeconflict()
88 {
89         if git ls-files -u | grep ' 1   '; then
90                 echo
91                 echo "MERGE CONFLICT."
92                 echo "change into the \"$1\" project directory, and then:"
93                 echo "- edit the files mentioned above with your favorite editor,"
94                 echo "  and fix the conflicts (marked with <<<<<<< blocks)"
95                 echo "- for binary files, you can select the files using"
96                 echo "  git checkout --ours or git checkout --theirs"
97                 echo "- when done with a file, 'git add' the file"
98                 echo "- when done, 'git commit'"
99                 echo
100                 exit 1
101         fi
102 }
103
104 enter()
105 {
106         $2 cd "$1"
107         check_mergeconflict "$1"
108 }
109
110 repos_urls="
111 .                             |                                                   | master
112 data/xonotic-data.pk3dir      |                                                   | master
113 data/xonotic-maps.pk3dir      |                                                   | master
114 data/xonotic-music.pk3dir     |                                                   | master
115 data/xonotic-nexcompat.pk3dir |                                                   | master
116 darkplaces                    |                                                   | div0-stable
117 fteqcc                        | git://github.com/Blub/qclib.git                   | master
118 div0-gittools                 | git://git.icculus.org/divverent/div0-gittools.git | master
119 netradiant                    |                                                   | master
120 "
121 # todo: in darkplaces, change repobranch to div0-stable
122
123 repos=`echo "$repos_urls" | grep . | cut -d '|' -f 1 | tr -d ' '`
124
125 base=`git config remote.origin.url`
126 base=${base%xonotic.git}
127
128 repourl()
129 {
130         t=`echo "$repos_urls" | grep "^$1 " | cut -d '|' -f 2 | tr -d ' '`
131         if [ -n "$t" ]; then
132                 echo "$t"
133         else
134                 if [ x"$1" = x"." ]; then
135                         echo "$base""xonotic.git"
136                 else
137                         echo "$base${1##*/}.git"
138                 fi
139         fi
140 }
141
142 repobranch()
143 {
144         t=`echo "$repos_urls" | grep "^$1 " | cut -d '|' -f 3 | tr -d ' '`
145         if [ -n "$t" ]; then
146                 echo "$t"
147         else
148                 echo "master"
149         fi
150 }
151
152 repos=`for d in $repos; do
153         p="${d%dir}"
154         if [ x"$p" = x"$d" ] || [ -d "$d" ] || ! [ -f "$p" ]; then
155                 echo "$d"
156         fi
157 done`
158
159 if [ "$#" = 0 ]; then
160         set -- help
161 fi
162 cmd=$1
163 shift
164
165 case "$cmd" in
166         update|pull)
167                 for d in $repos; do
168                         url=`repourl "$d"`
169                         branch=`repobranch "$d"`
170                         if [ -d "$d0/$d" ]; then
171                                 enter "$d0/$d" verbose
172                                 verbose git config remote.origin.url "$url"
173                                 verbose git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
174                                         # TODO remove this line later
175
176                                 verbose git config core.autocrlf false
177                                 verbose git config core.safecrlf false # we don't NEED that...
178
179                                 r=`git symbolic-ref HEAD`
180                                 r=${r#refs/heads/}
181                                 if git config branch.$r.remote >/dev/null 2>&1; then
182                                         if ! verbose git pull; then
183                                                 check_mergeconflict "$d"
184                                                 echo "Pulling failed. Press ENTER to continue, or Ctrl-C to abort."
185                                                 read -r DUMMY
186                                         fi
187                                 fi
188
189                                 cd "$d00"
190                                 checkself "$cmd" "$@"
191                                 cd "$d0/$d"
192                                 verbose git remote prune origin
193                                 cd "$d0"
194                         else
195                                 verbose git clone "$url" "$d0/$d"
196                                 enter "$d0/$d" verbose
197                                 verbose git checkout "$branch"
198                                 cd "$d0"
199                         fi
200                 done
201                 ;;
202         checkout|switch)
203                 remote=$1
204                 branch=$2
205                 if [ -z "$branch" ]; then
206                         branch=$remote
207                         remote=origin
208                 fi
209                 exists=false
210                 for d in $repos; do
211                         enter "$d0/$d" verbose
212                         if git rev-parse "refs/heads/$branch" >/dev/null 2>&1; then
213                                 exists=true
214                                 verbose git checkout "$branch"
215                         elif git rev-parse "refs/remotes/$remote/$branch" >/dev/null 2>&1; then
216                                 exists=true
217                                 verbose git checkout --track -b "$branch" "$remote/$branch"
218                         else
219                                 verbose git checkout "`repobranch "$d"`"
220                         fi
221                         cd "$d00"
222                         checkself "$cmd" "$@"
223                         cd "$d0"
224                 done
225                 if ! $exists; then
226                         echo "The requested branch was not found in any repository."
227                 fi
228                 exec "$SELF" branch
229                 ;;
230         branch)
231                 remote=$1
232                 branch=$2
233                 srcbranch=$3
234                 if [ -z "$branch" ]; then
235                         branch=$remote
236                         remote=origin
237                 fi
238                 if [ -z "$branch" ]; then
239                         for d in $repos; do
240                                 enter "$d0/$d"
241                                 r=`git symbolic-ref HEAD`
242                                 r=${r#refs/heads/}
243                                 echo "$d is at $r"
244                                 cd "$d0"
245                         done
246                 else
247                         for d in $repos; do
248                                 dv=`visible_repo_name "$d"`
249                                 enter "$d0/$d" verbose
250                                 a=
251                                 if git rev-parse "refs/heads/$branch" >/dev/null 2>&1; then
252                                         echo "Already having this branch in $dv."
253                                 else
254                                         while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
255                                                 echo "Branch in $dv?"
256                                                 read -r a
257                                         done
258                                         if [ x"$a" = x"y" ]; then
259                                                 if [ -n "$srcbranch" ]; then
260                                                         b=$srcbranch
261                                                 else
262                                                         b="`repobranch "$d"`"
263                                                 fi
264                                                 verbose git push "$remote" "$b":"$branch"
265                                                 verbose git checkout --track -b "$branch" "$remote/$branch"
266                                         fi
267                                 fi
268                                 cd "$d0"
269                         done
270                         "$SELF" branch
271                 fi
272                 ;;
273         branches)
274                 for d in $repos; do
275                         enter "$d0/$d"
276                         echo "In $d:"
277                         git branch -a -v -v | cut -c 3- | while read -r BRANCH REV UPSTREAM TEXT; do
278                                 case "$UPSTREAM" in
279                                         \[*)
280                                                 UPSTREAM=${UPSTREAM#\[}
281                                                 UPSTREAM=${UPSTREAM%\]}
282                                                 UPSTREAM=${UPSTREAM%:*}
283                                                 ;;
284                                         *)
285                                                 TEXT="$UPSTREAM $TEXT"
286                                                 UPSTREAM=
287                                                 ;;
288                                 esac
289                                 if [ x"$REV" = x"->" ]; then
290                                         continue
291                                 fi
292                                 BRANCH=${BRANCH#remotes/}
293                                 echo -n "  $BRANCH"
294                                 if [ -n "$UPSTREAM" ]; then
295                                         echo -n " (tracking $UPSTREAM)"
296                                 fi
297                                 #echo " $TEXT"
298                                 echo
299                         done
300                 done
301                 ;;
302         merge)
303                 for d in $repos; do
304                         dv=`visible_repo_name "$d"`
305                         enter "$d0/$d" verbose
306                         r=`git symbolic-ref HEAD`
307                         r=${r#refs/heads/}
308                         if git log HEAD..origin/"`repobranch "$d"`" | grep .; then
309                                 # we have uncommitted changes
310                                 a=
311                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
312                                         echo "Could merge from \"`repobranch "$d"`\" into \"$r\" in $dv. Do it?"
313                                         read -r a
314                                 done
315                                 if [ x"$a" = x"y" ]; then
316                                         if ! verbose git merge origin/"`repobranch "$d"`"; then
317                                                 check_mergeconflict "$d"
318                                                 exit 1 # this should ALWAYS be fatal
319                                         fi
320                                 fi
321                         fi
322                         cd "$d0"
323                 done
324                 ;;
325         push|commit)
326                 submit=$1
327                 for d in $repos; do
328                         dv=`visible_repo_name "$d"`
329                         enter "$d0/$d" verbose
330                         r=`git symbolic-ref HEAD`
331                         r=${r#refs/heads/}
332                         if git diff HEAD | grep .; then
333                                 # we have uncommitted changes
334                                 a=
335                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
336                                         echo "Uncommitted changes in \"$r\" in $dv. Commit?"
337                                         read -r a
338                                 done
339                                 if [ x"$a" = x"y" ]; then
340                                         verbose git commit -a
341                                 fi
342                         fi
343                         rem=`git config "branch.$r.remote" || echo origin`
344                         if { git log "$rem/$r".."$r" || git log origin/"`repobranch "$d"`".."$r"; } | grep .; then
345                                 a=
346                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
347                                         echo "Push \"$r\" in $dv?"
348                                         read -r a
349                                 done
350                                 if [ x"$a" = x"y" ]; then
351                                         verbose git push "$rem" HEAD
352                                 fi
353                         fi
354                         if [ x"$submit" = x"-s" ]; then
355                                 case "$r" in
356                                         */*)
357                                                 verbose git push "$rem" HEAD:"${r%%/*}/finished/${r#*/}"
358                                                 ;;
359                                 esac
360                         fi
361                         cd "$d0"
362                 done
363                 ;;
364         compile)
365                 if [ -n "$WE_HATE_OUR_USERS" ]; then
366                         TARGETS="sv-debug cl-debug"
367                 else
368                         TARGETS="sv-debug cl-debug sdl-debug"
369                 fi
370                 case "$1" in
371                         sdl)
372                                 TARGETS="sdl-debug"
373                                 shift
374                                 ;;
375                         glx|agl|wgl)
376                                 TARGETS="cl-debug"
377                                 shift
378                                 ;;
379                         dedicated)
380                                 TARGETS="sv-debug"
381                                 shift
382                                 ;;
383                 esac
384                 if [ -z "$MAKEFLAGS" ]; then
385                         if [ -f /proc/cpuinfo ]; then
386                                 ncpus=$((`grep -c '^processor   :' /proc/cpuinfo`+0))
387                                 if [ $ncpus -gt 1 ]; then
388                                         MAKEFLAGS=-j$ncpus
389                                 fi
390                         fi
391                 fi
392                 enter "$d0/fteqcc" verbose
393                 verbose make $MAKEFLAGS
394                 enter "$d0/data/xonotic-data.pk3dir" verbose
395                 verbose make FTEQCC="$d0/fteqcc/fteqcc.bin" $MAKEFLAGS
396                 enter "$d0/darkplaces" verbose
397                 for T in $TARGETS; do
398                         verbose make $MAKEFLAGS "$T"
399                 done
400                 ;;
401         run)
402                 if [ -n "$WE_HATE_OUR_USERS" ]; then
403                         client=
404                         export PATH="$d0/misc/buildfiles/w32:$PATH"
405                 else
406                         client=-sdl
407                 fi
408                 case "$1" in
409                         sdl|glx|agl|dedicated)
410                                 client=-$1
411                                 shift
412                                 ;;
413                         wgl)
414                                 client=
415                                 shift
416                                 ;;
417                 esac
418                 if ! [ -x "darkplaces/darkplaces$client" ]; then
419                         if [ -x "darkplaces/darkplaces$client.exe" ]; then
420                                 client=$client.exe
421                         else
422                                 echo "Client darkplaces/darkplaces$client not found, aborting"
423                                 exit 1
424                         fi
425                 fi
426                 set -- "darkplaces/darkplaces$client" -nexuiz -customgamename Xonotic -customgamedirname1 data -customgamedirname2 "" -customgamescreenshotname xonotic -customgameuserdirname xonotic "$@"
427                 if [ -n "$USE_GDB" ]; then
428                         set -- gdb --args "$@"
429                 fi
430                 "$@"
431                 ;;
432         each|foreach)
433                 for d in $repos; do
434                         enter "$d0/$d" verbose
435                         verbose "$@"
436                         cd "$d0"
437                 done
438                 ;;
439         save-patches)
440                 outfile=$1
441                 patchdir=`mktemp -d -t save-patches.XXXXXX`
442                 for d in $repos; do
443                         enter "$d0/$d" verbose
444                         git branch -v -v | cut -c 3- | {
445                                 i=0
446                                 while read -r BRANCH REV UPSTREAM TEXT; do
447                                         case "$UPSTREAM" in
448                                                 \[*)
449                                                         UPSTREAM=${UPSTREAM#\[}
450                                                         UPSTREAM=${UPSTREAM%\]}
451                                                         UPSTREAM=${UPSTREAM%:*}
452                                                         TRACK=true
453                                                         ;;
454                                                 *)
455                                                         UPSTREAM=origin/"`repobranch "$d"`"
456                                                         TRACK=false
457                                                         ;;
458                                         esac
459                                         if [ x"$REV" = x"->" ]; then
460                                                 continue
461                                         fi
462                                         if git format-patch -o "$patchdir/$i" "$UPSTREAM".."$BRANCH"; then
463                                                 echo "$d" > "$patchdir/$i/info.txt"
464                                                 echo "$BRANCH" >> "$patchdir/$i/info.txt"
465                                                 echo "$UPSTREAM" >> "$patchdir/$i/info.txt"
466                                                 echo "$TRACK" >> "$patchdir/$i/info.txt"
467                                                 i=$(($i+1))
468                                         else
469                                                 rm -rf "$patchdir/$i"
470                                         fi
471                                 done
472                         }
473                 done
474                 ( cd "$patchdir" && tar cvzf - . ) > "$outfile"
475                 rm -rf "$patchdir"
476                 ;;
477         restore-patches)
478                 infile=$1
479                 patchdir=`mktemp -d -t restore-patches.XXXXXX`
480                 ( cd "$patchdir" && tar xvzf - ) < "$infile"
481                 # detach the head
482                 for P in "$patchdir"/*/info.txt; do
483                         D=${P%/info.txt}
484                         exec 3<"$P"
485                         read -r d <&3
486                         read -r BRANCH <&3
487                         read -r UPSTREAM <&3
488                         read -r TRACK <&3
489                         verbose git checkout HEAD^0
490                         verbose git branch -D "$BRANCH"
491                         if [ x"$TRACK" = x"true" ]; then
492                                 verbose git checkout --track -b "$BRANCH" "$UPSTREAM"
493                         else
494                                 verbose git branch -b "$BRANCH" "$UPSTREAM"
495                         fi
496                         verbose git am "$D"
497                 done
498                 rm -rf "$patchdir"
499                 ;;
500         admin-merge)
501                 for d in $repos; do
502                         enter "$d0/$d" verbose
503                         git rev-parse "$1/$2" || continue
504                         # 1. review
505                         {
506                                 git log HEAD.."$1/$2"
507                                 git diff HEAD..."$1/$2"
508                         } | less
509                         a=
510                         while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
511                                 echo "Merge \"$1/$2\" into `git symbolic-ref HEAD` of $d?"
512                                 read -r a
513                         done
514                         if [ x"$a" = x"y" ]; then
515                                 git merge "$1/$2"
516                                 cd "$d0"
517                                 a=
518                                 if ! "$SELF" compile; then
519                                         a=n
520                                 fi
521                                 cd "$d0/$d"
522                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
523                                         echo "Still merge \"$1/$2\" into `git symbolic-ref HEAD` of $d? Maybe you want to test first."
524                                         read -r a
525                                 done
526                                 if [ x"$a" = x"y" ]; then
527                                         git push origin HEAD
528                                         git push "$1" :"$2"
529                                 else
530                                         git reset --hard HEAD@{1}
531                                 fi
532                         fi
533                 done
534                 ;;
535         *)
536                 echo "Usage:"
537                 echo "  $SELF pull"
538                 echo "  $SELF merge"
539                 echo "  $SELF push [-s]"
540                 echo "  $SELF branches"
541                 echo "  $SELF branch [<remote>] <branchname>"
542                 echo "  $SELF branch <remote> <branchname> <srcbranchname>"
543                 echo "  $SELF checkout [<remote>] <branchname>"
544                 echo "  $SELF compile"
545                 echo "  $SELF run <client> <options>"
546                 echo "  $SELF each <command>"
547                 ;;
548 esac