-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsymbol
executable file
·259 lines (218 loc) · 6.15 KB
/
symbol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
#!/usr/bin/env bash
# ============================================================================
#
# This file was generated with 'symbol-new smlnj-viscomp-example'
# Do NOT delete this file!
# This file should be checked into version control.
#
# For usage information, run
#
# ./symbol help
#
# or visit https://github.com/jez/symbol
#
# ============================================================================
set -euo pipefail
# cd into folder where the 'symbol' script is located, or quit (defensive)
BINPATH="$(perl -MCwd -le 'print Cwd::abs_path(shift)' "${BASH_SOURCE[0]}")"
cd "$(dirname "$BINPATH")" || exit 1
target=smlnj-viscomp-example
version=v0.10.5
# ----- logging & colors ------------------------------------------------------
red=$'\x1b[0;31m'
green=$'\x1b[0;32m'
yellow=$'\x1b[0;33m'
cyan=$'\x1b[0;36m'
cnone=$'\x1b[0m'
if [ -t 1 ]; then
USE_COLOR=1
else
USE_COLOR=0
fi
# Detects whether we can add colors or not
# http://stackoverflow.com/a/911213
in_color() {
local color="$1"
shift
if [ "$USE_COLOR" = "1" ]; then
echo "$color$*$cnone"
else
echo "$*"
fi
}
info() {
echo "$(in_color "$cyan" "[ .. ]") $*"
}
warn() {
# Entire warning message is yellow, because it won't halt the program, but we
# still really want to catch the user's attention.
in_color "$yellow" "[WARN] $*"
}
error() {
echo "$(in_color "$red" "[ERR!]") $*"
}
success() {
echo "$(in_color "$green" "[ OK ]") $*"
}
# ----- helper functions ------------------------------------------------------
tidy_symbol_work() {
mkdir -p .symbol-work
# This guards against the case where make won't build the target because
# the last command just built the target, but for the wrong "with=" value.
if [ -f .symbol-work/with ] && ! grep -q "^$WITH\$" .symbol-work/with; then
rm -f ".symbol-work/bin/$target"
fi
rm -f .symbol-work/error.log
rm -f .symbol-work/debug.log
}
ensure_no_argv() {
if [ "${#ARGV[@]}" -ne 0 ]; then
error "This command does not accept positional arguments."
info "subcommand: $SUBCOMMAND"
info "argv: ${ARGV[*]}"
exit 1
fi
}
ensure_with() {
if [ -z "$WITH" ]; then
error "Could not infer what to build the project with (with='')."
error "Is there a $target.cm file or $target.mlb file in this folder?"
print_help
exit 1
elif [ "$WITH" != smlnj ] && [ "$WITH" != mlton ]; then
error "Cannot build using 'with=$WITH'. Valid values: smlnj, mlton"
print_help
exit 1
fi
}
print_help() {
cat <<EOF
symbol: A build tool for Standard ML
Usage:
./symbol make [make variables]
./symbol install [make variables]
./symbol clean
./symbol version
Make variables:
with=(smlnj|mlton) Which toolchain to use to build the project.
[default: smlnj, unless no *.cm file]
prefix=<prefix> Where to install the resulting binaries to.
[default: \$HOME/.local]
EOF
}
# ----- option parsing --------------------------------------------------------
SUBCOMMAND="${1:-help}"
shift || true
WITH=""
MAKE_VARS=()
ARGV=()
while [[ $# -gt 0 ]]; do
case $1 in
with=*)
# removes 'with=' prefix
WITH=${1#with=}
shift
;;
*=*)
MAKE_VARS+=("$1")
shift
;;
-h|--help)
print_help
exit
;;
-*)
echo
error "Unrecognized option: '$1'"
print_help
exit 1
;;
*)
ARGV+=("$1")
shift
;;
esac
done
# Attempt to default with= to smlnj or mlton depending on what files exist
if [ -z "$WITH" ]; then
if [ "$SUBCOMMAND" = 'install' ] && [ -f "$target.mlb" ]; then
WITH=mlton
elif [ -f "$target.cm" ]; then
WITH=smlnj
elif [ -f "$target.mlb" ]; then
WITH=mlton
fi
fi
# ----- main ------------------------------------------------------------------
main() {
case "$SUBCOMMAND" in
make|install)
tidy_symbol_work
ensure_no_argv
ensure_with
# We do some crazy fd dupping here so that the make subprocess can log
# directly to our stdout, even though we redirect all of its other output
#
# child (make) "maps to" parent (symbol)
# fd 3 -> <stdout>
# <stdout> -> symbol.log
# <stderr> -> symbol.log
# Check to see if "make: Nothing to be done for `make'" would be printed
# https://stackoverflow.com/questions/7577052
if make -f .symbol.mk --question "$SUBCOMMAND" "with=$WITH" \
${MAKE_VARS[@]+"${MAKE_VARS[@]}"} 3>&1 >> .symbol-work/debug.log 2>&1; then
return
fi
# Build succeeded. The make target should have printed output.
if make -f .symbol.mk "$SUBCOMMAND" "with=$WITH" \
${MAKE_VARS[@]+"${MAKE_VARS[@]}"} 3>&1 >> .symbol-work/debug.log 2>&1; then
return
fi
if [ -f .symbol-work/error.log ]; then
# Normal failure.
# error.log is populated from SML/NJ / MLton-related commands.
cat .symbol-work/error.log
error "Building with '$WITH' failed. See output above."
info "(Debug output is in .symbol-work/debug.log)"
exit 1
elif [ -f .symbol-work/debug.log ]; then
# Exceptional failure. Probably something is wrong in the Makefile.
cat .symbol-work/debug.log
error "Build failed for unknown reason. Debugging output is above."
exit 1
else
# Super exceptional failure. We don't even have makefile debug output.
error "Build failed for unknown reason. If you can reproduce the failure,"
error "please report an issue: https://github.com/jez/symbol/issues"
exit 1
fi
;;
clean)
make -f .symbol.mk clean
;;
log)
# Helper subcommand to let logging commands be called from the makefile
case ${ARGV[0]} in
info|warn|error|success)
"${ARGV[@]}"
;;
*)
error "Unrecognized log command: '${ARGV[0]}'"
exit 1
;;
esac
;;
-h|--help|help)
print_help
;;
--version|version)
echo "$version"
;;
*)
error "Unrecognized subcommand: '$SUBCOMMAND'"
print_help
exit 1
;;
esac
}
main "$@"