77

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:

  1. Delete phpmd/phpmd from composer.json
  2. Delete phpmd/phpmd from composer.lock
  3. Delete phpmd/phpmd from the vendor folder
  4. Delete all the dependencies of phpmd/phpmd from composer.lock
  5. Delete all the dependencies of phpmd/phpmd from the vendor folder
  6. 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.

TachyonVortex
  • 8,242
  • 3
  • 48
  • 63
  • See http://stackoverflow.com/questions/26930816/how-to-remove-unused-dependencies-from-composer – Lode Oct 17 '16 at 12:50
  • Does this answer your question? [How to remove unused dependencies from composer?](https://stackoverflow.com/questions/26930816/how-to-remove-unused-dependencies-from-composer) – PhoneixS Nov 19 '21 at 10:57

5 Answers5

63

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.

kzap
  • 1,411
  • 13
  • 20
  • 1
    Ty a lot , it seems composer is full of hacks, sometimes id doesn't let me upgradem but lets remove+install. In mu case your cure works like a charm – Konstantin Ivanov Aug 10 '17 at 13:12
  • could you set this answer as solution? – webfacer May 28 '19 at 18:53
  • 1
    Is not any kind of hack. "composer update" updates the lock according to the set json then installs the packages etc. The fact that you specify a package means that only that package will be modified in lock. This is actually a basic usage and specified in docs (https://getcomposer.org/doc/01-basic-usage.md). – zozo Sep 11 '19 at 09:09
18

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.

Kevin G.
  • 585
  • 3
  • 5
  • Thank you for your answer. This does indeed achieve what I want. However, if possible, I'd prefer a solution which doesn't require changing the version constraint of `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`](https://guide.macports.org/chunked/using.html#using.port.uninstall) command: "Uninstall ports that were automatically installed as dependencies of the removed port and are no longer needed". – TachyonVortex Jan 16 '15 at 10:01
  • 1
    Theres a --update-with-dependencies flag. Maybe this is what you are looking for – Doug Amos Aug 19 '15 at 10:39
5

I found this answer here,

  1. Manually remove the package from composer.json.
  2. Manually delete vendor folder.
  3. Run composer install (from inside your project folder).

Composer re-installs the packages listed in composer.json.

JimB814
  • 510
  • 8
  • 24
4

To remove package from .json and .lock files you have to remove package as follows:

composer remove package-name
Lauris Kuznecovs
  • 819
  • 1
  • 12
  • 14
  • 15
    The question explicitly specified that this does not lead to the desired behavior. Could you elaborate why you think this does work? – Chris Aug 02 '18 at 09:22
  • This solution works fine for me - Laravel 6.0. No need to remove anything else from the json file nor the lock file. – Inigo EC Dec 19 '19 at 10:40
  • 1
    apparently there was a bug in composer where `composer remove` was broken. Updating composer might help. – cephei_vv Feb 05 '20 at 06:20
0

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.

Michael Cordingley
  • 1,485
  • 1
  • 11
  • 23