#!/usr/bin/env bash set -eo pipefail function print_help { cat << END build.sh is a facade for docker compose. It runs a set of optional tasks in the order specified below. This is the same script used by CI/CD to build, test, and package FQL. If the '--down' flag is set then 'docker compose down -v' is run first, shutting down all services and removing volumes. If the '--image build' flag is set then the script runs 'docker build' for the 'fql-build' docker image. The tag is determined by the git tag/hash and the FDB version. This image is used to run the 'generate' and 'verify' tasks below. If the '--generate' flag is set then the script checks if the code generated by 'go generate ./...' is up to date. If the '--verify' flag is set then the script builds, lints, and tests the codebase. This task interacts with an FDB docker container which is automatically started. If the --docs' flag is set then the documentation HTML will be generated under the /docs directory. If the '--image fql' flag is set then the script runs 'docker build' for the 'fql' docker image. The tag is determined by the git tag/hash and the FDB version. If the '--run' flag is provided then all the args after this flag are passed to an instance of the 'fql' docker image. Normally this image expects a cluster file as the first argument but this script takes care of starting an FDB cluster and providing the cluster file as the first argument. Note that this is the same FDB instance used by the 'verify' task. ./build.sh --run --write -q '/my/dir("hi")=nil' After this, the script ends. If any of the requested tasks fail then the script exits immediately. Multiple image names can be specified on the '--image' flag by separating them with commas. ./build.sh --image build,fql When building Docker images, the dependencies of the Dockerfile are specified in 'bake.hcl'. When this file is changed, you'll need to rebuild the docker images for the changes to take effect. END } # fail prints $1 to stderr and exits with code 1. function fail { local RED='\033[0;31m' NO_COLOR='\033[0m' echo -e "${RED}ERR! ${1}${NO_COLOR}" >&2 exit 1 } # join_array joins the elements of the $2 array into a # single string, placing $1 between each element. function join_array { local sep="$1" out="$2" if shift 2; then for arg in "$@"; do out="${out}${sep}${arg}" done fi echo "$out" } # Change directory to repo root. cd "${0%/*}" # Parse the flags. if [[ $# -eq 0 ]]; then print_help echo fail "At least one flag must be provided." fi while [[ $# -gt 0 ]]; do case $1 in --down) COMPOSE_DOWN="x" shift 1 ;; --generate) VERIFY_GENERATION="x" shift 1 ;; --verify) VERIFY_CODEBASE="x" shift 1 ;; --docs) GENERATE_DOCS="x" shift 1 ;; --image) for service in $(echo "$2" | tr "," "\n"); do case $service in build) IMAGE_BUILD="x" ;; fql) IMAGE_FQL="x" ;; *) fail "Invalid build target '$service'" ;; esac done shift 2 ;; --run) shift 1 RUN_FQL="x" FQL_ARGS=("$@") shift $# ;; --help) print_help exit 0 ;; *) fail "Invalid flag '$1'" esac done # Build variables required by the docker compose command. BUILD_TASKS=() if [[ -n "$VERIFY_GENERATION" ]]; then BUILD_TASKS+=('./scripts/verify_generation.sh') fi if [[ -n "$VERIFY_CODEBASE" ]]; then BUILD_TASKS+=('./scripts/setup_database.sh') BUILD_TASKS+=("./scripts/verify_codebase.sh") fi if [[ -n "$GENERATE_DOCS" ]]; then BUILD_TASKS+=('./scripts/generate_docs.sh') fi BUILD_COMMAND="$(join_array ' && ' "${BUILD_TASKS[@]}")" echo "BUILD_COMMAND=${BUILD_COMMAND}" export BUILD_COMMAND FQL_COMMAND=${FQL_ARGS[*]} echo "FQL_COMMAND=${FQL_COMMAND}" export FQL_COMMAND DOCKER_TAG="$(./scripts/docker_tag.sh)" echo "DOCKER_TAG=${DOCKER_TAG}" export DOCKER_TAG FDB_DOCKER_IMAGE="foundationdb/foundationdb:${FDB_VER:-6.2.30}" echo "FDB_DOCKER_IMAGE=${FDB_DOCKER_IMAGE}" export FDB_DOCKER_IMAGE # Run the requested commands. if [[ -n "$COMPOSE_DOWN" ]]; then (set -x; docker compose down -v) fi if [[ -n "$IMAGE_BUILD" ]]; then (set -x; docker buildx bake -f bake.hcl --load build) fi if [[ -n "$BUILD_COMMAND" ]]; then if ! docker image inspect "docker.io/janderland/fql-build:${DOCKER_TAG}" &>/dev/null; then echo "Build image not found, building..." (set -x; docker buildx bake -f bake.hcl --load build) fi if [[ -n "$VERIFY_CODEBASE" ]]; then (set -x; docker compose up -d fdb) fi (set -x; docker compose run --rm build /bin/sh -c "$BUILD_COMMAND") fi if [[ -n "$IMAGE_FQL" ]]; then (set -x; docker buildx bake -f bake.hcl --load fql) fi if [[ -n "$RUN_FQL" ]]; then if ! docker image inspect "docker.io/janderland/fql:${DOCKER_TAG}" &>/dev/null; then echo "FQL image not found, building..." (set -x; docker buildx bake -f bake.hcl --load fql) fi (set -x; docker compose run --rm fql 'docker:docker@{fdb}:4500' "${FQL_ARGS[@]}") fi