#!/bin/bash # This script is to be sourced in .travis.yaml from the project root directory, do not use it from somewhere else. # Creates or loads docker images to use in compilation, creates RUN function to start compilation on the docker image. # --get loads the image from a previously saved image cache, will build if no image is found # --build builds the image from the Dockerfile in .ci/$NAME # --save stores the image, if an image was loaded it will not be stored # requires: docker # uses env: NAME CACHE BUILD GET SAVE (correspond to args: --set-cache --build --get --save) # sets env: RUN CCACHE_DIR IMAGE_NAME RUN_ARGS RUN_OPTS BUILD_SCRIPT # exitcode: 1 for failure, 2 for missing dockerfile, 3 for invalid arguments export BUILD_SCRIPT=".ci/travis-compile.sh" project_name="cockatrice" save_extension=".tar.gz" image_cache="image" ccache_cache=".ccache" # Read arguments while [[ "$@" ]]; do case "$1" in '--build') BUILD=1 shift ;; '--get') GET=1 shift ;; '--save') SAVE=1 shift ;; '--set-cache') CACHE=$2 if ! [[ -d $CACHE ]]; then echo "could not find cache path: $CACHE" >&2 exit 3 fi shift 2 ;; *) if [[ $1 == -* ]]; then echo "unrecognized option: $1" return 3 fi NAME="$1" shift ;; esac done # Setup if ! [[ $NAME ]]; then echo "no build name given" >&2 return 3 fi export IMAGE_NAME="${project_name,,}_${NAME,,}" docker_dir=".ci/$NAME" if ! [[ -r $docker_dir/Dockerfile ]]; then echo "could not find Dockerfile in $docker_dir" >&2 return 2 # even if the image is cached, we do not want to run if there is no way to build this image fi if ! [[ -d $CACHE ]]; then echo "could not find cache dir: $CACHE" >&2 unset CACHE else if [[ $GET || $SAVE ]]; then img_dir="$CACHE/$image_cache" img_save="$img_dir/$IMAGE_NAME$save_extension" if ! [[ -d $img_dir ]]; then echo "could not find image dir: $img_dir" >&2 mkdir -p "$img_dir" fi fi export CCACHE_DIR="$CACHE/$ccache_cache" if ! [[ -d $CCACHE_DIR ]]; then echo "could not find ccache dir: $CCACHE_DIR" >&2 mkdir -p "$CCACHE_DIR" fi fi # Get the docker image from previously stored save if [[ $GET ]]; then if [[ $img_save ]] && docker load --input "$img_save"; then echo "loaded image" docker images unset BUILD # do not overwrite the loaded image with build unset SAVE # do not overwrite the stored image with the same image if [[ $(find "$CCACHE_DIR" -type f -print -quit) ]]; then # check contents of ccache echo "setting ccache to readonly" export RUN_ARGS="$RUN_ARGS -e CCACHE_READONLY=1 -e CCACHE_NOSTATS=1" # do not overwrite ccache else echo "ccache is empty: $(find "$CCACHE_DIR")" >&2 fi else echo "could not load cached image, building instead" >&2 BUILD=1 fi fi # Build the docker image from dockerfile if [[ $BUILD ]]; then if docker build --tag "$IMAGE_NAME" "$docker_dir"; then echo "built image" docker images else echo "could not build image $IMAGE_NAME" >&2 return 1 fi fi # Save docker image to cache (compressed) if [[ $SAVE ]]; then if [[ $img_save ]] && docker save --output "$img_save" "$IMAGE_NAME"; then echo "saved image to: $img_save" else echo "could not save image $IMAGE_NAME" >&2 fi fi # Set compile function, runs the compile script on the image, passes arguments to the script function RUN () { echo "running image:" if docker images | grep "$IMAGE_NAME"; then args="--mount type=bind,source=$(pwd),target=/src -w=/src" if [[ $CCACHE_DIR ]]; then args+=" --mount type=bind,source=$CCACHE_DIR,target=/.ccache -e CCACHE_DIR=/.ccache" fi docker run $args $RUN_ARGS "$IMAGE_NAME" bash "$BUILD_SCRIPT" $RUN_OPTS $@ return $? else echo "could not find docker image: $IMAGE_NAME" >&2 return 3 fi }