|
| 1 | +#!/usr/bin/env sh |
| 2 | +# Adapted from https://github.com/pre-commit/pre-commit/compare/main...artnc:pre-commit:optimize-docker-image-pull |
| 3 | + |
| 4 | +set -eu |
| 5 | + |
| 6 | +# Abort if Docker not found |
| 7 | +if ! command -v docker > /dev/null 2>&1; then |
| 8 | + exit |
| 9 | +fi |
| 10 | +export DOCKER_CLI_HINTS=false |
| 11 | + |
| 12 | +# Collect Docker images provided as arguments |
| 13 | +images="$@" |
| 14 | + |
| 15 | +# Search .pre-commit-config.yaml for more Docker image usages |
| 16 | +if [ -f .pre-commit-config.yaml ]; then |
| 17 | + # Fall back to dockerized yq if yq not found |
| 18 | + if ! command -v yq > /dev/null 2>&1; then |
| 19 | + echo "Local yq not found, using dockerized yq" |
| 20 | + yq() { |
| 21 | + docker run --init --network none --rm -v "${PWD}:/code" -w /code \ |
| 22 | + mikefarah/yq:4.48.1 "$@" |
| 23 | + } |
| 24 | + fi |
| 25 | + |
| 26 | + # Extract image names |
| 27 | + images="${images} $(yq '.repos[].hooks[] | |
| 28 | + # Extract `entry` from hooks with language `docker_image` |
| 29 | + select(.language=="docker_image") | .entry | |
| 30 | +
|
| 31 | + # Remove leading --entrypoint option |
| 32 | + sub("^ *--entrypoint(=| +)[^ ]+ +"; "") | |
| 33 | +
|
| 34 | + # Extract first word as possible image name |
| 35 | + split(" ")[0] | |
| 36 | +
|
| 37 | + # Lightly validate image name |
| 38 | + select(test("^[a-zA-Z0-9][a-zA-Z0-9.:/_-]*$"))' \ |
| 39 | + .pre-commit-config.yaml 2> /dev/null | tr '\n' ' ')" |
| 40 | +fi |
| 41 | + |
| 42 | +# Trim, deduplicate, and sort image list |
| 43 | +images="$(echo "${images}" | tr ' ' '\n' | sort -u | tr '\n' ' ' | xargs)" |
| 44 | + |
| 45 | +# Pull images in parallel |
| 46 | +pids="" |
| 47 | +for image in ${images}; do |
| 48 | + docker pull --quiet "${image}" & |
| 49 | + pids="${pids} $!" |
| 50 | +done |
| 51 | +exit_code=0 |
| 52 | +for pid in ${pids}; do |
| 53 | + if ! wait "${pid}"; then |
| 54 | + exit_code=1 |
| 55 | + fi |
| 56 | +done |
| 57 | +exit "${exit_code}" |
0 commit comments