Composer hook to fix package version - php

I need to hook in composer installation process to fix versions of second level dependencies of root package. I.e. my package depends on some packages (with correct versions) but these packages depends on other packages and its versions are "wrong". I try to use pre-package-install hook to patch such versions but it is not working for me, code inside Installer::prePackageInstall is not executed.
Root package composer.json looks like this:
{
"name": "***/root-package",
"repositories": [ { "type": "composer", "url": "http://***/packages.json" } ],
"require": {
"***/first-level-dep-1": "dev-release-XX",
"***/first-level-dep-2": "dev-release-XX"
},
"scripts": {
"pre-package-install": [
"root-package\\Installer::prePackageInstall"
]
}
}
First level dependency composer.json looks like this:
{
"name": "***/first-level-dep-1",
"repositories": [ { "type": "composer", "url": "http://***/packages.json" } ],
"require": {
"***/second-level-dep-1": "*", // !!! here is my problem
"***/second-level-dep-2": "*"
}
}
I need to replace * to appropriate version during installation process.

You don't have to "fix" that version. You should simply add that second-level-dep as your own dependency in the correct version, and the case is solved.
If the first-level-dependency requires ANY version of that package, then YOU depending on the correct version will restrict the installable versions to the one you allow.

Related

Load two custom libraries

I have some problem by using Composer to load a custom library from another custom library
I have 2 custom libraries called "ia/audit_trail" and "ia/flash". And "ia/audit_trail" needs "ia/flash" to work.
audit_trail : https://github.com/pierrererot/audit_trail
flash : https://github.com/pierrererot/flash
So, I have the require property set for calling another one. Nothing special, BUT, when I run a simple composer update -vvv in my main project, I got this error :
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Installation request for ia/audit_trail_component ~1.0.0 -> satisfiable by ia/audit_trail_component[1.0.0].
- ia/audit_trail_component 1.0.0 requires ia/flash_component ~1.0.0 -> no matching package found.
Potential causes:
- A typo in the package name
- The package is not available in a stable-enough version according to your minimum-stability setting
see https://getcomposer.org/doc/04-schema.md#minimum-stability for more details.
- It's a private package and you forgot to add a custom repository to find it
Read https://getcomposer.org/doc/articles/troubleshooting.md for further common problems...
BUT, if I put these two librairies directly into my main project (so if one librairy doesn't need another librairy), it works !.
Here is the composer.json of my main project :
{
"require": {
"ia/audit_trail_component": "1.0.0"
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/pierrererot/audit_trail.git"
}
]
}
All right. So I did require my custom "audit_trail" library. So now, here is the composer.json of my custom "audit_trail" library :
{
"name": "ia/audit_trail_component",
"version": "1.0.0",
"type": "library",
"require": {
"ia/flash_component": "1.0.0"
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/pierrererot/flash.git"
}
],
"minimum-stability": "dev"
}
All right. So I did require my custom "flash" library. And then, here is the composer.json of my custom "flash" library :
{
"name": "ia/flash_component",
"version": "1.0.0",
"description": "Flash Component",
"type": "library",
"minimum-stability": "dev"
}
As you can see, everything seems ok in my composer files, so I don't understand what I missed.
==> Does anyone have a clue please ?
Before you ask, I precise these things :
Both libraries have a "dev" and a "master" branch pushed on their Git repositories
Both libraries have a minimum 1.0.0 tag pushed on their Git repositories
repositories setting is root-only - Composer will ignore this setting for all dependencies and use only these repositories defined in your main project.
Repositories are only available to the root package and the repositories defined in your dependencies will not be loaded. Read the FAQ entry if you want to learn why.
https://getcomposer.org/doc/05-repositories.md#repository
So you need add all necessary repositories into composer.json of your main project:
"repositories": [
{
"type": "vcs",
"url": "https://github.com/pierrererot/audit_trail.git"
},
{
"type": "vcs",
"url": "https://github.com/pierrererot/flash.git"
}
],

How to patch a Composer library? [duplicate]

