PHP Composer require dependency if *condition* - composer-php

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?

Related

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

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"
}

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"
}
},

How to write an odd case version constraint for composer?

The constraint that I am interested in is
"require":{ "php": "..."
Is there a way to target php 7.1 for the project packages in composer.json even though I'm running 7.2 when I call composer update/install on the command line?
You can use platform configuration from Composer: https://getcomposer.org/doc/06-config.md#platform
Basically, your composer.json would look like this:
{
"require": {
...
},
"config": {
"platform": {
"php": "7.1"
}
}
}
This will make sure that you install only packages compatible with PHP 7.1, no matter which PHP version you use to actually install the packages.

How not upgrade to Laravel 5.4 when I run composer update

How can I Prevent my application from upgrading to Laravel 5.4 when I run composer update.
Thanks for any assistance.
Simply edit your project's composer.json and set exact version for laravel/laravel component you want to keep, i.e.:
"require": {
"laravel/framework": "5.3.29",
...
},
Alternatively, if you want still to have automatic updates for your current version you can use * (and this is constrain which Laravel uses too):
"require": {
"laravel/framework": "5.3.*",
...
},
See docs on how Composer versions are handled.
If unsure what version of Laravel you are using now, list it with composer:
composer show laravel/*
If you want to work on dev branch of the 5.3 version you should change dependency in your Laravel's composer.json:
"require": {
...
"laravel/framework": "5.3.*#dev",
...
},
where #dev points the development feature branch of 5.3.*.
Inside your composer.json file:
"require": {
"php": ">=5.6.4",
"laravel/framework": "5.3.*"
- your other packages here -
},
Make sure the "laravel/framework": "5.3.*" line is set to version 5.3.* instead of 5.4.*

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