#!/usr/bin/env bash egrep-q() { egrep "$@" >/dev/null 2>/dev/null } die() { echo 'pre-commit hook failure' 1>&2 echo '-----------------------' 1>&2 echo '' 1>&2 echo "$@" 1>&2 exit 1 } ExternalData_stage_linked_content() { # Identify the hash algorithm used. case "$file" in *.md5) algo=MD5 ; base="${file/.md5}" ; validate="^[0-9a-fA-F]{32}$" ;; *) die "$file: invalid content link (unrecognized extension)" ;; esac # Load and validate the hash stored in the staged blob. hash=$(git cat-file blob $dst_obj) || hash="" echo "$hash" | egrep-q "$validate" || die "$file: invalid content link (does not match '$validate')" # Reject simultaneous raw file and content link. files=$(git ls-files -- "$base") if test -n "$files"; then die "$file: content link may not coexist with $files" fi # Find the content referenced by the link. staged="$(dirname "$file")/.ExternalData_${algo}_${hash}" stored="${ExternalData_STORE}/$algo/$hash" ref="refs/data/$algo/$hash" obj=$(git rev-parse --verify -q "$ref") || obj="" if test -z "$obj" -a -f "$staged"; then # Content is staged by the ExternalData module. Store it in Git. obj=$(git hash-object --no-filters -w -- "$staged") || die "$file: git hash-object failed to load $staged" git update-ref "$ref" "$obj" "" || die "$file: git update-ref failed to create $ref = $obj" echo "$file: Added content to Git at $ref" fi # Move staged object to local store if it is in Git. if test -f "$staged" && test -n "$obj"; then mkdir -p "${stored%/*}" && mv "$staged" "$stored" && rm -f "$staged" && echo "$file: Added content to local store at $stored" fi # Report destination of content link. if test -f "$stored"; then echo "Content link $file -> $stored" else echo "Content link $file -> (object not in local store)" fi } ExternalData_non_content_link() { # Reject simultaneous raw file and content link. files=$(git ls-files -- "$file.md5") if test -n "$files"; then die "$file: file may not coexist with $files" fi } #----------------------------------------------------------------------------- # Check that developmer setup is up-to-date. lastSetupForDevelopment=$(git config --get hooks.SetupForDevelopment || echo 0) eval $(grep '^SetupForDevelopment_VERSION=' "${BASH_SOURCE%/*}/../SetupForDevelopment.sh") test -n "$SetupForDevelopment_VERSION" || SetupForDevelopment_VERSION=0 if test $lastSetupForDevelopment -lt $SetupForDevelopment_VERSION; then die 'Developer setup in this work tree is out of date. Please re-run Utilities/SetupForDevelopment.sh ' fi #----------------------------------------------------------------------------- # Local ExternalData object repository. ExternalData_STORE=".ExternalData" # Process content links created by/for the CMake ExternalData module. git diff-index --cached HEAD --diff-filter=AM | while read src_mode dst_mode src_obj dst_obj status file; do if echo "$dst_mode $file" | egrep-q '^100644 .*\.(md5)$'; then ExternalData_stage_linked_content else ExternalData_non_content_link fi done || exit 1