#!/usr/bin/env bash # Usage: script/mirror update # script/mirror verify # script/mirror stats set -e eval "$(grep RUBY_BUILD_MIRROR_URL= ./bin/ruby-build | head -1)" help_text() { sed -ne '/^#/!q;s/.\{1,2\}//;1d;p' < "$0" } test_mirrored() { curl -qsSfIL "$RUBY_BUILD_MIRROR_URL/$1" >/dev/null 2>&1 } compute_sha2() { local output="$(openssl dgst -sha256)" echo "${output##* }" | tr '[A-Z]' '[a-z]' } download_package() { curl -qsSfL -o "$2" "$1" } download_and_verify() { local checksum local url="$1" local file="$2" local expected="$3" download_package "$url" "$file" checksum="$(compute_sha2 < "$file")" if [ "$checksum" != "$expected" ]; then echo "Error: $url doesn't match its checksum $expected" >&2 return 1 fi } changed_files() { git diff --name-only --diff-filter=ACMR "$@" } potentially_new_packages() { local files="$(changed_files "$1" -- ./share/ruby-build)" [ -n "$files" ] && extract_urls $files } extract_urls() { $(type -p ggrep grep | head -1) -hoe 'http[^"]\+#[^"]\+' "$@" | sort | uniq } update() { local url local checksum local file for url in $(potentially_new_packages "$1"); do checksum="${url#*#}" url="${url%#*}" if test_mirrored "$checksum"; then echo "Already mirrored: $url" else echo "Mirroring: $url" file="${TMPDIR:-/tmp}/$checksum" download_and_verify "$url" "$file" "$checksum" ./script/s3-put "$file" "${AMAZON_S3_BUCKET?}" fi done } verify() { local url local checksum local file for url in $(potentially_new_packages "$1"); do checksum="${url#*#}" url="${url%#*}" echo "Verifying checksum for $url" file="${TMPDIR:-/tmp}/$checksum" download_and_verify "$url" "$file" "$checksum" done } stats() { local packages=( $(extract_urls ./share/ruby-build/*) ) local total="${#packages[@]}" local confirmed=0 local checksum for url in "${packages[@]}"; do checksum="${url#*#}" if test_mirrored "$checksum"; then confirmed="$((confirmed + 1))" else echo "failed: $url" >&2 fi echo -n "." done echo echo "$confirmed/$total mirrored" } cmd="$1" case "$cmd" in update | verify | stats ) shift 1 "$cmd" "$@" ;; -h | --help ) help_text exit 0 ;; * ) help_text >&2 exit 1 ;; esac