This is my composer.json, I want to use Nodge's fork of lessphp project on Github
"repositories": [{
"type": "package",
"package": {
"version": "dev-master",
"name": "nodge/lessphp",
"source": {
"url": "https://github.com/Nodge/lessphp.git",
"type": "git",
"reference": "master"
},
"autoload": {
"classmap": ["lessc.inc.php"]
}
}
}],
"require": {
"php": ">=5.3.3",
"nodge/lessphp": "dev-master"
},
But I get this error when I run composer update:
nodge/lessphp dev-master -> no matching package found.
I don't know how to require correctly this fork.
The most common (and easiest) way of doing it is using a VCS repository.
All you have to do is add your fork as a repository and update the
version constraint to point to your custom branch. Your custom branch
name must be prefixed with dev-.
Assuming you forked monolog/monolog and created a branch called bugfix, you would update your composer.json like this:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/igorw/monolog"
}
],
"require": {
"monolog/monolog": "dev-bugfix"
}
}
Note that you don't change the require statement except to specify your bugfix branch. You still reference the upstream package (monolog/monolog), not your personal fork (igorw/monolog), and the branch name is prefixed with dev-. You can read details in the docs
Using VCS works:
"name": "test/test",
"repositories": [{
"type": "vcs",
"url": "http://github.com/Nodge/lessphp"
}],
"require": {
"leafo/lessphp": "dev-master"
},
But if I require a module that has this composer.json, it doesn't work. It installs the original project, not the fork.
Example
"name": "example/example",
"require": {
"test/test": "dev-master"
},
I should mention again the repository. Is that normal?
If you can't get #Neilime answer to work for you, make sure your fork uses a different branch.
For example push your changes to a branch on your fork called my-bugfix, do not added dev- prefix in your branch name but in your composer.json you have to add it. Your composer file will look like:
"repositories":
[
{
"type": "vcs",
"url": "http://github.com/yourname/packageName"
}
],
"require": {
"owner/packageName": "dev-my-bugfix"
},
I have tried many options but After I got this post I saw the light and it just worked perfect.
This is what you have to do:
1- Fork The repository
2- Create a branch and make the required modifications.
3- Add the repository label to your composer.json
"repositories": [
{
"type": "vcs",
"url": "https://github.com/user/yourforkname"
}
]
4- In the command line inside your project require your fork like this:
composer require vendor/packagename:dev-branchname
And Voilá!!
You have your fork version working
According to the Composer documentation
http://getcomposer.org/doc/05-repositories.md#vcs, it's enough to
specify the original repository (not the fork) in the require ("nodge/lessphp" in your case). Composer will then install YOUR fork (look at the code in the vendors)
So, this is 2019, and most of the answers here are already correct.
If you find yourself however, in a situation where you need to require a particular branch of your fork (that you created), have composer list the available versions/tags first.
This saved me a lot of time.
A full example with spatie/laravel-backup package.
First, add repositories key to composer.json. With the url of your fork
"repositories": [{
"type": "vcs",
"url": "https://github.com/holymp2006/laravel-backup"
}]
Get available versions/tags
composer show "spatie/laravel-backup" --all
Choose the version you want from versions in the terminal output, then require that version
composer require spatie/laravel-backup:v5.x-dev
I usually add a "dist" node to the package definition.
I never had a problem using it this way.
I can't remember where I got this trick from, though, for any further explanations.
{
"repositories": [
{
"type": "package",
"package": {
"version": "dev-master",
"name": "nodge/lessphp",
"source": {
"url": "https://github.com/Nodge/lessphp.git",
"type": "git",
"reference": "master"
},
"autoload": {
"classmap": ["lessc.inc.php"]
},
"dist": {
"url": "https://github.com/Nodge/lessphp/archive/master.zip",
"type": "zip"
}
}
}
],
"require": {
"nodge/lessphp": "*"
}
}
The accepted answer and clarifying answers all worked well for me when I had ex. an application, which needed a dependency I had forked and modified. I’d still use the accepted answer in this case.
However, when I had a package I wanted to distribute myself on Packagist, which also contained a forked and modified dependency, this approach no longer worked.
If someone were to try and install with this config, they’ll still get that same -> no matching package found. error message.
This answer and the linked Composer docs suggest that the repo settings have to be at the top-level composer.json. That means, someone installing this package would have to add that config to their composer.json file too—which adds a lot of unnecessary confusion to the install process.
Instead, I published my fork to Packagist. My understanding is that while forks are frowned upon, this would be considered a maintained fork, since I am using it for this new package.
Hopefully that’s helpful for anyone who has this problem with a package or library they’d like to distribute.

composer is ignoring installer-paths configuration

