Remove a package using composer (without updating other packages) - laravel

I've currently installed a package "watson/sitemap". Now, I want to remove it without using "composer update" since it will update other packages which I don't want.
Any help would be much appreciated.

UPDATE: Composer 2 is now out, and it seems to be smart enough to handle the recursion. You need only remove the offending package.
I recently needed to do this. Here's a real-world example. This is pretty hacky. You could script this by using Composer's PHP classes or by parsing the composer.lock file, but this is a manual process you can follow.
1. Remove the unwanted package(s)
composer remove --no-update illuminate/mail
composer update illuminate/mail
2. Look for orphaned dependencies
composer show -N | xargs -n 1 composer why | grep "There is no installed package"
Output (something like this):
There is no installed package depending on "erusev/parsedown"
There is no installed package depending on "swiftmailer/swiftmailer"
There is no installed package depending on "tijsverkoyen/css-to-inline-styles"
3. Remove orphaned dependencies
composer update erusev/parsedown swiftmailer/swiftmailer tijsverkoyen/css-to-inline-styles
4. Rinse, repeat
Repeat steps 2 and 3 until you've found all the orphans.
Clarification: If you use the --no-update flag, you won't upgrade packages... however (as of writing, early 2020) it also does not remove orphaned dependencies. You're not telling it not to "upgrade". You're telling it not to update any of the installed (composer.lock) dependencies. Big difference. This is why you have to find them and manually "update" them out of your project.

Right way:
composer remove watson/sitemap --no-update
From CLI Docs:
The remove command removes packages from the composer.json file from
the current directory.
php composer.phar remove vendor/package vendor/package2
After removing the requirements, the modified requirements will be
uninstalled.
Hack way:
Remove the entry from composer.json then run
composer update watson/sitemap
This will remove a package totally from composer.lock and /vendor

I'm not sure this is possible. To restate your question. You have watson/sitemap in your composer.json, you've executed a composer update to download the package and it's dependencies. Now you want to remove the package but leave dependent packages in place?
I'm not sure there's a good way to do this, you'll have to run composer update at some point, which will just download it again. If my interpretation is correct, maybe your solution is to just add the other packages that you need that you don't want removed when you get rid of watson/sitemap, possibly sloppy/paste it's dependencies into your composer.json file?

I use
composer remove package-name --no-update-with-dependencies
Works imho

Related

Is there a way to composer require without actually pulling the package?

Is there a way to composer require some/thing without actually pulling the package? In my workflow, it would hasten things if I knew a command to just check version requirements and update composer.json without actually doing anything with regard to the vendor directory.
You can use --no-update switch to avoid updating and installing new dependencies - it will only add new dependency to composer.json.
composer require --no-update symfony/symfony
But since require does not check if required package can be installed (it always pick the newest version compatible with your PHP as a constraint, without checking if it will be possible to install), this can leave composer.json in non-installable state.
It will also not update composer.lock so composer install may ignore your new dependency. So this is probably a bad idea unless you want to do something with it before you commit new composer.json.
You may try to use --dry-run switch to test what will happen after composer update - you will be able to check if composer.json is installable, but composer.lock still will be out of date.
composer update --dry-run

composer is not removing entry from composer.lock

I've used following command to remove a package using composer.
composer remove sjparkinson/static-review
Above command removes entry from composer.json file but composer.lock file still contains entry for mentioned library in require section.
What is the proper way to update composer.lock ? Should I update it manually?
Composer does not removing this package, because it is required by another dependency. So even if you don't require it directly, it is still required by your project, so you cannot remove it. You can use composer why some-vendor/some-package command to check what is the reason to keep this package installed:
composer why sjparkinson/static-review
magento/product-community-edition 2.2.4 requires sjparkinson/static-review (~4.1)
If you really want to remove this package, you need to remove magento/product-community-edition too (and every dependency, which depends on this package).
BTW: Editing composer.lock manually is really bad idea, you should never do that.

composer - install new package without updating other packages

I added a package in the require block of my composer.json.
I do a composer install and it says Nothing to install or update.
In my understanding, composer update would work but I shouldn't do that because it updates the versions of the other packages to the latest, but I haven't tested my code on them.
How do I install that new package?
The Command Line.
You don't have to add the new packages manually to your composer.json file and then do a composer install or update. Use The Command Line
Installing new packages from the command line automatically adds it to your composer.json file and it does not update previously installed packages.
From the project root, simply run:
composer require package/name
Hope it helps
For future readers, if you have already added package(s) to your require block in composer.json, it's as simple as listing them all after the update command to exclude existing packages from being updated. First, simulate update to ensure you're happy with the result:
composer update --dry-run vendor/project vendor2/project2
If okay, run it again with the --dry-run argument removed.
You can see the output of updating new/specific packages is different from that of:
composer update --dry-run
Your composer.lock file should be on version control or otherwise backed up so you can restore it & revert all packages in the event of failure.
Using composer require will also update other dependencies.
We can install a new package without updating anything else like this:
composer require package/name --no-update
this will add your package to composer.json, leaving composer.lock intact.
composer update package/name
this will now install/update your new package, adding it to composer.lock. This will not update any other dependencies.

Installing only new packages from composer.json

I'm trying to make composer update only newly added packages to composer.json i.e when I manually add a package dependency to the composer.json file, it should update the composer.lock file only for the new package; the rest of the packages should be at the same version as before. I tried running composer update --lock but I don't think it does what I'm trying to achieve and it took a lot of time to finish. I checked the commands on composer's documentation but can't find one to achieve my wish. Any advice or workaround will be appreciated.
Note: I'm using Laravel Forge, so there is a 2 minutes deployment limit.
In order to install only new packages with composer you should run
composer install
Because composer update will install your new packages but will update and all the other already installed packages.
You can specify the name of the package as an argument to the update command. This will perform a partial update: composer update the-package/you-want-to-update
I think your question is related to your (guessed) current workflow: To add a new package you edit the composer.json file and then run composer update - wishing to only add/update that new file.
If that is true, here is the solution:
composer require new/package will add the newest possible version (taking into account the currently installed packages) of the new package. Benefits: Only one command line, and no fiddling with JSON content.
If you already know which version you want, you could also run composer require new/package:^2.1.25#beta (or whatever version and stability level you want - this example is exaggerating a bit). If this version is incompatible with existing packages, nothing will get installed, everything will get rolled back, and you get an error message.

composer update ignore deps

How can i tell composer to ignore certain deps while running update?
I know i can update certain packages with:
php composer.phar update vendor/package vendor/package2
But i would like to have it the other way around by telling composer to update all except these packages.
In my case the command would be much shorter than the above, since i just want to ignore some experimental bundle.
And i dont want to delete it fully, which would probably happen, if I clear the bundle from the require list.
I think this is not possible by now.
However you can try to shorten the explicit update calls with wildcards:
php composer.phar update doctrine/*
As described here: http://getcomposer.org/doc/03-cli.md#update
But composer will ask you if you want to keep local changes if composer detects such.
The package has modified files:
D code/controller/yourFile.php
Discard changes [y,n,v,s,?]?
Also you can use the stash/apply mechanism for git repos which is featured in composer.
https://github.com/composer/composer/pull/1188
Also helpful:
Composer: Develop directly in vendor packages
Maybe it wasn't possible at that time, but nowadays you can do it like this
composer update --ignore-platform-reqs vendor/package

Resources