Skip to content

Commit 8df8eb7

Browse files
authored
Merge pull request #309 from wilzbach/fix-setup-sh
Cleanup setup.sh + bash compatible + full shellcheck + run on Travis merged-on-behalf-of: Sebastian Wilzbach <[email protected]>
2 parents 0f2f073 + 13841a8 commit 8df8eb7

File tree

2 files changed

+130
-95
lines changed

2 files changed

+130
-95
lines changed

setup.sh

+108-95
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
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:
@@ -19,45 +17,72 @@
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
#
4364
function 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
#
6994
function 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

109133
function 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

168191
function 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 "$@"
209218
confirmChoices
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
212225
makeWorld

travis.sh

+22
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,25 @@ make -f posix.mak all DMD="$(which dmd)"
1414
make -f posix.mak test DMD="$(which dmd)" \
1515
RDMD_TEST_COMPILERS=dmd,"$GDMD","$LDMD2" \
1616
VERBOSE_RDMD_TEST=1
17+
18+
# Test setup.sh
19+
shellcheck setup.sh
20+
21+
dmd=dmd/generated/linux/release/64/dmd
22+
dir=generated/setup.sh-test
23+
cwd="$(pwd)"
24+
25+
# check initial checkout
26+
rm -rf "$dir" && mkdir "$dir" && pushd "$dir"
27+
echo "y" | "$cwd"/setup.sh
28+
echo 'void main(){ import std.stdio; "Hello World".writeln;}' | "./${dmd}" -run - | grep -q "Hello World"
29+
30+
# test updates
31+
echo "y" | "$cwd"/setup.sh
32+
echo 'void main(){ import std.stdio; "Hello World".writeln;}' | "./${dmd}" -run - | grep -q "Hello World"
33+
popd && rm -rf "$dir" && mkdir "$dir" && pushd "$dir"
34+
35+
# test checking out tags
36+
echo "y" | "$cwd"/setup.sh --tag=2.078.1
37+
echo 'void main(){ import std.stdio; __VERSION__.writeln;}' | "./2.078.1/${dmd}" -run - | grep -q "2078"
38+
popd

0 commit comments

Comments
 (0)