#!/usr/bin/env bash # SPDX-License-Identifier: Apache-2.0 # Copyright (C) 2021 Arm Limited or its affiliates and Contributors. All rights reserved. [[ "$TRACE" ]] && set -x set -euo pipefail shopt -s extglob print_help() { echo 'Usage: elfshaker-store-all [FIND] <(git-list-between | ...)' echo '' echo 'Stores the directories read in on the standard input as snapshots. ' echo 'This command will REMOVE ALL files in the elfshaker repository (except the repository data)!' echo '' echo 'Each line of the input should consist of two tokens: [DIR] [SNAPSHOT]. ' echo 'The contents of each directory will be copied to the elfshaker repository and stored by elfshaker store SNAPSHOT. ' echo '' echo 'The FIND argument is a shell command that will be executed. The output of the execution will ' echo 'be passed to elfshaker store in the --files-from option.' echo '' echo 'Example:' echo "elfshaker-store-all 'find . -name *.o' <(git-list-between 01/01/2020 02/01/2020 | awk '{print" '"/path/to/builds/"$1 $2'"}')" } main() { if [ ! -d 'elfshaker_data' ]; then echo 'Not an elfshaker repository!' exit 1 fi REPO="$(realpath .)" while read -r DIR TAG; do rm -r !('elfshaker_data') || true echo "Processing $DIR..." FILES="$(mktemp)" (cd "$DIR" && bash <<< "$1") > "$FILES" # mkdir and cp do not perform the check-if-exists and create-dir # operations as a single transaction on the filesystem and fail if the # directory happens to be created after the check but before the call to # mkdir(3). We run mkdir sequentially to avoid this problem and only # then we can run cp --parents concurrently and safely. xargs -a "$FILES" dirname | sort | uniq | xargs mkdir -p (cd "$DIR" && xargs -a "$FILES" -P8 -I{} cp --reflink=auto -a --parents {} "$REPO") elfshaker store "$TAG" --verbose rm "$FILES" done } case "${1:--h}" in -h | --help) print_help [ $# -ne 0 ] exit $? ;; *) main "$@" ;; esac