Merge branch 'master' of ssh://git.xonotic.org/xonotic
[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         .
112         data/xonotic-data.pk3dir
113         data/xonotic-maps.pk3dir
114         data/xonotic-music.pk3dir
115         data/xonotic-nexcompat.pk3dir
116         darkplaces
117         fteqcc@git://github.com/Blub/qclib.git
118         div0-gittools@git://git.icculus.org/divverent/div0-gittools.git
119         netradiant
120 "
121
122 repos=`for X in $repos_urls; do echo "${X%%@*}"; done`
123
124 if [ "$#" = 0 ]; then
125         set -- help
126 fi
127 cmd=$1
128 shift
129
130 case "$cmd" in
131         update|pull)
132                 base=`git config remote.origin.url`
133                 base=${base%xonotic.git}
134                 for dcomplete in $repos_urls; do
135                         case "$dcomplete" in
136                                 *@*)
137                                         d=${dcomplete%%@*}
138                                         url=${dcomplete#*@}
139                                         switch=false
140                                         ;;
141                                 *)
142                                         d=${dcomplete%%@*}
143                                         url=$base${d##*/}.git
144                                         switch=true
145                                         ;;
146                         esac
147                         if [ -d "$d0/$d" ]; then
148                                 enter "$d0/$d" verbose
149                                 case "$d" in
150                                         .)
151                                                 ;;
152                                         *)
153                                                 if $switch; then
154                                                         verbose git config remote.origin.url "$url"
155                                                 fi
156                                                 ;;
157                                 esac
158                                 verbose git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
159                                         # TODO remove this line later
160
161                                 verbose git config core.autocrlf false
162                                 verbose git config core.safecrlf false # we don't NEED that...
163
164                                 r=`git symbolic-ref HEAD`
165                                 r=${r#refs/heads/}
166                                 if git config branch.$r.remote >/dev/null 2>&1; then
167                                         if ! verbose git pull; then
168                                                 check_mergeconflict "$d"
169                                                 echo "Pulling failed. Press ENTER to continue, or Ctrl-C to abort."
170                                                 read -r DUMMY
171                                         fi
172                                 fi
173
174                                 cd "$d00"
175                                 checkself "$cmd" "$@"
176                                 cd "$d0/$d"
177                                 verbose git remote prune origin
178                                 cd "$d0"
179                         else
180                                 verbose git clone "$url" "$d0/$d"
181                         fi
182                 done
183                 ;;
184         checkout|switch)
185                 remote=$1
186                 branch=$2
187                 if [ -z "$branch" ]; then
188                         branch=$remote
189                         remote=origin
190                 fi
191                 exists=false
192                 for d in $repos; do
193                         enter "$d0/$d" verbose
194                         if git rev-parse "refs/heads/$branch" >/dev/null 2>&1; then
195                                 exists=true
196                                 verbose git checkout "$branch"
197                         elif git rev-parse "refs/remotes/$remote/$branch" >/dev/null 2>&1; then
198                                 exists=true
199                                 verbose git checkout --track -b "$branch" "$remote/$branch"
200                         else
201                                 verbose git checkout master
202                         fi
203                         cd "$d00"
204                         checkself "$cmd" "$@"
205                         cd "$d0"
206                 done
207                 if ! $exists; then
208                         echo "The requested branch was not found in any repository."
209                 fi
210                 exec "$SELF" branch
211                 ;;
212         branch)
213                 remote=$1
214                 branch=$2
215                 srcbranch=$3
216                 if [ -z "$branch" ]; then
217                         branch=$remote
218                         remote=origin
219                 fi
220                 if [ -z "$srcbranch" ]; then
221                         srcbranch=master
222                 fi
223                 if [ -z "$branch" ]; then
224                         for d in $repos; do
225                                 enter "$d0/$d"
226                                 r=`git symbolic-ref HEAD`
227                                 r=${r#refs/heads/}
228                                 echo "$d is at $r"
229                                 cd "$d0"
230                         done
231                 else
232                         for d in $repos; do
233                                 dv=`visible_repo_name "$d"`
234                                 enter "$d0/$d" verbose
235                                 a=
236                                 if git rev-parse "refs/heads/$branch" >/dev/null 2>&1; then
237                                         echo "Already having this branch in $dv."
238                                 else
239                                         while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
240                                                 echo "Branch in $dv?"
241                                                 read -r a
242                                         done
243                                         if [ x"$a" = x"y" ]; then
244                                                 verbose git push "$remote" "$srcbranch":"$branch"
245                                                 verbose git checkout --track -b "$branch" "$remote/$branch"
246                                         fi
247                                 fi
248                                 cd "$d0"
249                         done
250                         "$SELF" branch
251                 fi
252                 ;;
253         branches)
254                 for d in $repos; do
255                         enter "$d0/$d"
256                         echo "In $d:"
257                         git branch -a -v -v | cut -c 3- | while read -r BRANCH REV UPSTREAM TEXT; do
258                                 case "$UPSTREAM" in
259                                         \[*)
260                                                 UPSTREAM=${UPSTREAM#\[}
261                                                 UPSTREAM=${UPSTREAM%\]}
262                                                 UPSTREAM=${UPSTREAM%:*}
263                                                 ;;
264                                         *)
265                                                 TEXT="$UPSTREAM $TEXT"
266                                                 UPSTREAM=
267                                                 ;;
268                                 esac
269                                 if [ x"$REV" = x"->" ]; then
270                                         continue
271                                 fi
272                                 BRANCH=${BRANCH#remotes/}
273                                 echo -n "  $BRANCH"
274                                 if [ -n "$UPSTREAM" ]; then
275                                         echo -n " (tracking $UPSTREAM)"
276                                 fi
277                                 #echo " $TEXT"
278                                 echo
279                         done
280                 done
281                 ;;
282         merge)
283                 for d in $repos; do
284                         dv=`visible_repo_name "$d"`
285                         enter "$d0/$d" verbose
286                         r=`git symbolic-ref HEAD`
287                         r=${r#refs/heads/}
288                         if git log HEAD..origin/master | grep .; then
289                                 # we have uncommitted changes
290                                 a=
291                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
292                                         echo "Could merge from \"master\" into \"$r\" in $dv. Do it?"
293                                         read -r a
294                                 done
295                                 if [ x"$a" = x"y" ]; then
296                                         if ! verbose git merge origin/master; then
297                                                 check_mergeconflict "$d"
298                                                 exit 1 # this should ALWAYS be fatal
299                                         fi
300                                 fi
301                         fi
302                         cd "$d0"
303                 done
304                 ;;
305         push|commit)
306                 submit=$1
307                 for d in $repos; do
308                         dv=`visible_repo_name "$d"`
309                         enter "$d0/$d" verbose
310                         r=`git symbolic-ref HEAD`
311                         r=${r#refs/heads/}
312                         if git diff HEAD | grep .; then
313                                 # we have uncommitted changes
314                                 a=
315                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
316                                         echo "Uncommitted changes in \"$r\" in $dv. Commit?"
317                                         read -r a
318                                 done
319                                 if [ x"$a" = x"y" ]; then
320                                         verbose git commit -a
321                                 fi
322                         fi
323                         rem=`git config "branch.$r.remote" || echo origin`
324                         if git log "$rem/$r".."$r" | grep .; then
325                                 a=
326                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
327                                         echo "Push \"$r\" in $dv?"
328                                         read -r a
329                                 done
330                                 if [ x"$a" = x"y" ]; then
331                                         verbose git push "$rem" HEAD
332                                 fi
333                         fi
334                         if [ x"$submit" = x"-s" ]; then
335                                 case "$r" in
336                                         */*)
337                                                 verbose git push "$rem" HEAD:"${r%%/*}/finished/${r#*/}"
338                                                 ;;
339                                 esac
340                         fi
341                         cd "$d0"
342                 done
343                 ;;
344         compile)
345                 if [ -z "$MAKEFLAGS" ]; then
346                         if [ -f /proc/cpuinfo ]; then
347                                 ncpus=$((`grep -c '^processor   :' /proc/cpuinfo`+0))
348                                 if [ $ncpus -gt 1 ]; then
349                                         MAKEFLAGS=-j$ncpus
350                                 fi
351                         fi
352                 fi
353                 enter "$d0/fteqcc" verbose
354                 verbose make $MAKEFLAGS
355                 enter "$d0/data/xonotic-data.pk3dir" verbose
356                 verbose make FTEQCC="$d0/fteqcc/fteqcc.bin" $MAKEFLAGS
357                 enter "$d0/darkplaces" verbose
358                 verbose make $MAKEFLAGS sv-debug
359                 verbose make $MAKEFLAGS cl-debug
360                 if ! [ -n "$WE_HATE_OUR_USERS" ]; then
361                         verbose make $MAKEFLAGS sdl-debug
362                 fi
363                 ;;
364         run)
365                 if [ -n "$WE_HATE_OUR_USERS" ]; then
366                         client=
367                 else
368                         client=-sdl
369                 fi
370                 case "$1" in
371                         sdl|glx|agl|dedicated)
372                                 client=-$1
373                                 shift
374                                 ;;
375                         wgl)
376                                 client=
377                                 shift
378                                 ;;
379                 esac
380                 if ! [ -x "darkplaces/darkplaces$client" ]; then
381                         if [ -x "darkplaces/darkplaces$client.exe" ]; then
382                                 client=$client.exe
383                         else
384                                 echo "Client darkplaces/darkplaces$client not found, aborting"
385                                 exit 1
386                         fi
387                 fi
388                 #verbose "darkplaces/darkplaces$client" -xonotic "$@"
389                 verbose "darkplaces/darkplaces$client" -nexuiz -customgamename Xonotic -customgamedirname1 data -customgamedirname2 "" -customgamescreenshotname xonotic -customgameuserdirname xonotic "$@"
390                 ;;
391         each|foreach)
392                 for d in $repos; do
393                         enter "$d0/$d" verbose
394                         verbose "$@"
395                         cd "$d0"
396                 done
397                 ;;
398         save-patches)
399                 outfile=$1
400                 patchdir=`mktemp -d -t save-patches.XXXXXX`
401                 for d in $repos; do
402                         enter "$d0/$d" verbose
403                         git branch -v -v | cut -c 3- | {
404                                 i=0
405                                 while read -r BRANCH REV UPSTREAM TEXT; do
406                                         case "$UPSTREAM" in
407                                                 \[*)
408                                                         UPSTREAM=${UPSTREAM#\[}
409                                                         UPSTREAM=${UPSTREAM%\]}
410                                                         UPSTREAM=${UPSTREAM%:*}
411                                                         TRACK=true
412                                                         ;;
413                                                 *)
414                                                         UPSTREAM=origin/master
415                                                         TRACK=false
416                                                         ;;
417                                         esac
418                                         if [ x"$REV" = x"->" ]; then
419                                                 continue
420                                         fi
421                                         if git format-patch -o "$patchdir/$i" "$UPSTREAM".."$BRANCH"; then
422                                                 echo "$d" > "$patchdir/$i/info.txt"
423                                                 echo "$BRANCH" >> "$patchdir/$i/info.txt"
424                                                 echo "$UPSTREAM" >> "$patchdir/$i/info.txt"
425                                                 echo "$TRACK" >> "$patchdir/$i/info.txt"
426                                                 i=$(($i+1))
427                                         else
428                                                 rm -rf "$patchdir/$i"
429                                         fi
430                                 done
431                         }
432                 done
433                 ( cd "$patchdir" && tar cvzf - . ) > "$outfile"
434                 rm -rf "$patchdir"
435                 ;;
436         restore-patches)
437                 infile=$1
438                 patchdir=`mktemp -d -t restore-patches.XXXXXX`
439                 ( cd "$patchdir" && tar xvzf - ) < "$infile"
440                 # detach the head
441                 for P in "$patchdir"/*/info.txt; do
442                         D=${P%/info.txt}
443                         exec 3<"$P"
444                         read -r d <&3
445                         read -r BRANCH <&3
446                         read -r UPSTREAM <&3
447                         read -r TRACK <&3
448                         verbose git checkout HEAD^0
449                         verbose git branch -D "$BRANCH"
450                         if [ x"$TRACK" = x"true" ]; then
451                                 verbose git checkout --track -b "$BRANCH" "$UPSTREAM"
452                         else
453                                 verbose git branch -b "$BRANCH" "$UPSTREAM"
454                         fi
455                         verbose git am "$D"
456                 done
457                 rm -rf "$patchdir"
458                 ;;
459         admin-merge)
460                 for d in $repos; do
461                         enter "$d0/$d" verbose
462                         git rev-parse "$1/$2" || continue
463                         # 1. review
464                         {
465                                 git log HEAD.."$1/$2"
466                                 git diff HEAD..."$1/$2"
467                         } | less
468                         a=
469                         while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
470                                 echo "Merge \"$1/$2\" into `git symbolic-ref HEAD` of $d?"
471                                 read -r a
472                         done
473                         if [ x"$a" = x"y" ]; then
474                                 git merge "$1/$2"
475                                 cd "$d0"
476                                 a=
477                                 if ! "$SELF" compile; then
478                                         a=n
479                                 fi
480                                 cd "$d0/$d"
481                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
482                                         echo "Still merge \"$1/$2\" into `git symbolic-ref HEAD` of $d? Maybe you want to test first."
483                                         read -r a
484                                 done
485                                 if [ x"$a" = x"y" ]; then
486                                         git push origin HEAD
487                                         git push "$1" :"$2"
488                                 else
489                                         git reset --hard HEAD@{1}
490                                 fi
491                         fi
492                 done
493                 ;;
494         *)
495                 echo "Usage:"
496                 echo "  $SELF pull"
497                 echo "  $SELF merge"
498                 echo "  $SELF push [-s]"
499                 echo "  $SELF branches"
500                 echo "  $SELF branch [<remote>] <branchname>"
501                 echo "  $SELF branch <remote> <branchname> <srcbranchname>"
502                 echo "  $SELF checkout [<remote>] <branchname>"
503                 echo "  $SELF compile"
504                 echo "  $SELF run <client> <options>"
505                 echo "  $SELF each <command>"
506                 ;;
507 esac