mirror of
https://github.com/commercialhaskell/stackage.git
synced 2026-01-11 23:08:30 +01:00
178 lines
4.5 KiB
Bash
Executable File
178 lines
4.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -eu
|
|
cd "$(dirname "$0")"
|
|
|
|
#
|
|
# Constants and defaults
|
|
#
|
|
|
|
DOCKER_REPO=fpco/stack-build
|
|
PUSH=false
|
|
DRY=false
|
|
VARIANT=build
|
|
|
|
#
|
|
# Functions
|
|
#
|
|
|
|
# Print usage information and exit with failure status. First argument is an
|
|
# error message.
|
|
usage() {
|
|
echo "$0: $1" >&2
|
|
echo
|
|
echo "Usage: $0 [--push] [--dry-run] [--small] lts-X.Y]"
|
|
echo "See README.md for more information."
|
|
echo
|
|
exit 1
|
|
}
|
|
|
|
# Print a command, and if --dry-run disabled also run it
|
|
dry() {
|
|
echo ">>> $*"
|
|
[[ $DRY = true ]] || "$@"
|
|
}
|
|
|
|
# Push an image if --push is enabled (otherwise do nothing)
|
|
push() {
|
|
[[ $PUSH = false ]] || dry docker push "$1"
|
|
}
|
|
|
|
# Tag an image, and then push it if --push is enabled
|
|
tagpush() {
|
|
dry docker tag "$1" "$2"
|
|
push "$2"
|
|
}
|
|
|
|
#
|
|
# Parse command-line
|
|
#
|
|
|
|
LTS_SLUG_ARG=
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--push)
|
|
PUSH=true
|
|
shift
|
|
;;
|
|
--dry-run)
|
|
DRY=true
|
|
shift
|
|
;;
|
|
--small)
|
|
VARIANT=small
|
|
DOCKER_REPO=fpco/stack-build-small
|
|
shift
|
|
;;
|
|
-*)
|
|
usage "Unknown option: $1"
|
|
;;
|
|
*)
|
|
if [[ -n "$LTS_SLUG_ARG" ]]; then
|
|
usage "Cannot specify multiple snapshots: $1"
|
|
fi
|
|
LTS_SLUG_ARG="$1"
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
case "$LTS_SLUG_ARG" in
|
|
"")
|
|
usage "Missing argument: snapshot"
|
|
;;
|
|
lts-*.*)
|
|
LTS_SLUG="$LTS_SLUG_ARG"
|
|
;;
|
|
*)
|
|
echo "$0: Wrong snapshot format: $LTS_SLUG_ARG" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
#
|
|
# Determine if lts slug is latest
|
|
#
|
|
|
|
SNAPSHOTS="$(mktemp "lts-snapshots.json.XXXXXX")"
|
|
trap "rm -f \"$SNAPSHOTS\"" EXIT
|
|
wget -qO- https://www.stackage.org/download/lts-snapshots.json >"$SNAPSHOTS"
|
|
|
|
LTS_VERSION="${LTS_SLUG#lts-}"
|
|
LTS_MAJOR="${LTS_VERSION%.*}"
|
|
LTS_MINOR="${LTS_VERSION#*.}"
|
|
|
|
#
|
|
# Determine latest LTS version
|
|
#
|
|
|
|
if [[ ! -x "$HOME/.local/bin/jq" ]]; then
|
|
mkdir -p $HOME/.local/bin
|
|
if [[ "$(uname)" = "Darwin" ]]; then
|
|
curl -o $HOME/.local/bin/jq -L https://github.com/stedolan/jq/releases/download/jq-1.6/jq-osx-amd64
|
|
else
|
|
curl -o $HOME/.local/bin/jq -L https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64
|
|
fi
|
|
chmod +x $HOME/.local/bin/jq
|
|
fi
|
|
|
|
LATEST_LTS_SLUG=$($HOME/.local/bin/jq -r ".[\"lts\"]" $SNAPSHOTS)
|
|
LATEST_LTS_VERSION="${LATEST_LTS_SLUG#lts-}"
|
|
LATEST_LTS_MAJOR="${LATEST_LTS_VERSION%.*}"
|
|
LATEST_LTS_MINOR="${LATEST_LTS_VERSION#*.}"
|
|
|
|
#
|
|
# Determine latest minor version of the selected major version
|
|
#
|
|
|
|
MAJOR_LATEST_LTS_SLUG=$(jq -r ".[\"lts-$LTS_MAJOR\"]" $SNAPSHOTS)
|
|
MAJOR_LATEST_LTS_VERSION="${MAJOR_LATEST_LTS_SLUG#lts-}"
|
|
MAJOR_LATEST_LTS_MAJOR="${MAJOR_LATEST_LTS_VERSION%.*}"
|
|
MAJOR_LATEST_LTS_MINOR="${MAJOR_LATEST_LTS_VERSION#*.}"
|
|
|
|
#
|
|
# Find the Dockerfile for the selected snapshot
|
|
#
|
|
|
|
if [[ -s "$LTS_SLUG/Dockerfile" ]]; then
|
|
|
|
# If there is an exact match, build and push that image
|
|
|
|
sed "s/\\\$DOCKER_REPO/$(echo $DOCKER_REPO|sed 's/\//\\\//')/g" "$LTS_SLUG/Dockerfile" >"$LTS_SLUG/Dockerfile.sub"
|
|
dry docker build -t "$DOCKER_REPO:$LTS_SLUG" --build-arg "DOCKER_REPO=$DOCKER_REPO" --build-arg "LTS_SLUG=$LTS_SLUG" --build-arg "VARIANT=$VARIANT" -f "$LTS_SLUG/Dockerfile.sub" "$LTS_SLUG"
|
|
rm -f "$LTS_SLUG/Dockerfile.sub"
|
|
push "$DOCKER_REPO:$LTS_SLUG"
|
|
else
|
|
|
|
# If no exact match, find a dockerfile for any earlier minor version of the
|
|
# selected major version, and just create a new tag from version's image with the selected
|
|
# minor version (assuming that nothing needs to change), and push it.
|
|
|
|
minor=$(( LTS_MINOR - 1 ))
|
|
while [[ ! -s "lts-$LTS_MAJOR.$minor/Dockerfile" && $minor -ge 0 ]]; do
|
|
minor=$(( minor - 1 ))
|
|
done
|
|
if [[ $minor -lt 0 ]]; then
|
|
echo "$0: Cannot find any Dockerfile for LTS major version" >&2
|
|
exit 1
|
|
fi
|
|
dry docker pull "$DOCKER_REPO:lts-$LTS_MAJOR.$minor" || true
|
|
tagpush "$DOCKER_REPO:lts-$LTS_MAJOR.$minor" "$DOCKER_REPO:$LTS_SLUG"
|
|
fi
|
|
|
|
#
|
|
# Create and push additional tags
|
|
#
|
|
|
|
# If we select the latest minor version for the selected major version, then
|
|
# also create and push an 'lts-X' tag.
|
|
if [[ $LTS_MINOR -ge $MAJOR_LATEST_LTS_MINOR ]]; then
|
|
tagpush "$DOCKER_REPO:$LTS_SLUG" "$DOCKER_REPO:lts-$LTS_MAJOR"
|
|
fi
|
|
|
|
# If we selected the latest LTS snapshot, also create and push the 'lts' and 'latest' tags.
|
|
if [[ "$LTS_MAJOR" = "$LATEST_LTS_MAJOR" ]] && [[ $LTS_MINOR -ge $LATEST_LTS_MINOR ]]; then
|
|
tagpush "$DOCKER_REPO:$LTS_SLUG" "$DOCKER_REPO:lts"
|
|
tagpush "$DOCKER_REPO:$LTS_SLUG" "$DOCKER_REPO:latest"
|
|
fi
|