.gitattributes file
[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                                 exec ../all.xonotic.sh "$@"
27                                 ;;
28                 esac
29                 ;;
30 esac
31
32 msg()
33 {
34         echo "\e[1m$*\e[m"
35 }
36
37 checksum()
38 {
39         if [ -x /usr/bin/md5sum ]; then
40                 /usr/bin/md5sum "$@"
41         elif [ -x /bin/md5sum ]; then
42                 /bin/md5sum "$@"
43         elif [ -x /usr/bin/cksum ]; then
44                 /usr/bin/cksum "$@"
45         else
46                 echo "NOCHECKSUM"
47         fi
48 }
49
50 self=`checksum "$SELF"`
51 checkself()
52 {
53         self_new=`checksum "$SELF"`
54         if [ x"$self" != x"$self_new" ]; then
55                 msg "./all has changed."
56                 if [ -z "$XONOTIC_FORBID_RERUN_ALL" ]; then
57                         msg "Rerunning the requested operation to make sure."
58                         export XONOTIC_FORBID_RERUN_ALL=1
59                         exec "$SELF" "$@"
60                 else
61                         msg "Please try $SELF update, and then retry your requested operation."
62                         exit 1
63                 fi
64         fi
65         return 0
66 }
67
68 verbose()
69 {
70         msg "+ $*"
71         "$@"
72 }
73
74 visible_repo_name()
75 {
76         case "$1" in
77                 .)
78                         echo "the root directory"
79                         ;;
80                 *)
81                         echo "\"$1\""
82                         ;;
83         esac
84 }
85
86 check_mergeconflict()
87 {
88         if git ls-files -u | grep ' 1   '; then
89                 echo
90                 echo "MERGE CONFLICT."
91                 echo "change into the \"$1\" project directory, and then:"
92                 echo "- edit the files mentioned above with your favorite editor,"
93                 echo "  and fix the conflicts (marked with <<<<<<< blocks)"
94                 echo "- for binary files, you can select the files using"
95                 echo "  git checkout --ours or git checkout --theirs"
96                 echo "- when done with a file, 'git add' the file"
97                 echo "- when done, 'git commit'"
98                 echo
99                 exit 1
100         fi
101 }
102
103 enter()
104 {
105         $2 cd "$1"
106         check_mergeconflict "$1"
107 }
108
109 repos_urls="
110         .
111         data/xonotic-data.pk3dir
112         data/xonotic-maps.pk3dir
113         data/xonotic-music.pk3dir
114         data/xonotic-nexcompat.pk3dir
115         darkplaces
116         fteqcc@git://github.com/Blub/qclib.git
117         div0-gittools@git://git.icculus.org/divverent/div0-gittools.git
118         netradiant
119 "
120
121 repos=`for X in $repos_urls; do echo "${X%%@*}"; done`
122
123 if [ "$#" = 0 ]; then
124         set -- help
125 fi
126 cmd=$1
127 shift
128
129 case "$cmd" in
130         update|pull)
131                 base=`git config remote.origin.url`
132                 base=${base%xonotic.git}
133                 for dcomplete in $repos_urls; do
134                         case "$dcomplete" in
135                                 *@*)
136                                         d=${dcomplete%%@*}
137                                         url=${dcomplete#*@}
138                                         switch=false
139                                         ;;
140                                 *)
141                                         d=${dcomplete%%@*}
142                                         url=$base${d##*/}.git
143                                         switch=true
144                                         ;;
145                         esac
146                         if [ -d "$d0/$d" ]; then
147                                 enter "$d0/$d" verbose
148                                 case "$d" in
149                                         .)
150                                                 ;;
151                                         *)
152                                                 if $switch; then
153                                                         verbose git config remote.origin.url "$url"
154                                                 fi
155                                                 ;;
156                                 esac
157                                 verbose git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
158                                         # TODO remove this line later
159
160                                 verbose git config core.autocrlf input
161                                 verbose git config core.safecrlf true
162
163                                 r=`git symbolic-ref HEAD`
164                                 r=${r#refs/heads/}
165                                 if git config branch.$r.remote >/dev/null 2>&1; then
166                                         if ! verbose git pull; then
167                                                 check_mergeconflict "$d"
168                                                 exit 1 # FATAL
169                                         fi
170                                 fi
171
172                                 cd "$d00"
173                                 checkself "$cmd" "$@"
174                                 cd "$d0/$d"
175                                 verbose git remote prune origin
176                                 cd "$d0"
177                         else
178                                 verbose git clone "$url" "$d0/$d"
179                         fi
180                 done
181                 ;;
182         checkout|switch)
183                 remote=$1
184                 branch=$2
185                 if [ -z "$branch" ]; then
186                         branch=$remote
187                         remote=origin
188                 fi
189                 exists=false
190                 for d in $repos; do
191                         enter "$d0/$d" verbose
192                         if git rev-parse "refs/heads/$branch" >/dev/null 2>&1; then
193                                 exists=true
194                                 verbose git checkout "$branch"
195                         elif git rev-parse "refs/remotes/$remote/$branch" >/dev/null 2>&1; then
196                                 exists=true
197                                 verbose git checkout --track -b "$branch" "$remote/$branch"
198                         else
199                                 verbose git checkout master
200                         fi
201                         cd "$d00"
202                         checkself "$cmd" "$@"
203                         cd "$d0"
204                 done
205                 if ! $exists; then
206                         echo "The requested branch was not found in any repository."
207                 fi
208                 exec "$SELF" branch
209                 ;;
210         branch)
211                 remote=$1
212                 branch=$2
213                 srcbranch=$3
214                 if [ -z "$branch" ]; then
215                         branch=$remote
216                         remote=origin
217                 fi
218                 if [ -z "$srcbranch" ]; then
219                         srcbranch=master
220                 fi
221                 if [ -z "$branch" ]; then
222                         for d in $repos; do
223                                 enter "$d0/$d"
224                                 r=`git symbolic-ref HEAD`
225                                 r=${r#refs/heads/}
226                                 echo "$d is at $r"
227                                 cd "$d0"
228                         done
229                 else
230                         for d in $repos; do
231                                 dv=`visible_repo_name "$d"`
232                                 enter "$d0/$d" verbose
233                                 a=
234                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
235                                         echo "Branch in $dv?"
236                                         read -r a
237                                 done
238                                 if [ x"$a" = x"y" ]; then
239                                         verbose git push "$remote" "$srcbranch":"$branch"
240                                         verbose git checkout --track -b "$branch" "$remote/$branch"
241                                 fi
242                                 cd "$d0"
243                         done
244                         "$SELF" branch
245                 fi
246                 ;;
247         branches)
248                 for d in $repos; do
249                         enter "$d0/$d"
250                         echo "In $d:"
251                         git branch -a -v -v | cut -c 3- | while read -r BRANCH REV UPSTREAM TEXT; do
252                                 case "$UPSTREAM" in
253                                         \[*)
254                                                 UPSTREAM=${UPSTREAM#\[}
255                                                 UPSTREAM=${UPSTREAM%\]}
256                                                 UPSTREAM=${UPSTREAM%:*}
257                                                 ;;
258                                         *)
259                                                 TEXT="$UPSTREAM $TEXT"
260                                                 UPSTREAM=
261                                                 ;;
262                                 esac
263                                 if [ x"$REV" = x"->" ]; then
264                                         continue
265                                 fi
266                                 BRANCH=${BRANCH#remotes/}
267                                 echo -n "  $BRANCH"
268                                 if [ -n "$UPSTREAM" ]; then
269                                         echo -n " (tracking $UPSTREAM)"
270                                 fi
271                                 #echo " $TEXT"
272                                 echo
273                         done
274                 done
275                 ;;
276         merge)
277                 for d in $repos; do
278                         dv=`visible_repo_name "$d"`
279                         enter "$d0/$d" verbose
280                         r=`git symbolic-ref HEAD`
281                         r=${r#refs/heads/}
282                         if git log HEAD..origin/master | grep .; then
283                                 # we have uncommitted changes
284                                 a=
285                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
286                                         echo "Could merge from \"master\" into \"$r\" in $dv. Do it?"
287                                         read -r a
288                                 done
289                                 if [ x"$a" = x"y" ]; then
290                                         if ! verbose git merge origin/master; then
291                                                 check_mergeconflict "$d"
292                                                 exit 1 # this should ALWAYS be fatal
293                                         fi
294                                 fi
295                         fi
296                         cd "$d0"
297                 done
298                 ;;
299         push|commit)
300                 submit=$1
301                 for d in $repos; do
302                         dv=`visible_repo_name "$d"`
303                         enter "$d0/$d" verbose
304                         r=`git symbolic-ref HEAD`
305                         r=${r#refs/heads/}
306                         if git diff HEAD | grep .; then
307                                 # we have uncommitted changes
308                                 a=
309                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
310                                         echo "Uncommitted changes in \"$r\" in $dv. Commit?"
311                                         read -r a
312                                 done
313                                 if [ x"$a" = x"y" ]; then
314                                         verbose git commit -a
315                                 fi
316                         fi
317                         rem=`git config "branch.$r.remote" || echo origin`
318                         if git log "$rem/$r".."$r" | grep .; then
319                                 a=
320                                 while [ x"$a" != x"y" -a x"$a" != x"n" ]; do
321                                         echo "Push \"$r\" in $dv?"
322                                         read -r a
323                                 done
324                                 if [ x"$a" = x"y" ]; then
325                                         verbose git push "$rem" HEAD
326                                 fi
327                         fi
328                         if [ x"$submit" = x"-s" ]; then
329                                 case "$r" in
330                                         */*)
331                                                 verbose git push "$rem" HEAD:"${r%%/*}/finished/${r#*/}"
332                                                 ;;
333                                 esac
334                         fi
335                         cd "$d0"
336                 done
337                 ;;
338         compile)
339                 if [ -z "$MAKEFLAGS" ]; then
340                         if [ -f /proc/cpuinfo ]; then
341                                 ncpus=$((`grep -c '^processor   :' /proc/cpuinfo`+0))
342                                 if [ $ncpus -gt 1 ]; then
343                                         MAKEFLAGS=-j$ncpus
344                                 fi
345                         fi
346                 fi
347                 enter "$d0/fteqcc" verbose
348                 verbose make $MAKEFLAGS
349                 enter "$d0/data/xonotic-data.pk3dir" verbose
350                 verbose make FTEQCC="$d0/fteqcc/fteqcc.bin" $MAKEFLAGS
351                 enter "$d0/darkplaces" verbose
352                 verbose make $MAKEFLAGS sv-debug
353                 verbose make $MAKEFLAGS cl-debug
354                 verbose make $MAKEFLAGS sdl-debug
355                 ;;
356         run)
357                 client=-sdl
358                 case "$1" in
359                         sdl|glx|agl|dedicated)
360                                 client=-$1
361                                 shift
362                                 ;;
363                         wgl)
364                                 client=
365                                 shift
366                                 ;;
367                 esac
368                 if ! [ -x "darkplaces/darkplaces$client" ]; then
369                         if [ -x "darkplaces/darkplaces$client.exe" ]; then
370                                 client=$client.exe
371                         else
372                                 echo "Client darkplaces/darkplaces$client not found, aborting"
373                                 exit 1
374                         fi
375                 fi
376                 #verbose "darkplaces/darkplaces$client" -xonotic "$@"
377                 verbose "darkplaces/darkplaces$client" -nexuiz -customgamename Xonotic -customgamedirname1 data -customgamedirname2 "" -customgamescreenshotname xonotic -customgameuserdirname xonotic "$@"
378                 ;;
379         each|foreach)
380                 for d in $repos; do
381                         enter "$d0/$d" verbose
382                         verbose "$@"
383                         cd "$d0"
384                 done
385                 ;;
386         save-patches)
387                 outfile=$1
388                 patchdir=`mktemp -d -t save-patches.XXXXXX`
389                 for d in $repos; do
390                         enter "$d0/$d" verbose
391                         git branch -v -v | cut -c 3- | {
392                                 i=0
393                                 while read -r BRANCH REV UPSTREAM TEXT; do
394                                         case "$UPSTREAM" in
395                                                 \[*)
396                                                         UPSTREAM=${UPSTREAM#\[}
397                                                         UPSTREAM=${UPSTREAM%\]}
398                                                         UPSTREAM=${UPSTREAM%:*}
399                                                         TRACK=true
400                                                         ;;
401                                                 *)
402                                                         UPSTREAM=origin/master
403                                                         TRACK=false
404                                                         ;;
405                                         esac
406                                         if [ x"$REV" = x"->" ]; then
407                                                 continue
408                                         fi
409                                         if git format-patch -o "$patchdir/$i" "$UPSTREAM".."$BRANCH"; then
410                                                 echo "$d" > "$patchdir/$i/info.txt"
411                                                 echo "$BRANCH" >> "$patchdir/$i/info.txt"
412                                                 echo "$UPSTREAM" >> "$patchdir/$i/info.txt"
413                                                 echo "$TRACK" >> "$patchdir/$i/info.txt"
414                                                 i=$(($i+1))
415                                         else
416                                                 rm -rf "$patchdir/$i"
417                                         fi
418                                 done
419                         }
420                 done
421                 ( cd "$patchdir" && tar cvzf - . ) > "$outfile"
422                 rm -rf "$patchdir"
423                 ;;
424         restore-patches)
425                 infile=$1
426                 patchdir=`mktemp -d -t restore-patches.XXXXXX`
427                 ( cd "$patchdir" && tar xvzf - ) < "$infile"
428                 # detach the head
429                 for P in "$patchdir"/*/info.txt; do
430                         D=${P%/info.txt}
431                         exec 3<"$P"
432                         read -r d <&3
433                         read -r BRANCH <&3
434                         read -r UPSTREAM <&3
435                         read -r TRACK <&3
436                         verbose git checkout HEAD^0
437                         verbose git branch -D "$BRANCH"
438                         if [ x"$TRACK" = x"true" ]; then
439                                 verbose git checkout --track -b "$BRANCH" "$UPSTREAM"
440                         else
441                                 verbose git branch -b "$BRANCH" "$UPSTREAM"
442                         fi
443                         verbose git am "$D"
444                 done
445                 rm -rf "$patchdir"
446                 ;;
447         *)
448                 echo "Usage:"
449                 echo "  $SELF pull"
450                 echo "  $SELF merge"
451                 echo "  $SELF push [-s]"
452                 echo "  $SELF branches"
453                 echo "  $SELF branch [<remote>] <branchname>"
454                 echo "  $SELF branch <remote> <branchname> <srcbranchname>"
455                 echo "  $SELF checkout [<remote>] <branchname>"
456                 echo "  $SELF compile"
457                 echo "  $SELF run <client> <options>"
458                 echo "  $SELF each <command>"
459                 ;;
460 esac