bcmath_compat: can't install on heroku
During an Heroku deployment i get this error :
Your requirements could not be resolved to an installable set of packages.
Problem 1
- don't install phpseclib/bcmath_compat 1.0.3|don't install php 7.3.13
- composer.json/composer.lock requires php 7.3.* -> satisfiable by php[7.3.13].
- Installation request for phpseclib/bcmath_compat 1.0.3 -> satisfiable by phpseclib/bcmath_compat[1.0.3].
The phpseclib/bcmath_compat package is an indirect dependency of laravel/framework via moontoast/math
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 5
- Comments: 53 (19 by maintainers)
Commits related to this issue
- š Patch for heroku https://github.com/phpseclib/bcmath_compat/issues/1 https://github.com/ramsey/uuid/issues/288 — committed to Dosugamea/drinker by Dosugamea 3 years ago
@calvinmuller run
composer require phpseclib/bcmath_compat:1.0.4which locks the version at 1.0.4 which contained the fix (removed in 1.0.5)Here is the Heroku support response :
The issue here is your update of moontoast/math from 1.1.2 to 1.2.1
1.1.2 required ext-bcmath: https://packagist.org/packages/moontoast/math#1.1.2
1.2.1 uses phpseclib/bcmath_compat instead: https://packagist.org/packages/moontoast/math#1.2.1
The issue that follows then is that phpseclib/bcmath_compat via its composer.json metadata provides the ext-bcmath extension, but that extension is marked as replaced (because itās bundled with PHP) by PHP 7.3.13.
A replace is a provide plus a conflict, and thatās why PHP 7.3.13 (with ext-bcmath available as a shared extension) conflicts.
This doesnāt happen on your local machine because dependency resolution works differently there - your regular composer install step is working, but on Heroku, whatās failing is the āplatform installā step that installs PHP and all necessary extensions, not userland dependencies, using a special custom repository and installer, and a composer.json generated from your composer.lock.
I donāt think there is a way to work around this, short of you transitioning to e.g. brick/math (moontoast/math is marked as abandoned), or downgrading to moontoast/math 1.1.2. Iāll put it on the list of things to investigate on our side, but itās a very fundamental aspect of how Composer handles dependencies, and how we have to resolve app requirements, that make it an edge case weāll not likely be able to fix.
Hope this helps, and sorry I donāt have happier news.
Hi.
To clarify whatās going on on Heroku, and why this is failing⦠this is not happening during the regular
composer install, but during the installation of PHP (and extensions). The āmainā installation of app dependencies is not custom, and uses a standard Composer install without proprietary changes.But before that step can even be done, we need PHP installed, and all the right extensions that the app (and its dependencies) require, otherwise
composer installwould immediately fail.To achieve that on Heroku, we parse the appās
composer.lock, extract all packages with platform dependencies (php,ext-foobar, etc), and translate that into a newcomposer.jsonwhere the dependencies are likeheroku-sys/php,heroku-sys/ext-foobar, and so forth).This
composer.jsonis thencomposer installed (against a custom repository, e.g. https://lang-php.s3.amazonaws.com/dist-heroku-18-stable/packages.json and using a custom installer) to install binaries of PHP and any required extensions.The reason itās done this way is that dependency graphs for platform package requirements in a
composer.jsoncan be complex, and the only way to ensure weāre installing the right thing(s) is to mirror the same package structure and requirements as the main project, otherwise weād always run into situations where the latercomposer installfor the app dependencies fails.Example: your project requires
php:*andext-redis:*, that should give you PHP 7.3.latest andext-redis5.latest.But if your project requires
php:*andext-redis:3.*, youāll get PHP 7.2, sinceext-redisv3 is not compatible with 7.3.Multiply that by the number of
phpandext-ā¦requireandconflictrules in all dependentcomposer.jsonfiles, and it should be clear why some hand-written logic that first tries to install the latest PHP 7.3 and then just fails in the next step (when trying to installext-redisv5) would constantly lead to frustration for users - we want agit push heroku masterto ājust workā by figuring out the right set of things to install.Now the issue with
ext-bcmathis that itās built into PHP, and the package manifest for each PHP build (heroku-sys/phppackage) on Heroku containsheroku-sys/ext-bcmathas areplacedeclaration, becauseprovidewould be incorrect - we want to avoid the installation of an āexternalāext-bcmath(e.g. when someone builds one into a custom āplatformā repository for use on Heroku).This is, however, only really a requirement for extensions that are not built as shared (and
ext-bcmathis built as shared). Iāll investigate whether the package definitions could be changed in such a way that shared extensions areprovided instead, but IIRC there was a particular reason (internal to Composer) why we went withreplacefor everything back when this was implemented.Example generated āplatformā
composer.json(from an appāscomposer.lock):Example package definition for PHP 7.3.13 from the custom Heroku repository for platform installation:
As a temporary workaround, you can use Composerās require inline alias feature to force the use of a previous, non-breaking version of moontoast/math.
Simply run the following command at the root of your project:
composer require moontoast/math "1.1.2 as 1.999.999"Pinging @dzuelke. Is this something youāre able to look into, to rule out whether this is a Heroku issue? š
I think what Iāll do is this:
When I get home Iāll tag a new release of bcmath_compat: 1.0.4. In this new release Iāll remove the āprovidesā bit from composer.json. In theory it could break other setups but tbh Laravel Nova is probably accounting for 99% of the usage of this library (altho I have no idea what percentage of Laravel Nova installs are running on Heroku).
Maybe Iāll create a 2.0.0 tag as well wherein the āprovidesā will be included.
Then when I update bcmath_compat to use phpseclib 3.0 Iāll create a 3.0.0 tag and a 4.0.0 tag.
Itās a suboptimal solution but I think itās the most practical one available to us idk.
@dzuelke - great news!
Iāve unpinned the issue and updated the README.md file to remove the Heroku note.
Thanks!
User-land dependency installation on Heroku supports Composer 2, but the installation of the platform packages themselves (PHP, extensions, etc), where the error is occurring, is still performed using Composer 1 at the moment, so this is expected.
Iāve tagged a new release - 1.0.4 - that removes the provides thing from composer.json.
I still stand by my statement that this is a Heroku bug. It sounds like theyāre using a custom Composer setup. If Heroku wants to continue to use their custom Composer setup I think they should do one of the following:
Either way this is not a fix that should live in bcmath_compat but this also seems to me like a bit of a David and Goliath situation, with bcmath_compat being David and Heroku being Goliath, so whatever.
Just to loop back, I decided to cut my losses and revert to a last known good commit. From there, I branched. I then:
Followed by a composer update
I then updated Nova, and Spark, and again ran my composer update. I then pushed to Heroku.
I canāt say for sure why, but it worked so itās possible my issues are related to my commits. If I can come up with a better answer than that, Iāll drop back.
Thanks all again for your help.