Do not update a specific package - composer-php

Is there a way to tell composer that each time I do a composer update I want him to ignore a specific package?

Have you considered specifying the required version for the package you are trying to ignore? For instance:
"require": {
"some/package": "~1.2"
}
This may get updated, because you are saying any version >=1.2,<2.0, But if you strictly say you want only version 1.0, you should not see any updates to that package:
"require": {
"some/package": "1.2"
}

Actually I don't know if there is any way to tell composer to exclude one specific package from updating but you can tell which packages to update as
composer update <package> <package2>; // or
php composer.phar update <package> <package2>;
For example,
composer update foo/package1 bar/package2; // or
php composer.phar update foo/package1 bar/package2;
Also, I think, if you don't list them in composer.json (remove after installation) by yourself, then they will not be updated unless also specified in the list.
From Composer:
If you only want to install or update one dependency, you can whitelist them:
$ php composer.phar update monolog/monolog [...]
Check this link and also check Composer.
Update : (found on internet but not tested)
To do that, just remove the package from composer.lock

Update: Only availble for composer versions 1.0.0-alpha6 and lower. Using it in version 1.0.0-alpha7 and higher will remove all packages in "require-dev".
I believe currently you can trick composer with some mess if you can afford it in your project. Something like: Put all packages you don't want to update in "require-dev" and run updates with composer update --no-dev
Just be careful of that if you run composer install as i recall they will be removed from your project.
All this trickery is really nasty, so we should wait for official way of doing things like that, personally i update packages explicitly specifying them

To ignore a specific package, you can use provide (if it's part of your own package) or replace. This tells Composer that you wish to provide/replace a specific package, so it won't download it.
Here is the composer.json file example which should work:
{
"require": {
"radic/tmp-underscore-php": "~1.2.0"
},
"replace": {
"patchwork/utf8": "*"
}
}
In this example, the patchwork/utf8 package would be ignored on composer install or update.
To exclude specific version, see: Composer exclude specific versions.

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

Remove a package using composer (without updating other packages)

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

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: how can I install another dependency without updating old ones?

I have a project with a few dependencies and I'd like to install another one, but I'd like to keep the others the way they are. So I've edited the composer.json, but if I run composer install, I get the following output:
Installing dependencies from lock file
Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.
Your requirements could not be resolved to an installable set of packages.
Problem 1
- laravel/framework dev-master requires ext-mcrypt * -> the requested PHP extension mcrypt is missing from your system.
- laravel/framework dev-master requires ext-mcrypt * -> the requested PHP extension mcrypt is missing from your system.
- Installation request for laravel/framework dev-master -> satisfiable by laravel/framework dev-master.
First of all, I do have mcrypt installed, so I don't know why it's complaining about that there.
So, how can I install this new dependency?
My composer.json:
{
"require": {
"opauth/opauth": "*",
"opauth/facebook": "*",
"opauth/google": "*",
"opauth/twitter": "*",
"imagine/Imagine": "dev-develop",
"laravel/framework": "4.*",
"loic-sharma/profiler": "dev-master"
},
"autoload": {
"classmap": [
"app/libraries",
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/tests/TestCase.php"
]
},
"minimum-stability": "dev"
}
To install a new package and only that, you have two options:
Using the require command, just run:
composer require new/package
Composer will guess the best version constraint to use, install the package, and add it to composer.lock.
You can also specify an explicit version constraint by running:
composer require new/package ~2.5
–OR–
Using the update command, add the new package manually to composer.json, then run:
composer update new/package
If Composer complains, stating "Your requirements could not be resolved to an installable set of packages.", you can resolve this by passing the flag --with-dependencies. This will whitelist all dependencies of the package you are trying to install/update (but none of your other dependencies).
Regarding the question asker's issues with Laravel and mcrypt: check that it's properly enabled in your CLI php.ini. If php -m doesn't list mcrypt then it's missing.
Important: Don't forget to specify new/package when using composer update! Omitting that argument will cause all dependencies, as well as composer.lock, to be updated.
Actually, the correct solution is:
composer require vendor/package
Taken from the CLI documentation for Composer:
The require command adds new packages to the composer.json file from the current directory.
php composer.phar require
After adding/changing the requirements, the modified requirements will be installed or updated.
If you do not want to choose requirements interactively, you can just pass them to the command.
php composer.phar require vendor/package:2.* vendor/package2:dev-master
While it is true that composer update installs new packages found in composer.json, it will also update the composer.lock file and any installed packages according to any fuzzy logic (> or * chars after the colons) found in composer.json! This can be avoided by using composer update vendor/package, but I wouldn't recommend making a habit of it, as you're one forgotten argument away from a potentially broken project…
Keep things sane and stick with composer require vendor/package for adding new dependencies! 😉
We can install a new package without updating other dependencies like this:
composer require package/name --no-update
this will add your package to composer.json (no update to composer.lock)
composer update package/name
this will now install/update your new package, adding it to composer.lock without updating other deps
My use case is simpler, and fits simply your title but not your further detail.
That is, I want to install a new package which is not yet in my composer.json without updating all the other packages.
The solution here is composer require x/y
In my case, I had a repo with:
requirements A,B,C,D in .json
but only A,B,C in the .lock
In the meantime, A,B,C had newer versions with respect when the lock was generated.
For some reason, I deleted the "vendors" and wanted to do a composer install and failed with the message:
Warning: The lock file is not up to date with the latest changes in composer.json.
You may be getting outdated dependencies. Run update to update them.
Your requirements could not be resolved to an installable set of packages.
I tried to run the solution from Seldaek issuing a composer update vendorD/libraryD but composer insisted to update more things, so .lock had too changes seen my my git tool.
The solution I used was:
Delete all the vendors dir.
Temporarily remove the requirement VendorD/LibraryD from the .json.
run composer install.
Then delete the file .json and checkout it again from the repo (equivalent to re-adding the file, but avoiding potential whitespace changes).
Then run Seldaek's solution composer update vendorD/libraryD
It did install the library, but in addition, git diff showed me that in the .lock only the new things were added without editing the other ones.
(Thnx Seldaek for the pointer ;) )

Resources