The situation
Let's say I have a project with two packages installed by Composer:
php composer.phar require 'squizlabs/php_codesniffer:~2.0' 'phpmd/phpmd:~2.1'
The autogenerated composer.json
file looks like this:
{
"require": {
"squizlabs/php_codesniffer": "~2.0",
"phpmd/phpmd": "~2.1"
}
}
In the autogenerated composer.lock
file, there are the two requested packages:
2.0.0 squizlabs/php_codesniffer
2.1.3 phpmd/phpmd
and also four dependencies of phpmd/phpmd
:
2.0.4 pdepend/pdepend
2.5.9 symfony/config
2.5.9 symfony/dependency-injection
2.5.9 symfony/filesystem
A few days later, squizlabs/php_codesniffer
version 2.1.0
is released, but I don't want to run update
yet. I want to stay on version 2.0.0
for now, and maybe I'll run update
in a few days.
The question
I now want to remove phpmd/phpmd
from my project. I want to achieve the following points:
Delete phpmd/phpmd from composer.json Delete phpmd/phpmd from composer.lock Delete phpmd/phpmd from the vendor folder Delete all the dependencies of phpmd/phpmd from composer.lock Delete all the dependencies of phpmd/phpmd from the vendor folder Do not update squizlabs/php_codesniffer to version 2.1.0
Edit: I'd prefer a solution which doesn't require changing the version constraint of squizlabs/php_codesniffer
in composer.json
What I've tried
If I run:
php composer.phar remove phpmd/phpmd
this achieves points 1, 2, 3, 6, but does not achieve points 4, 5.
The dependencies of phpmd/phpmd
remain in composer.lock
and the vendor
folder.
If I run:
php composer.phar remove phpmd/phpmd
php composer.phar update
this achieves points 1, 2, 3, 4, 5, but does not achieve point 6.
squizlabs/php_codesniffer
gets updated to version 2.1.0
.
Remove the entry from composer.json
then run composer update phpmd/phpmd
.
As to why that is the solution that works. I have no idea but that is what is required to remove a package totally from composer.lock
and /vendor
and allow you to install a new/replacement/conflicting package.
Do this:
php composer.phar remove phpmd/phpmd
Modify the composer.json file so it contains the following require section.
{
"require": {
"squizlabs/php_codesniffer": "2.0.*",
}
}
Now run composer.phar update
. That should get you where you want to be.
Note: You could also pin the php_codesniffer package to a specific version e.g. 2.0.0
. More information about how composer does versioning can be found on here.
squizlabs/php_codesniffer
in composer.json
. Sorry, I should have made this clear in my question. Ideally, I'm looking for something similar to MacPorts' --follow-dependencies
flag for its uninstall
command: "Uninstall ports that were automatically installed as dependencies of the removed port and are no longer needed".
To remove package from .json and .lock files you have to remove package as follows:
composer remove package-name
composer remove
was broken. Updating composer might help.
I found this answer here,
Manually remove the package from composer.json. Manually delete vendor folder. Run composer install (from inside your project folder).
Composer re-installs the packages listed in composer.json.
composer install
would use the lock file and reinstall the remove package
I do not believe this to currently be possible. This is the sort of thing that you may wish to submit as a feature request to Composer.
Meanwhile, I think your best bet is to go with option #1: php composer.phar remove phpmd/phpmd
It will remove the package from your explicit dependencies without forcing you to update anything. The obsolete dependencies from your removed library will remain until you next run composer update
, which is something you should be doing periodically anyway. Most of the files from the old dependencies should be set to autoload one way or another, so you shouldn't have any real penalties for keeping those files around other than the space they use on disk.
Success story sharing