-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
composer
executable file
·113 lines (94 loc) · 5.04 KB
/
composer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/usr/bin/env bash
# fail hard
set -o pipefail
# fail harder
set -eu
source $(dirname $BASH_SOURCE)/_util/include/manifest.sh
OUT_PREFIX=$1
dep_formula=${0#$WORKSPACE_DIR/}
dep_name=$(basename $BASH_SOURCE)
dep_version=${dep_formula#"${dep_name}-"}
dep_package=${dep_name}-${dep_version}
dep_manifest=${dep_package}.composer.json
echo "-----> Bundling Composer (${dep_version})..."
export PATH=${OUT_PREFIX}/bin:$PATH
EXPECTED_SIGNATURE=$(wget -q -O - https://composer.github.io/installer.sig)
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', 'composer-setup.php');")
if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]; then
>&2 echo 'ERROR: Invalid installer signature'
rm composer-setup.php
exit 1
fi
php composer-setup.php --version=${dep_version}
# work around https://github.com/composer/composer/issues/11046
echo '{}' > composer.json
plugin_api_version=$(php composer.phar show --platform | grep 'composer-plugin-api' | awk '{print $2}')
# php is in there, so clear it first
rm -rf ${OUT_PREFIX}/*
mkdir -p ${OUT_PREFIX}/bin
mv composer.phar ${OUT_PREFIX}/bin/composer
# a few reasonable defaults for Composer (use available memory, always mirror path repos because of FS boundaries during build, always run non-interactively)
tee ${OUT_PREFIX}/bin/export.composer.sh > ${OUT_PREFIX}/bin/profile.composer.sh <<-'EOF'
mlib="/sys/fs/cgroup/memory/memory.limit_in_bytes"
if [[ -f "$mlib" ]]; then
export COMPOSER_MEMORY_LIMIT=${COMPOSER_MEMORY_LIMIT:-$(cat "$mlib")}
fi
export COMPOSER_MIRROR_PATH_REPOS=${COMPOSER_MIRROR_PATH_REPOS:-1}
export COMPOSER_NO_INTERACTION=${COMPOSER_NO_INTERACTION:-1}
EOF
# this gets sourced after package install, so that the buildpack and following buildpacks can invoke
# composer bin-dir goes last to avoid any conflicts
# we use --no-plugins just in case the vendor dir is there, see e.g. https://github.com/Ocramius/PackageVersions/issues/64
cat >> ${OUT_PREFIX}/bin/export.composer.sh <<-'EOF'
export PATH="/app/.heroku/php/bin:$PATH"
# now composer is on the path
# the export script is called with /app as the cwd, but the app source with composer.json is in another location
# we need to cd to the dirname of realpath 'composer' first to find the actual location of the app during the build:
# - we know 'composer' is on $PATH in /app/.heroku/php/bin
# - we know /app/.heroku/php is a symlink to the build dir
# - we $(dirname $(realpath 'composer')) to get $build_dir/.heroku/php/bin/
# - then we cd up three times (from .heroku/php/bin, from .heroku/php, from .heroku) so we're in the build dir
# - then we invoke 'composer config bin-dir' in there and realpath that so it's absolute
# no scan dir so no newrelic starts up and outputs messages etc
# we need to use --canonicalize-missing, otherwise we'd have to mkdir -p the bin-dir (it's not there yet when we source export early on in bin/compile)
export PATH="$PATH:$(cd "$(dirname "$(realpath "$(which composer)")")"; cd ../../..; bin_dir="$(PHP_INI_SCAN_DIR= COMPOSER_AUTH= composer config --no-plugins bin-dir)"; realpath --canonicalize-missing "$bin_dir")"
EOF
# this gets sourced on dyno boot
# unlimited Composer process timeout only for runtime, not build time
# composer bin-dir goes last to avoid any conflicts
# we use --no-plugins just in case the vendor dir is there, see e.g. https://github.com/Ocramius/PackageVersions/issues/64
cat >> ${OUT_PREFIX}/bin/profile.composer.sh <<-'EOF'
export COMPOSER_PROCESS_TIMEOUT=${COMPOSER_PROCESS_TIMEOUT:-0}
export PATH="$HOME/.heroku/php/bin:$PATH"
# now composer is on the path
# no scan dir so no newrelic starts up and outputs messages etc
# re-set COMPOSER_AUTH to ensure a malformed `heroku config:set` will not cause immediate outage
export PATH="$PATH:$(realpath "$(PHP_INI_SCAN_DIR= COMPOSER_AUTH= composer config --no-plugins bin-dir)")"
EOF
# Composer 2.3+ requires 7.2.5+
if [[ $dep_version == 1.* || $dep_version == 2.[012].* ]]; then
phpreq=">=5.3.2"
else
phpreq=">=7.2.5"
fi
# the || true (needs to be there, not before the <<-'HEREDOC') prevents 'set -e' induced termination from the 'read' encountering EOF
read -r -d '' require <<-EOF || true
{
"heroku-sys/php": "${phpreq}",
"heroku-sys/ext-filter": "*",
"heroku-sys/ext-hash": "*",
"heroku-sys/ext-iconv": "*",
"heroku-sys/ext-json": "*",
"heroku-sys/ext-phar": "*",
"heroku-sys/ext-openssl": "*",
"heroku-sys/ext-zlib": "*"
}
EOF
MANIFEST_REQUIRE="${MANIFEST_REQUIRE:-"$require"}"
MANIFEST_CONFLICT="${MANIFEST_CONFLICT:-"{}"}"
MANIFEST_REPLACE="${MANIFEST_REPLACE:-"{}"}"
MANIFEST_PROVIDE="${MANIFEST_PROVIDE:-"{\"heroku-sys/composer-plugin-api\":\"${plugin_api_version}\"}"}"
MANIFEST_EXTRA="${MANIFEST_EXTRA:-"{\"export\":\"bin/export.composer.sh\",\"profile\":\"bin/profile.composer.sh\"}"}"
python $(dirname $BASH_SOURCE)/_util/include/manifest.py "heroku-sys-program" "heroku-sys/${dep_name}" "$dep_version" "${dep_formula}.tar.gz" "$MANIFEST_REQUIRE" "$MANIFEST_CONFLICT" "$MANIFEST_REPLACE" "$MANIFEST_PROVIDE" "$MANIFEST_EXTRA" > $dep_manifest
print_or_export_manifest_cmd "$(generate_manifest_cmd "$dep_manifest")"