I'm try using CakePHP for the first time with composer, but I have some problems.
I have this composer.json:
{
"name": "example.com.br",
"repositories": [
{
"type": "pear",
"url": "http://pear.cakephp.org"
}
],
"config": {
"vendor-dir": "Vendor/"
},
"require": {
"php": ">=5.4",
"pear-cakephp/cakephp": ">=2.4.3",
"cakephp/debug_kit": "2.2.*",
"smottt/wideimage": "dev-master"
},
"extra": {
"installer-paths": {
"app/Plugin/DebugKit": ["cakephp/debug_kit"],
"app/Vendor/Wideimage": ["smottt/wideimage"]
}
}
}
When I run composer install (or update) --prefer-dist, everything works except smottt/wideimage.
This package is being installed in the /Vendor folder instead /app/Vendor, so, installer-paths was ignored.
Of course, what Danack has said is true: the composer-installers plugin only supports a select list of package types.
In response to that, I have written an extension for the composer-installers plugin which allows any arbitrary package type to be handled by the "installer-paths" directive.
Simply require oomphinc/composer-installers-extender in your composer.json and add support for any additional arbitrary package types:
"extra": {
"installer-types": ["library"],
"installer-paths": {
"special/package/": ["my/package"],
"path/to/libraries/{$name}/": ["type:library"]
}
}
For packages that don't specify a type, use the default type library.
From the documentation.
You cannot use this to change the path of any package. This is only
applicable to packages that require composer/installers and use a
custom type that it handles.
From one of the packages you're installing:
{
"name": "smottt/wideimage",
"description": "An open-source PHP library for image manipulation. (With namespaces, PHP 5.3+)",
"homepage": "http://wideimage.sourceforge.net",
"type": "library",
"license": ["GPL-2.0","LGPL-2.1"],
"version": "11.02.19",
"autoload": {
"psr-0" : {
"WideImage" : "lib/"
}
}
}
So basically the package you're trying to install doesn't support custom install paths.
Use option "script" of composer (work only with linux) :
"scripts": {
"post-install-cmd": [
"php -r \"system('mv '.getcwd().'/Vendor/smottt/wideimage '.getcwd().'/Vendor/Wideimage');\""
]
}
Add your custom types to the installer-types:
{
"installer-types": ["library", "myttype-1", "mytype-2"]
}
https://packagist.org/packages/oomphinc/composer-installers-extender

Load vendor dependencies with composer.json

I have recently forked robmorgan/phinx project and modified the composer.json file in my project to use the forked version:
{
"name": "...",
"description": "...",
"repositories": [
{
"type": "package",
"package": {
"name": "lube8uy/phinx",
"version": "master",
"source": {
"url": "https://github.com/lube8uy/phinx.git",
"type": "git",
"reference": "master"
}
}
}
],
"require": {
"php": ">=5.3.0",
"lube8uy/phinx": "dev-master"
}
}
First question: additional vendors
Now, when I load the composer.json file in my project I get this forked version correctly.
What I don't know is how to load the dependencies from the phinx project itself:
https://github.com/lube8uy/phinx/blob/master/composer.json
If I use the original packagist source everything works fine and I got all the dependencies, but now that I use my own repository I can't get them.
Second question: updates
How can I receive the modifications I made to my github source?
I made some modifications, pushed them to the correct branch, then I run composer update but nothing was updated... what am I doing wrong?
Thank you very much
For your first question:
Try to require it as a VCS repository (Version Control System, see composer doc on vcs repositories), like the following:
{
"name": "...",
"description": "...",
"repositories": [
{
"type": "vcs",
"url": "https://github.com/lube8uy/phinx"
}
],
"require": {
"php": ">=5.3.0",
"robmorgan/phinx": "dev-master"
}
}
It now requires the package robmorgan/phinx which is found at https://github.com/lube8uy/phinx which is the desired fork. It still has the original name robmorgan/phinx but is found at a different location.
It still has the same name because of the package name in its composer.json. If you want to change the name to lube8ye/phinx, change it in the composer.json in the fork.
For your second question:
The changes made in a package you require via composer should be updated automatically when you execute php composer.phar update in your project. If this does not work, try to force composer to require a specific commit by adding the commit hash after dev-master in your require section like so:
"require": {
"robmorgan/phinx": "dev-master#1234abcd"
}
Whereat 1234abcd is the hash of the desired commit.
Also: Try clearing composer's cache by deleting the folders content to avoid loading a cached version (see composer doc on COMPOSER_CACHE_DIR)

How to require a fork with composer?

