-
Notifications
You must be signed in to change notification settings - Fork 0
/
build_generic.sh
executable file
·151 lines (135 loc) · 4.41 KB
/
build_generic.sh
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
#!/bin/bash
# NOTE: ensure to declare `local` and `readonly` variables on a separate line
# from a command substitution because `set -e` will fail to recognize an error
# occured with e.g. `readonly x=$(ls -z)` because:
# https://google.github.io/styleguide/shellguide.html#s7.6-use-local-variables
set -eu
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
cd "${DIR}"
ARGS=("$@")
DATE=$(date --utc --iso=seconds)
TRASH="${DIR}/_CLEANED/$DATE"
# associative array
declare -A IGNORE
IGNORE["$0"]=1
# `build.sh` calls this script with arguments specified
IGNORE["${DIR}/build.sh"]=1
IGNORE["${DIR}/.git"]=1
IGNORE["${DIR}/.gitignore"]=1
IGNORE["${DIR}/_CLEANED"]=1
IGNORE["${DIR}/index.html"]=1
readonly DIR ARGS DATE TRASH IGNORE
function get_files () {
local files
readarray -d '' files < <(find "$DIR" -mindepth 1 -maxdepth 1 -print0)
# `output` is a nameref to allow returning an array from this function
local -n output=$1
output=()
for f in "${files[@]}"; do
if [[ -z ${IGNORE["$f"]+x} ]]; then
output+=("$f")
fi
done
}
function rust_cargo () {
local manifest="$2"
local target="${DIR}/${1}"
local tmp_dir
tmp_dir=$(mktemp -d)
readonly tmp_dir
if ! [[ -z "$(ls -A $tmp_dir)" ]]; then
echo "DANGER: expected empty directory '$tmp_dir'" 1>&2
exit 1
fi
cargo doc --no-deps --manifest-path $manifest --target-dir "$tmp_dir"
mv "${tmp_dir}/doc" "$target"
echo "Created ${target}"
if [[ -f "${tmp_dir}/.rustc_info.json" ]]; then
echo "Removing tmp directory ${tmp_dir}"
rm -rf "${tmp_dir}"
else
printf "\nError: Failed safefy check when attempting to remove ${tmp_dir}\n" 1>&2
exit 1
fi
}
function jl_make () {
local make_file="$2"
local target="${DIR}/${1}"
julia -- "$make_file"
mv "$(dirname "${make_file}")/build/" "$target"
echo "Created ${target}"
}
function usage() {
echo "Usage:"
echo " $(basename "$0") [paths...] Get docs for the specified 'Cargo.toml' for Rust or 'make.jl' for Julia"
echo " $(basename "$0") clean Place previous buillds in directory '_CLEANED'"
echo "where:"
echo " paths: path to a Cargo.toml"
}
function run() {
local -a trash_files
get_files trash_files
readonly trash_files
case "${ARGS[0]}" in
clean)
if [[ ${#ARGS[@]} -gt 1 ]]; then
usage 1>&2
exit 1
fi
if [[ ${#trash_files[@]} -eq 0 ]]; then
echo "No files to clean" 1>&2
exit 0
fi
echo "Moving files to $TRASH:"
mkdir -p "${TRASH}"
for f in "${trash_files[@]}"; do
echo "$f"
mv "$f" "$TRASH"
done
printf "\nContents of ${DIR}/_CLEANED:\n"
du -hd 1 "${DIR}/_CLEANED"
;;
-h|--help)
usage 1>&2
exit 0
;;
*)
local -a projects langs
if [[ ${#trash_files[@]} -gt 0 ]]; then
echo "Run \`$0 clean\` ... found files:" 1>&2
printf '%s\n' "${trash_files[@]}"
exit 1
fi
# check inputs
local project_path
for project_path in "${ARGS[@]}"; do
if [[ "$(basename "$project_path")" == "Cargo.toml" ]]; then
langs+=("rust")
projects+=("$(awk -F'[ ="]+' '$1 == "name" { print $2 }' $project_path)")
elif [[ "$(basename "$project_path")" == "make.jl" ]]; then
langs+=("julia")
projects+=("$(awk -F'[][]' '/modules/ { print $2 }' $project_path)")
else
usage 1>&2
exit 1
fi
done
echo "Found projects:"
local lang proj path
for ii in $(seq 0 $((${#ARGS[@]} - 1)) ); do
lang="${langs[${ii}]}"
proj="${projects[${ii}]}"
path="$( realpath -e "${ARGS[${ii}]}" )"
echo "$lang: $proj => $path"
if [[ "$lang" == "rust" ]]; then
rust_cargo "$proj" "$path"
elif [[ "$lang" == "julia" ]]; then
jl_make "$proj" "$path"
fi
printf "\n"
done
;;
esac
}
run
exit 0