|
1 | 1 | #!/usr/bin/env bash |
2 | 2 | # |
3 | | -# This buildpacks allows to run custom commands on the build dyno. |
4 | | -# |
5 | | -# Example: |
6 | | -# heroku config:set BUILDPACK_RUN='./myexec-1:ls -l:bin/myexec-2 foo bar' |
7 | | -# git push heroku master |
8 | | -# |
9 | | -# The above example runs the following three commands during the build: |
10 | | -# 1. ./myexec-1 |
11 | | -# 2. ls -l |
12 | | -# 3. bin/myexec-2 foo bar |
13 | | -# |
14 | | -# Notes: |
15 | | -# - If BUILDPACK_RUN is unset, then './buildpack-run.sh' is used by default |
16 | | -# - All commands must be executable (i.e. the exec flag must be set) |
17 | | -# - If any command exits with a non-zero code, the build is aborted |
18 | | -# |
19 | | -# --- |
20 | | -# |
21 | 3 | # The 'compile' script is executed by the slug compiler with three arguments: |
22 | | -# $1: build_dir, location of your app directory on the build dyno |
23 | | -# $2: cache_dir, directory on the build dyno that persists between builds |
24 | | -# $3: env_dir, directory holding all the app's config vars as files |
| 4 | +# |
| 5 | +# - $1: build_dir, location of your app directory on the build dyno |
| 6 | +# - $2: cache_dir, directory on the build dyno that persists between builds |
| 7 | +# - $3: env_dir, directory holding all the app's config vars as files |
25 | 8 | # |
26 | 9 | # More information here: https://devcenter.heroku.com/articles/buildpack-api |
27 | 10 | #------------------------------------------------------------------------------# |
28 | 11 |
|
29 | | -# Indent stdin |
30 | | -i() { sed 's/^/ /'; } |
31 | | -a() { sed 's/^/-----> /'; } |
32 | | -I() { sed "s/^/$(printf '\033')[31m /;s/$/$(printf '\033')[0m/"; } |
33 | | -A() { sed "s/^/$(printf '\033')[31m-----> /;s/$/$(printf '\033')[0m/"; } |
34 | | - |
| 12 | +# Indentation |
| 13 | +indent() { sed 's/^/ /'; } |
| 14 | +arrow() { sed 's/^/-----> /'; } |
| 15 | +indent-err() { sed "s/^/$(printf '\033')[31m /;s/$/$(printf '\033')[0m/"; } |
| 16 | +arrow-err() { sed "s/^/$(printf '\033')[31m-----> /;s/$/$(printf '\033')[0m/"; } |
35 | 17 |
|
36 | | -# These environment variables can be accessed from the user-supplied commands |
| 18 | +# Default enviroment variables |
37 | 19 | export BUILD_DIR=$1 |
38 | 20 | export CACHE_DIR=$2 |
39 | 21 | export ENV_DIR=$3 |
40 | 22 |
|
41 | 23 | cd "$BUILD_DIR" |
42 | 24 |
|
43 | | -# Extract commands from BUILDPACK_RUN config variable |
| 25 | +# If BUILDPACK_RUN_LOAD_CONFIG is set, create env vars for all of the app's |
| 26 | +# config vars (except thos specified in BUILDPACK_RUN_LOAD_CONFIG_SKIP). The |
| 27 | +# env vars are not created immediately, but the commands to create them are |
| 28 | +# written to a file, which is then sourced before the user-supplied commands |
| 29 | +# are executed (this is to prevent name clashes between the config vars and |
| 30 | +# env vars used by this script). |
| 31 | +BUILDPACK_RUN_CONFIG_FILE=$(mktemp) |
| 32 | +if [[ -f "$ENV_DIR/BUILDPACK_RUN_LOAD_CONFIG" ]]; then |
| 33 | + echo "Loading config vars into environment" | arrow |
| 34 | + skip='^()$' |
| 35 | + if [[ -f "$ENV_DIR/BUILDPACK_RUN_LOAD_CONFIG_SKIP" ]]; then |
| 36 | + skip="^($(tr ':' '|' <"$ENV_DIR/BUILDPACK_RUN_LOAD_CONFIG_SKIP"))$" |
| 37 | + echo "(except: $(cat "$ENV_DIR/BUILDPACK_RUN_LOAD_CONFIG_SKIP"))" | indent |
| 38 | + fi |
| 39 | + shopt -s nullglob |
| 40 | + for f in "$ENV_DIR"/*; do |
| 41 | + if ! grep -qE "$skip" <<<$(basename "$f"); then |
| 42 | + echo "export $(basename "$f")=\$(cat "$f")" >>"$BUILDPACK_RUN_CONFIG_FILE" |
| 43 | + fi |
| 44 | + done |
| 45 | +fi |
| 46 | + |
| 47 | +# Extract commands from BUILDPACK_RUN config var |
44 | 48 | if [[ -f "$ENV_DIR/BUILDPACK_RUN" ]]; then |
45 | | - COMMANDS=$(cat "$ENV_DIR/BUILDPACK_RUN") |
46 | | -elif [[ -f ./buildpack-run.sh ]]; then |
47 | | - COMMANDS=./buildpack-run.sh |
| 49 | + BUILDPACK_RUN_COMMANDS=$(cat "$ENV_DIR/BUILDPACK_RUN") |
| 50 | +elif [[ -f buildpack-run.sh ]]; then |
| 51 | + BUILDPACK_RUN_COMMANDS=./buildpack-run.sh |
48 | 52 | else |
49 | | - echo "Error: can't apply buildpack." | A |
50 | | - echo "You must specify one ore more colon-delimited commands in" | I |
51 | | - echo "BUILDPACK_RUN or use the default file ./buildpack-run.sh." | I |
52 | | - echo "See https://github.com/weibeld/heroku-buildpack-run#configure." | I |
53 | | - echo |
| 53 | + echo "Error: can't apply buildpack" | arrow-err |
| 54 | + cat <<EOF | indent-err |
| 55 | +You must either create an executable script named buildpack-run.sh |
| 56 | +in the root directory of your app, or specify one or more commands |
| 57 | +to execute in the BUILDPACK_RUN config variable (colon-delimited). |
| 58 | +See https://github.com/weibeld/heroku-buildpack-run#configure |
| 59 | +EOF |
54 | 60 | exit 1 |
55 | 61 | fi |
56 | | -IFS=':' COMMANDS=($COMMANDS) |
| 62 | +IFS=':' BUILDPACK_RUN_COMMANDS=($BUILDPACK_RUN_COMMANDS) |
57 | 63 |
|
58 | 64 | # Run commands |
59 | | -for c in ${COMMANDS[@]}; do |
60 | | - # Test if local file is executable (breaking change from previous version) |
61 | | - file=$(echo "$c" | cut -f 1 -d " ") |
62 | | - if [[ -f "$file" && ! -x "$file" ]]; then |
63 | | - echo "Error: $file is not executable." | A |
64 | | - echo "Make it executable by running 'chmod +x $file'" | I |
65 | | - echo "on your local machine, then commit and push as usual." | I |
| 65 | +for BUILDPACK_RUN_CMD in ${BUILDPACK_RUN_COMMANDS[@]}; do |
| 66 | + echo "Running: $BUILDPACK_RUN_CMD" | arrow |
| 67 | + . "$BUILDPACK_RUN_CONFIG_FILE" |
| 68 | + eval "$BUILDPACK_RUN_CMD" || { |
| 69 | + echo "Aborting: '$BUILDPACK_RUN_CMD' exited with exit code $?" | arrow-err |
66 | 70 | exit 1 |
67 | | - fi |
68 | | - echo "Running: $c" | a |
69 | | - eval "$c" |
70 | | - EXIT_CODE=$? |
71 | | - if [[ "$EXIT_CODE" != 0 ]]; then |
72 | | - echo "Aborting build because '$c' exited with a non-zero code ($EXIT_CODE)" | A |
73 | | - exit 1 |
74 | | - fi |
| 71 | + } |
75 | 72 | done |
76 | | - |
77 | | -exit 0 |
0 commit comments