This is my composer.json, I want to use Nodge's fork of lessphp project on Github
"repositories": [{
"type": "package",
"package": {
"version": "dev-master",
"name": "nodge/lessphp",
"source": {
"url": "https://github.com/Nodge/lessphp.git",
"type": "git",
"reference": "master"
},
"autoload": {
"classmap": ["lessc.inc.php"]
}
}
}],
"require": {
"php": ">=5.3.3",
"nodge/lessphp": "dev-master"
},
But I get this error when I run composer update:
nodge/lessphp dev-master -> no matching package found.
I don't know how to require correctly this fork.
The most common (and easiest) way of doing it is using a VCS repository.
All you have to do is add your fork as a repository and update the
version constraint to point to your custom branch. Your custom branch
name must be prefixed with dev-.
Assuming you forked monolog/monolog and created a branch called bugfix, you would update your composer.json like this:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/igorw/monolog"
}
],
"require": {
"monolog/monolog": "dev-bugfix"
}
}
Note that you don't change the require statement except to specify your bugfix branch. You still reference the upstream package (monolog/monolog), not your personal fork (igorw/monolog), and the branch name is prefixed with dev-. You can read details in the docs
Using VCS works:
"name": "test/test",
"repositories": [{
"type": "vcs",
"url": "http://github.com/Nodge/lessphp"
}],
"require": {
"leafo/lessphp": "dev-master"
},
But if I require a module that has this composer.json, it doesn't work. It installs the original project, not the fork.
Example
"name": "example/example",
"require": {
"test/test": "dev-master"
},
I should mention again the repository. Is that normal?
If you can't get #Neilime answer to work for you, make sure your fork uses a different branch.
For example push your changes to a branch on your fork called my-bugfix, do not added dev- prefix in your branch name but in your composer.json you have to add it. Your composer file will look like:
"repositories":
[
{
"type": "vcs",
"url": "http://github.com/yourname/packageName"
}
],
"require": {
"owner/packageName": "dev-my-bugfix"
},
I have tried many options but After I got this post I saw the light and it just worked perfect.
This is what you have to do:
1- Fork The repository
2- Create a branch and make the required modifications.
3- Add the repository label to your composer.json
"repositories": [
{
"type": "vcs",
"url": "https://github.com/user/yourforkname"
}
]
4- In the command line inside your project require your fork like this:
composer require vendor/packagename:dev-branchname
And Voilá!!
You have your fork version working
According to the Composer documentation
http://getcomposer.org/doc/05-repositories.md#vcs, it's enough to
specify the original repository (not the fork) in the require ("nodge/lessphp" in your case). Composer will then install YOUR fork (look at the code in the vendors)
So, this is 2019, and most of the answers here are already correct.
If you find yourself however, in a situation where you need to require a particular branch of your fork (that you created), have composer list the available versions/tags first.
This saved me a lot of time.
A full example with spatie/laravel-backup package.
First, add repositories key to composer.json. With the url of your fork
"repositories": [{
"type": "vcs",
"url": "https://github.com/holymp2006/laravel-backup"
}]
Get available versions/tags
composer show "spatie/laravel-backup" --all
Choose the version you want from versions in the terminal output, then require that version
composer require spatie/laravel-backup:v5.x-dev
I usually add a "dist" node to the package definition.
I never had a problem using it this way.
I can't remember where I got this trick from, though, for any further explanations.
{
"repositories": [
{
"type": "package",
"package": {
"version": "dev-master",
"name": "nodge/lessphp",
"source": {
"url": "https://github.com/Nodge/lessphp.git",
"type": "git",
"reference": "master"
},
"autoload": {
"classmap": ["lessc.inc.php"]
},
"dist": {
"url": "https://github.com/Nodge/lessphp/archive/master.zip",
"type": "zip"
}
}
}
],
"require": {
"nodge/lessphp": "*"
}
}
The accepted answer and clarifying answers all worked well for me when I had ex. an application, which needed a dependency I had forked and modified. I’d still use the accepted answer in this case.
However, when I had a package I wanted to distribute myself on Packagist, which also contained a forked and modified dependency, this approach no longer worked.
If someone were to try and install with this config, they’ll still get that same -> no matching package found. error message.
This answer and the linked Composer docs suggest that the repo settings have to be at the top-level composer.json. That means, someone installing this package would have to add that config to their composer.json file too—which adds a lot of unnecessary confusion to the install process.
Instead, I published my fork to Packagist. My understanding is that while forks are frowned upon, this would be considered a maintained fork, since I am using it for this new package.
Hopefully that’s helpful for anyone who has this problem with a package or library they’d like to distribute.

Categories