1- #! /usr/bin/env zsh
1+ #! /usr/bin/env bash
22
33# Run this script to install or update your dmd toolchain from
44# github.
55#
6- # Make sure zsh is installed. You may need to change the shebang.
7- #
86# First run, create a working directory, e.g. /path/to/d/. Then run
97# this script from that directory (the location of the script itself
108# doesn't matter). It will create the following subdirectories:
1917# update.
2018#
2119
22- setopt err_exit
20+ set -ueo pipefail
2321
24- local projects
25- typeset -a projects
26- projects=(dmd druntime phobos dlang.org tools installer)
22+ declare -a projects
23+ projects=(dmd druntime phobos dlang.org tools installer dub)
2724# Working directory
28- local wd=$( pwd)
25+ wd=$( pwd)
26+ # github username
27+ githubUser=" dlang"
2928# Configuration
30- local makecmd=make
31- local parallel=8
32- local model=64
29+ makecmd=" make"
30+ parallel=8
31+ model=64
32+ build=" release"
33+ githubUri=" https://github.com/"
3334# List of projects to install vs. update. Their disjoint union is
3435# $projects.
35- local toInstall toUpdate
36- typeset -a toInstall toUpdate
36+ declare -a toInstall toUpdate
37+ toInstall=()
38+ toUpdate=()
3739# Mess to go here
38- local tempdir=$( mktemp -d /tmp/dmd-update.XXX)
40+ tempdir=$( mktemp -d /tmp/dmd-update.XXX)
41+
42+ function cleanup() {
43+ rm -rf " $tempdir " ;
44+ }
45+ trap cleanup EXIT
46+
47+ function help() {
48+ echo " ./setup.sh
49+ Clones and builds dmd, druntime, phobos, dlang.org, tools, installer and dub.
50+
51+ Additional usage
52+
53+ install replace current dmd binary with the freshly dmd
54+
55+ Options
56+
57+ --user=USER set a custom GitHub user name (requires the repos to be forked)
58+ --tag=TAG select a specific tag to clone" >&2
59+ }
3960
4061#
4162# Take care of the command line arguments
4263#
4364function handleCmdLine() {
44- local arg
45- for arg in $* ; do
46- case $arg in
47- (--tag=* )
48- tag=" ` echo $arg | sed ' s/[-a-zA-Z0-9]*=//' ` "
65+ for arg in " $@ " ; do
66+ case " $arg " in
67+ --tag=* )
68+ tag=" ${arg// [-a-zA-Z0-9]* =// } "
4969 ;;
50- (install)
70+ --user=* )
71+ githubUser=" ${arg// [-a-zA-Z0-9]* =// } "
72+ ;;
73+ install)
5174 install=" yes"
5275 ;;
53- ( * )
76+ * )
5477 echo " Error: $arg not recognized." >&2
78+ echo >&2
79+ help
5580 exit 1
5681 ;;
5782 esac
5883 done
5984
60- if [[ ! -z $ tag ]] ; then
85+ if [ ! -z " ${ tag+x} " ] ; then
6186 wd+=" /$tag "
6287 mkdir -p " $wd "
6388 fi
@@ -68,33 +93,32 @@ function handleCmdLine() {
6893#
6994function confirmChoices() {
7095 function joinWithWorkingDir() {
71- for i in $* ; do
96+ for i in " $@ " ; do
7297 echo " $wd /$i "
7398 done
7499 }
75100
76- for project in $ projects; do
77- if [ -e " $wd /$project " ]; then
78- toUpdate=( $toUpdate " $project " )
101+ for project in " ${ projects[@]} " ; do
102+ if [ -d " $wd /$project " ] ; then
103+ toUpdate+=( " $project " )
79104 else
80- toInstall=( $toInstall " $project " )
105+ toInstall+=( " $project " )
81106 fi
82107 done
83- if [[ ! -z $toInstall ]]; then
108+ if [[ ${ # toInstall[@]} -gt 0 ]]; then
84109 echo " *** The following projects will be INSTALLED:"
85- joinWithWorkingDir ${toInstall}
86- echo " *** Note: this script assumes you have a github account set up."
110+ joinWithWorkingDir " ${toInstall[@]} "
87111 fi
88- if [[ ! -z $toUpdate ]]; then
112+ if [[ ${ # toUpdate[@]} -gt 0 ]]; then
89113 echo " *** The following projects will be UPDATED:"
90- joinWithWorkingDir ${toUpdate}
114+ joinWithWorkingDir " ${toUpdate[@]} "
91115 fi
92116
93- echo " Is this what you want?"
117+ echo " Is this what you want? [y|n] "
94118 local yn
95119 while true ; do
96- read yn
97- case $yn in
120+ read -r yn
121+ case " $yn " in
98122 [Yy]* ) break ;;
99123 [Nn]* ) exit ;;
100124 * ) echo " Please answer y or n." ;;
@@ -108,26 +132,27 @@ function confirmChoices() {
108132
109133function installAnew() {
110134 local projects
111- projects=($* )
112- for project in $ projects; do
135+ projects=(" $@ " )
136+ for project in " ${ projects[@]} " ; do
113137 (
114- cd $wd &&
115- git clone --quiet git://github.com/dlang/$project .git &&
116- touch $tempdir /$project
138+ git clone " ${githubUri}${githubUser} /$project .git" " $wd /$project "
139+ if [ " $githubUser " != " dlang" ] ; then
140+ git -C " $wd /$project " remote add upstream " ${githubUri} dlang/$project .git"
141+ fi
142+ touch " $tempdir /$project "
117143 ) &
118144 done
119145 wait
120146
121- for project in $ projects; do
122- if [ ! -f $tempdir /$project ]; then
147+ for project in " ${ projects[@]} " ; do
148+ if [ ! -f " $tempdir /$project " ]; then
123149 echo " Getting $project failed." >&2
124- rm -rf $tempdir
125150 exit 1
126151 fi
127- if [[ ! -z $ tag &&
128- ( $project = dmd || $project = druntime || $project = phobos ||
129- $ project = dlang.org) ]] ; then
130- ( cd $wd / $project && git checkout v $tag )
152+ if [ ! -z " ${ tag+x} " ] ; then
153+ if [ " $project " == " dmd " ] -o [ " $project " == " druntime " ] -o [ " $project " == " phobos " ] -o [ " $project " == " dlang.org " ] ; then
154+ git -C " $wd / $ project" checkout " v $tag "
155+ fi
131156 fi
132157 done
133158}
@@ -141,72 +166,60 @@ function update() {
141166
142167 function update_project() {
143168 local project=$1
144- local gitproject=" git://github.com/dlang/$project .git"
145- if ! ( cd " $wd /$project " && \
146- git checkout master && \
147- git pull --ff-only $gitproject master && \
148- git pull $gitproject master --tags && \
149- git fetch $gitproject && \
150- git fetch --tags $gitproject ) 2> $tempdir /$project .log
169+ local gitproject=" ${githubUri} dlang/$project .git"
170+ local git=(" git" " -C" " $wd /$project " )
171+ if ! ( \
172+ " ${git[@]} " checkout master && \
173+ " ${git[@]} " pull --ff-only --tags " $gitproject " master ) 2> " $tempdir /$project .log"
151174 then
152- echo " Failure updating $wd /$project ." >> $tempdir /errors
175+ echo " Failure updating $wd /$project ." >> " $tempdir /errors"
153176 exit 1
154177 fi
155178 }
156179
157- for project in $ toUpdate; do
158- update_project $project &
180+ for project in " ${ toUpdate[@]} " ; do
181+ update_project " $project " &
159182 done
160183 wait
161184
162- if [ -f $tempdir /errors ]; then
163- cat $tempdir /* .log >&2
185+ if [ -f " $tempdir /errors" ]; then
186+ cat " $tempdir " /* .log >&2
164187 exit 1
165188 fi
166189}
167190
168191function makeWorld() {
169- # First make dmd
170- (
171- which dmd > /dev/null || BT=" AUTO_BOOTSTRAP=1"
172- cd " $wd /dmd/src" &&
173- $makecmd -f posix.mak clean MODEL=$model $BT &&
174- $makecmd -f posix.mak -j $parallel MODEL=$model $BT
175- )
176-
177- # Update the running dmd version
178- if [[ ! -z $install ]]; then
179- local old=$( which dmd)
192+ local BOOTSTRAP=" "
193+ which dmd > /dev/null || BOOTSTRAP=" AUTO_BOOTSTRAP=1"
194+ for repo in dmd druntime phobos ; do
195+ " $makecmd " -C " $wd /$repo " -f posix.mak clean
196+ " $makecmd " -C " $wd /$repo " -f posix.mak " -j${parallel} " MODEL=" $model " BUILD=" $build " $BOOTSTRAP
197+ done
198+
199+ # Update the running dmd version (only required once)
200+ if [[ ! -z " ${install+x} " ]]; then
201+ local old dmdBinary
202+ old=$( which dmd)
203+ dmdBinary=$( ls -1 $wd /dmd/generated/* /$build /$model /dmd)
180204 if [ -f " $old " ]; then
181- echo " Copying " $wd /dmd/src/dmd" over $old "
182- [ ! -w " $old " ] && local sudo=" sudo"
183- $sudo cp " $wd /dmd/src/dmd" " $old "
205+ echo " Linking '$dmdBinary ' to $old "
206+ local sudo=" "
207+ if [ ! -w " $old " ] ; then
208+ sudo=" sudo"
209+ fi
210+ ln -s " $tempdir /dmd.symlink" " $old "
211+ " $sudo " mv " $tempdir /dmd.symlink" " $old "
184212 fi
185213 fi
186-
187- # Then make druntime
188- (
189- cd " $wd /druntime" &&
190- $makecmd -f posix.mak -j $parallel DMD=" $wd /dmd/src/dmd" MODEL=$model
191- )
192-
193- # Then make phobos
194- (
195- cd " $wd /phobos" &&
196- $makecmd -f posix.mak -j $parallel DMD=" $wd /dmd/src/dmd" MODEL=$model
197- )
198-
199- # Then make website
200- (
201- cd " $wd /dlang.org" &&
202- $makecmd -f posix.mak clean DMD=" $wd /dmd/src/dmd" MODEL=$model &&
203- $makecmd -f posix.mak html -j $parallel DMD=" $wd /dmd/src/dmd" MODEL=$model
204- )
205214}
206215
207216# main
208- handleCmdLine $*
217+ handleCmdLine " $@ "
209218confirmChoices
210- installAnew $toInstall
211- update $toUpdate
219+ if [ ${# toInstall[@]} -gt 0 ] ; then
220+ installAnew " ${toInstall[@]} "
221+ fi
222+ if [ ${# toUpdate[@]} -gt 0 ] ; then
223+ update " ${toUpdate[@]} "
224+ fi
212225makeWorld
0 commit comments