-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathbuild.sh
More file actions
executable file
·185 lines (167 loc) · 6.1 KB
/
build.sh
File metadata and controls
executable file
·185 lines (167 loc) · 6.1 KB
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
#!/bin/bash
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Fail on error
set -e
#set -x
# Base image and packages are defined in Dockerfile (digest-pinned, tracked by Dependabot).
# To regenerate requirements.txt after changing requirements.in, see README.md#updating-the-dependency-lockfile
SOLR_LOCAL_PELICAN_IMAGE="solr-pelican-image"
DOCKER_CMD="docker run --rm -ti -w /work -p 8000:8000 -v $(pwd):/work $SOLR_LOCAL_PELICAN_IMAGE"
unset SERVE
unset BUILD
unset LOCK
PELICAN_CMD="pelican content -o output"
export SITEURL="https://solr.apache.org/"
# Option definitions: "short_flag:long_flag:description"
# Omit short_flag (leave empty before first colon) for long-only options.
# Usage text and getopt spec are both derived from this array.
OPTIONS=(
"l:live:Live build and reload source changes on localhost:8000"
"b:build:Force rebuild of the local Docker image"
":lock:Regenerate requirements.txt from requirements.in (use with -b to also rebuild image)"
"h:help:Show this help message"
":pelican-help:Show all options accepted by Pelican"
)
function usage {
echo "Usage: ./build.sh [OPTIONS] [-- <pelican arguments>]"
echo ""
echo "Options:"
for opt_def in "${OPTIONS[@]}"; do
short="${opt_def%%:*}"
rest="${opt_def#*:}"
long="${rest%%:*}"
desc="${rest#*:}"
if [[ -n "$short" ]]; then
printf " -%s, --%-16s %s\n" "$short" "$long" "$desc"
else
printf " --%-16s %s\n" "$long" "$desc"
fi
done
echo ""
echo "Any extra arguments after -- are passed directly to Pelican."
}
# Build short and long getopt spec strings from OPTIONS array.
function _getopt_specs {
local short="" long=""
for opt_def in "${OPTIONS[@]}"; do
s="${opt_def%%:*}"
l="${opt_def#*:}"; l="${l%%:*}"
[[ -n "$s" ]] && short+="$s"
long+="${long:+,}${l}"
done
echo "${short}|${long}"
}
function build_image {
echo "Building local Docker image for Pelican, called $SOLR_LOCAL_PELICAN_IMAGE."
docker build --no-cache -t $SOLR_LOCAL_PELICAN_IMAGE .
}
function regen_lockfile {
ensure_image
echo "Regenerating requirements.txt from requirements.in inside Docker..."
docker run --rm -w /work -v "$(pwd):/work" $SOLR_LOCAL_PELICAN_IMAGE \
pip-compile --quiet --strip-extras --allow-unsafe --generate-hashes --output-file=requirements.txt requirements.in
echo "requirements.txt updated."
}
function ensure_image {
if ! docker inspect $SOLR_LOCAL_PELICAN_IMAGE >/dev/null 2>&1
then
build_image
fi
}
function check_requirements_update {
# Check requirements.txt — that is what is COPY'd into the Dockerfile
local req_mod_time
if [[ $(uname) == "Darwin" ]]; then
req_mod_time=$(stat -f "%m" requirements.txt)
else
req_mod_time=$(stat -c "%Y" requirements.txt)
fi
# Get the build timestamp of the docker image
local image_build_time
image_build_time=$(docker inspect --format='{{.Created}}' $SOLR_LOCAL_PELICAN_IMAGE)
# Parse the timestamp into seconds since epoch in UTC
if [[ $(uname) == "Darwin" ]]; then
# macOS date command workaround
image_build_time=$(echo "$image_build_time" | awk -F '.' '{print $1}')
image_build_time=$(date -ju -f "%Y-%m-%dT%H:%M:%S" "$image_build_time" "+%s")
else
# Linux date command
image_build_time=$(date -d "$(echo "$image_build_time" | cut -d'.' -f1 | sed 's/T/ /; s/Z//')" --utc "+%s")
fi
# Compare the timestamps and rebuild if requirements.txt is newer than the image
if [[ $req_mod_time -gt $image_build_time ]]; then
echo "requirements.txt has been updated since the last build, rebuilding image!"
build_image
fi
}
if ! docker -v >/dev/null 2>&1
then
echo "ERROR: This script requires docker."
echo " Please install Docker and try again."
echo
usage
exit 2
fi
# Handle a single parsed option. Returns 1 (exit loop) on --.
function handle_opt {
case "$1" in
-l|--live) SERVE=true ;;
-b|--build) BUILD=true ;;
--lock) LOCK=true ;;
-h|--help) usage; exit 0 ;;
--pelican-help) ensure_image; $DOCKER_CMD pelican -h; exit 0 ;;
--) return 1 ;;
*) echo "Unknown option: $1" >&2; usage; exit 1 ;;
esac
}
# Use GNU getopt when available (detected via exit code 4 from getopt -T).
# GNU getopt gives proper error messages and handles --opt=value and option
# reordering. Falls back to a plain bash loop which handles all our flag options.
getopt -T &>/dev/null; _getopt_test=$?
if [[ $_getopt_test -eq 4 ]]; then
specs=$(_getopt_specs)
PARSED=$(getopt -o "${specs%%|*}" --long "${specs#*|}" -n "build.sh" -- "$@") || { usage; exit 1; }
eval set -- "$PARSED"
while true; do
if handle_opt "$1"; then shift; else shift; break; fi
done
else
while [[ $# -gt 0 ]]; do
if handle_opt "$1"; then shift; else shift; break; fi
done
fi
if [[ $LOCK ]]; then
regen_lockfile
if [[ ! $BUILD ]]; then
echo "Run './build.sh -b' to rebuild the Docker image with the updated lockfile."
exit 0
fi
fi
if [[ $BUILD ]]; then
build_image
else
ensure_image
check_requirements_update
fi
if [[ $SERVE ]]; then
echo "Building Solr site locally. Goto http://localhost:8000 to view."
echo "Edits you do to the source tree will be compiled immediately!"
$DOCKER_CMD sh -c "$PELICAN_CMD --autoreload --listen -b 0.0.0.0 $*"
else
echo "Building Solr site locally."
echo "To build and serve live edits locally, run this script with -l argument. Use -h for help."
$DOCKER_CMD sh -c "$PELICAN_CMD $*"
fi