#!/usr/bin/env bash
#
# Workaround an issue with bitbucket pipeline's cache system not retaining
# mtime of cached files. This in turn breaks cargo's incremental build system
# which appears to be based on the mtime of its output files. Without this
# workaround, caching the './target/' directory is useless.
#
# We workaround the issue by packing the './target/' directory as a tarball
# file after a successful wrapped operation. Immediatly before the wrapped
# operation, when the cache tarball exists and the './target/' directory does
# not, we merely unpack our tarball.
#
# We than just rely on bitbucket's caching system to compress and cache our
# resulting tarball instead of './target/'.
#
# Note that contrary to bitbucket's broken caching system, tarballs do preserve
# mtime.
#
# Also note that for some reason, bitbucket's caching system is unable to work
# with plain files (such as our tarball) which forces us to create a directory
# with our tarball within.
#
# More details at:
# <https://community.atlassian.com/t5/Bitbucket-discussions/Pipelines-cache-does-not-retain-original-file-modification-time/td-p/1833749>
#
set -euf -o pipefail
repo_root="$(cd "$(dirname "$0")/../.." && pwd)"
work_dir="${WORK_DIR:-$repo_root}"
set -v

rel_cached_dir="target"
cache_dir="${CARGO_TARGET_CACHE_DIR:-"$work_dir/.ci/.cache/cargo-target"}"
cache_tarball="$cache_dir/content.tar"

if [[ -e "$cache_tarball" ]] && ! [[ -e "$work_dir/$rel_cached_dir" ]]; then
  printf "Unpacking '%s' into './%s/'.\n" \
    "$cache_tarball" "$rel_cached_dir"
  (cd "$work_dir" && tar -xf "$cache_tarball" "$rel_cached_dir")
fi

echo "$@"
"$@"

if [[ -e "$work_dir/$rel_cached_dir" ]]; then
  printf "Packing './%s/' cache into '%s'.\n" \
    "$rel_cached_dir" "$cache_tarball"
  mkdir -p "$cache_dir"
  (cd "$work_dir" && tar -cf "$cache_tarball" "$rel_cached_dir")
fi
