How to composer install using a package's composer.lock file? - composer-php

If I have:
a fresh project
no composer.lock
composer.json like the following
{
"name": "fresh",
"type": "library",
"require": {
"consolidation/robo": "3.0.3"
}
}
Then run composer install
It will install consolidation/robo and update the consolidation/robo internal dependencies instead of using the consolidation/robo internal composer.lock to get a known working version of the library.
How do to get composer install to use https://github.com/consolidation/robo/blob/3.0.3/composer.lock when installing consolidation/robo dependencies instead of running the equivalent of composer update on consolidation/robo?
Currently, it's retrieving a broken internal dependency and I have to outline it in my root composer.json which internal dependency should be retrieved. Where as the https://github.com/consolidation/robo/blob/3.0.3/composer.lock has the working version of the library.

That's the way composer is supposed to work.
Lockfiles for dependencies are ignored, that's by design. If the package you are using has broken version constraints (e.g. it says its compatible with ^2.1 of foo/bar, but in reality was only tested with versions >= 2.1.0 && <= 2.2.2, and installing version 2.3 of foo/bar breaks), it's either becuse foo/bar broke the semver promise, or because the package you depend on was not adequately tested.
What you can do is simply add in your root composer.json:
{
"conflict":
"foo/bar": ">=2.3"
}

Related

How to constraint compatibility with PHP without explicitly constraint all the depending packages

I got this requirement in my composer.json:
"php": ">= 5.6",
"symfony/http-foundation": "^3.0"
The problem with that configuration is that it will install paragonie/random_compat v9.99.99 which is only compatible with PHP 7 and more. But the thing is that I don't want my composer.lock file to require PHP 7, I want it to still be compatible with PHP 5.6.
The solution I found is to track down which package was pulling this dependency and, once I found it, I added this to my requirements:
"paragonie/random_compat": "~2.0"
But I wonder if there is not a better way of doing that: somehow telling that I accept all the versions above PHP 5.6, but I don't accept packages that would force to have PHP 7?
If you want to make composer.lock compatible with PHP 5.6, you have at least two options to achieve that:
Use PHP 5.6 for composer update - you should be able to install multiple versions of PHP on your OS and run Composer like this:
/path/to/php6.5 /path/to/composer update
Use platform settings in composer.json to force installation for specific version regardless PHP version used to run Composer commands:
"config": {
"platform": {
"php": "5.6.38"
}
},

PHP Composer require dependency if *condition*

Is there any way to require a dependency in composer.json only if a condition is fulfilled?
Typically, I'd like to use Guzzle 6 if the PHP version is high enough, otherwise do nothing. The library will handle a fallback if you don't have guzzle.
I know you can use "some/dependency": "^1.0 || ^2.0", which will choose the latest major that fits your other requirements. What I'm looking for is something like:
"some/dependency": "nothing || ^2.0"
You cannot do this directly as constraints in your composer.json. However you can achieve this by creating bridge package, which may define different dependencies for different versions, which could have different requirements.
So you can create me/guzzle-wrapper package and:
Tag 1.0.0 version with composer.json:
{
"name": "me/guzzle-wrapper",
"require": {
"php": "<5.5",
}
}
Tag 2.0.0 version with composer.json:
{
"name": "me/guzzle-wrapper",
"require": {
"php": ">=5.5",
"guzzlehttp/guzzle": "^6.3"
}
}
So instead requiring guzzlehttp/guzzle directly, you can use this meta package - depending on your PHP version Composer will install 2.0.0 which requires Guzzle, or 1.0.0 which does not require anything.
But if your package is able to work without Guzzle, maybe you should move this requirement to suggest section?

Can't install module using composer on Magento 2.1

I am trying to install M2ePro module on my Magento ver. 2.1.8 application using composer and getting this error:
[http]$ php-7.0 /usr/local/bin/composer require m2e/ebay-amazon-magento2
Could not find a matching version of package m2e/ebay-amazon-magento2.
Check the package spelling, your version constraint and that the
package is available in a stability which matches your
minimum-stability (alpha).
The spelling of the package is correct, I have tried defining the version of the module (The only one available is 1.3.2):
[http]$ php-7.0 /usr/local/bin/composer require m2e/ebay-amazon-magento2:1.3.2
However get the same error so I believe stability of this module is "Beta" and I have "minimum-stability (alpha)" set so beta modules should be installed with no problems.?
I looked for solution in composer docs but could find anything about installing beta: https://getcomposer.org/doc/03-cli.md#require
Or was I looking in the wrong place?
I managed to successfully install the module on my development site and didn't receive this error so I thought it might be due to the fact that my Magento application was in the "Production" mode but setting the mode to "Developer" did not solve my problem.
UPDATE:
I just found this thread: https://magento.stackexchange.com/questions/114393/error-in-using-composer-to-install-a-module-in-magento-2-0. The answer to this question is that you need to define the package as repository. The package is from marketplace and this is content of my composer.json:
"minimum-stability": "alpha",
"prefer-stable": true,
"repositories": [
{
"type": "composer",
"url": "https://repo.magento.com/"
}
],
I have previously installed modules from marketplace using composer with no problems.
It came out that my auth.json had incorrect credentials and couldn't find the account.
Correcting the account settings fixed my problem.

Should extension shims be avoided in Composer?

Let's say I have some code in a package that requires ext-oauth to handle OAuth signature generation.
{
"name":"vendor/my-package",
"type":"library",
"require":{
"ext-oauth":"*"
}
}
When I try to install this package on a system that doesn't have the extension, Composer raises an error, as expected.
$ composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
- The requested PHP extension ext-oauth * is missing from your system. Install or enable PHP's oauth extension.
Clearly the ext-oauth package is missing on this system, checking via composer show --platform confirms this.
Assume the system can't be updated to include the extension, virtualization (via Docker or Vagrant) also isn't an option. Would hacking around it by using a package that provides the ext-oauth extension or require'ng a package from packagist be a reasonable solution?
This synthetic test appears to work.
{
"name":"vendor/my-package",
"type":"library",
"require":{
"vendor/ext-oauth":"1.0",
"ext-oauth":"*"
},
"repositories":[
{
"type":"package",
"package":{
"name":"vendor/ext-oauth",
"version":"1.0",
"dist":{
"url":"https://example.com/ext-oauth.zip",
"type":"zip"
},
"provide":{
"ext-oauth":"1.0"
},
"autoload":[
"files":[
"src/oauth.php",
"src/oauthexception.php"
]
]
}
}
]
}
Composer then downloads the provided shim and installs it, marking the ext-oauth dependency as met.
$ composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Installing vendor/ext-oauth (1.0): Downloading (100%)
Writing lock file
Generating autoload files
This feels wrong, but appears to accomplish satisfying the dependency in a maintainable way. Is there a good reason - other than code smell - to avoid providing this sort of shim when PHP extensions can't be installed?

composer not downloading latest composer.json from github?

Here's my projects composer.json:
{
"require": {
"phpseclib/phpseclib": "0.3.x"
}
}
Here's phpseclib's composer.json:
https://github.com/phpseclib/phpseclib/blob/master/composer.json
Note how that file has in it this line:
"System": "phpseclib/"
When I do cat vendor/phpseclib/phpseclib/composer.json I don't see that line. Why not?
You have told Composer to download the latest tagged version of "phpseclib/phpseclib" that matches "0.3.x".
First - there is no version tagged since they added "System": "phpseclib/" so Composer isn't downloading it. You should set the required version to be dev-master if you want to get the absolutely latest version.
Second - I don't think 0.3.x isn't a valid semver version. Did you mean 0.3.* or the equivalent ~0.3 ?

Resources