Skip to content

Commit

Permalink
require runtime platform requirement in require if require-dev has one
Browse files Browse the repository at this point in the history
  • Loading branch information
dzuelke committed Nov 23, 2016
1 parent 1dc7b82 commit 8c83457
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

- ext-blackfire/1.14.1 [David Zuelke]

### CHG

- composer.json "require" or dependencies must now contain a runtime version requirement if "require-dev" or dependencies contain one [David Zuelke]

## v114 (2016-11-10)

### ADD
Expand Down
7 changes: 4 additions & 3 deletions bin/compile
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,10 @@ echo "export PATH=\$HOME/.heroku/php/bin:\$PATH:\$HOME/$composer_bindir" > $buil
status "Installing platform packages..."

# extract requirements from composer.lock
/app/.heroku/php-min/bin/php $bp_dir/bin/util/platform.php "$bp_dir/support/installer/" $HEROKU_PHP_PLATFORM_REPOSITORIES 2>&1 >$build_dir/.heroku/php/composer.json | indent || error "Couldn't parse '$COMPOSER_LOCK'; it must be a valid lock
file generated by Composer. Run 'composer update', add/commit
the change, then push again."
/app/.heroku/php-min/bin/php $bp_dir/bin/util/platform.php "$bp_dir/support/installer/" $HEROKU_PHP_PLATFORM_REPOSITORIES 2>&1 >$build_dir/.heroku/php/composer.json | indent || error "Couldn't load '$COMPOSER_LOCK'; it must be a valid lock
file generated by Composer and be in a consistent state.
Check above for any parse errors and address them if necessary.
Run 'composer update', add/commit the change, then push again."

# reset COMPOSER for the platform install step
COMPOSER_bak="$COMPOSER"
Expand Down
13 changes: 11 additions & 2 deletions bin/util/platform.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ function mkmetas($package, array &$metapaks, &$have_runtime_req = false) {
if(!is_array($json)) exit(1);

$have_runtime_req = false;
$have_dev_runtime_req = false;
$require = [];
$requireDev = [];
if(file_exists($COMPOSER_LOCK)) {
Expand All @@ -56,6 +57,7 @@ function mkmetas($package, array &$metapaks, &$have_runtime_req = false) {
if(!$lock || !isset($lock["platform"], $lock["platform-dev"], $lock["packages"], $lock["packages-dev"])) exit(1);
if(!isset($lock["content-hash"]) && !isset($lock["hash"])) exit(1);
$have_runtime_req |= hasreq($lock["platform"]);
$have_dev_runtime_req |= hasreq($lock["platform-dev"]);
// for each package that has platform requirements we build a meta-package that we then depend on
// we cannot simply join all those requirements together with " " or "," because of the precedence of the "|" operator: requirements "5.*," and "^5.3.9|^7.0", which should lead to a PHP 5 install, would combine into "5.*,^5.3.9|^7.0" (there is no way to group requirements), and that would give PHP 7
$metapaks = [];
Expand Down Expand Up @@ -95,7 +97,7 @@ function mkmetas($package, array &$metapaks, &$have_runtime_req = false) {
}
// collect platform requirements from dev packages in lock file
foreach($lock["packages-dev"] as $package) {
if(mkmetas($package, $metapaks)) {
if(mkmetas($package, $metapaks, $have_dev_runtime_req)) {
$requireDev[$package["name"]] = $package["version"];
}
}
Expand All @@ -105,7 +107,14 @@ function mkmetas($package, array &$metapaks, &$have_runtime_req = false) {
}

// if no PHP or HHVM is required anywhere, we need to add something
if(!$have_runtime_req) { // FIXME: this may break things if only root require-dev contains a PHP requirement that conflicts with the default
if(!$have_runtime_req) {
if($have_dev_runtime_req) {
// there is no requirement for a PHP or HHVM version in "require", nor in any dependencies therein, but there is one in "require-dev"
// that's problematic, because requirements in there may effectively result in a rule like "7.0.*", but we'd next write "^5.5.17" into our "require" to have a sane default, and that'd blow up in CI where dev dependenies are installed
// we can't compute a resulting version rule (that's the whole point of the custom installer that uses Composer's solver), so throwing an error is the best thing we can do here
file_put_contents("php://stderr", "ERROR: neither your $COMPOSER 'require' section nor any\ndependency therein requires a runtime version, but 'require-dev'\nor a dependency therein does. Heroku cannot automatically select\na default runtime version in this case.\nPlease add a version requirement for 'php' to section 'require'\nin $COMPOSER, 'composer update', commit, and deploy again.");
exit(3);
}
file_put_contents("php://stderr", "NOTICE: No runtime required in $COMPOSER_LOCK; using PHP ". ($require["heroku-sys/php"] = "^5.5.17") . "\n");
} elseif(!isset($root["require"]["php"]) && !isset($root["require"]["hhvm"])) {
file_put_contents("php://stderr", "NOTICE: No runtime required in $COMPOSER; requirements\nfrom dependencies in $COMPOSER_LOCK will be used for selection\n");
Expand Down

0 comments on commit 8c83457

Please sign in to comment.