composer remove (uninstall) all installed packages (composer install rollback) - php

I have a project with the composer.lock file.
I installed packages with the command:
composer install
Now I would like to rollback that composer install command to the state as it was before running it.
How to remove all packages without affecting composer.lock file?
Is there any single composer command to do that?
I tried:
composer remove *
but I got:
[UnexpectedValueException]
"LICENSE" is not a valid alias.
I tried:
composer remove */*
But then I get bunch of print like:
bin/console is not required in your composer.json and has not been removed
Package "bin/console" listed for update is not locked.
Why composer remove * did not work at all? AFAIK the package name as VendorName/PackageName is a common convention for Packagist but not a must (if you use private repos) so how one would be able to remove all packages named IdontHaveAnySlash etc. at once?
I may use someting similar to:
for package in $(composer show | awk '{print $1}'); do composer remove --no-interaction --dev --no-install "$package"; done
But that is not a simple and single composer command.
Also composer often complains about a package being a part (dependency) of another one so composer does not uninstall it.
Removal failed, doctrine/annotations is still present, it may be required by another package. See composer why doctrine/annotations.
As my intention is to rollback to the state that did not have any package installed but only files: composer.lock and potentially composer.json I really don't care about any dependencies, packages versions, downloading repositories' urls etc.
I just want to have a project without any installed dependencies as it was before.
Is there any single composer command to do that?
My:
composer --version
is:
version 2.2.7 2022-02-25 11:12:27
Following yivi answer I created a simple test to verify:
mkdir -p /tmp/composer-install
cd /tmp/composer-install
curl -o composer.json https://raw.githubusercontent.com/composer/composer/18246212db7103d0a2688febcc336f77183275ee/composer.json
curl -o composer.lock https://raw.githubusercontent.com/composer/composer/d955458f271edb4fcc055a394f90a60a8328a2a8/composer.lock
sha1sum composer.json > composer.json.sha1
sha1sum composer.lock > composer.lock.sha1
composer install
sha1sum -c composer.json.sha1
sha1sum -c composer.lock.sha1
that outputs:
composer.json: OK
composer.lock: OK
So both composer.json and composer.lock are not affected by composer install so the only one thing to achieve the rollback (uninstall) of the composer install is to remove the vendor directory
rm -rf vendor
However as yivi mentioned:
If some other plugin (e.g Symfony Flex) makes changes to your existing files during the process, you'd better have the project on top of a version control system, in which case reverting is managed by VCS, not of composer.
I did not test against that case.

rm -rf vendor
In any case, install should not make any changes to a lockfile, so there shouldn't be anything to "revert" from an install but deleting the installed files.
If the lockfile does not originally exist, then it will be created.
If some other plugin (e.g Symfony Flex) makes changes to your existing files during the process, you'd better have the project on top of a version control system, in which case reverting is managed by VCS, not of composer.
As my intention is to rollback to the state that did not have any package installed but only files: composer.lock and potentially composer.json
For you to be able to run composer install at all, you need at the very least composer.json to exist. install reads from the lockfile (composer.lock), but requires the JSON configuration file to exist as well. If the lockfile does not exist, update will be run instead and the lockfile will be created.
I tried composer remove
remove is the opposite from require. It removes packages from composer.json, as require adds them. Not the opposite of install. There is no opposite of install, as it does not make much conceptual sense. If one needs to delete the installed project... one can always do so.

Related

Composer install with only composer.lock

I freshly installed a PHP application given with a composer.lock file.
When running composer install, command line tool is still asking for a composer.json.... I don't have.
In composer documentation, it's said that install command first look for a composer.lock and then for a composer.json.
Why composer is still asking for a file it doesn't need to install my dependencies ?
composer install > returns :
Composer could not find a composer.json file
You still need the composer.json file to install or update any dependencies.
Having a composer.lock file means that composer will not search for the latest commits of the dependencies
A few weeks ago on Twitter, I noticed that the OpenCFP project doesn’t have a composer.lock file in it’s repository. “So what,” you might say, “just composer install and away you go. You’ll get the same dependencies, right?”
Wrong.
The point of the lock file is to record the exact versions that are installed so they can be re-installed. This means that if you have a version spec of 1.* and your co-worker runs composer update which installs 1.2.4, and then commits the composer.lock file, when you composer install, you will also get 1.2.4, even if 1.3.0 has been released. This ensures everybody working on the project has the same exact version.
Source: Composer: It's all about Lock File
You must have a composer.json to install dependencies, because it's the file where dependencies theirself are listed. Refer to the documentation.
composer.lock lists dependencies which has already been installed. The composer looks first into it in order to keep versions consistent.
The (documentation states)[https://getcomposer.org/doc/01-basic-usage.md#installing-with-composer-lock]:
running install when a composer.lock file is present resolves and installs all dependencies that you listed in composer.json, but Composer uses the exact versions listed in composer.lock to ensure that the package versions are consistent for everyone working on your project.
If you have lost your composer.json you can reverse engineering your composer.lock. Open it and read all the packages installed, then create a composer.json which requires them. Not every single package will be a direct dependency for your problem: you should identify and remove those which are not.

What are the differences between composer update and composer install?

What are the differences between composer update and composer install?
composer update
composer update will update your depencencies as they are specified in composer.json
For example, if you require this package as a dependency:
"mockery/mockery": "0.9.*",
and you have actually installed the 0.9.1 version of the package, running composer update will cause an upgrade of this package (for example to 0.9.2, if it's already been released)
in detail composer update will:
Read composer.json
Remove installed packages that are no more required in composer.json
Check the availability of the latest versions of your required packages
Install the latest versions of your packages
Update composer.lock to store the installed packages version
composer install
composer install will not update anything; it will just install all the dependencies as specified in the composer.lock file
In detail:
Check if composer.lock file exists (if not, it will run composer update and create it)
Read composer.lock file
Install the packages specified in the composer.lock file
When to install and when to update
composer update is mostly used in the 'development phase', to upgrade our project packages according to what we have specified in the composer.json file,
composer install is primarily used in the 'deploying phase' to install our application on a production server or on a testing environment, using the same dependencies stored in the composer.lock file created by composer update.
When you run composer install it will look for a lock file and install whatever is contained in it, if it can't find one, it'll read composer.json, install its dependencies and generate a lockfile.
When you run composer update it simply reads composer.json, installs the dependencies and updates the lockfile (or creates a new lockfile).
composer install
If composer.lock does exist.
Processes and installs dependencies from the composer.lock file.
If composer.lock does not exist.
Process package installs from composer.json.
Creates the composer.lock file based on the installed packages.
As per: composer help install:
The install command reads the composer.lock file from the current directory, processes it, and downloads and installs all the libraries and dependencies outlined in that file. If the file does not exist it will look for composer.json and do the same.
composer update
Processes dependencies from the composer.json file (installs, updates and removes).
Creates or updates the composer.lock file according to the changes.
As per: composer help update:
The update command reads the composer.json file from the
current directory, processes it, and updates, removes or installs all the
dependencies.
See also: Composer: It’s All About the Lock File
composer install
if(composer.lock existed){
installs dependency with EXACT version in composer.lock file
} else {
installs dependency with LATEST version in composer.json
generate the composer.lock file
}
composer update
composer update = remove composer.lock -> composer install
Why we need 2 commands. I think it can explain by composer.lock.
Imagine, we DON'T have composer.lock and in composer.json, there is a dependency "monolog/monolog": "1.0.*" or "monolog/monolog": "^1.0".
Then, it will have some cases
We working well today with current dependency version (eg:1.0.0) but a few
months later, the dependency update (eg:1.0.1) and it possible have some bug
Another team member may have a different dependency version if they run composer install in a different time.
What if we always use an EXACT version in composer.json such as "monolog/monolog": "1.0.1"?
We still need composer.lock because composer.json only track the main version of your dependency, it can not track the version of dependencies of dependency.
What if all dependencies of dependency also use the EXACT version?
Imagine you begin with ALL dependencies which use the EXACT version then you don't care about composer.lock. However, a few months later, you add a new dependency (or update old dependency), and the dependencies of this dependency don't use the EXACT version. Then it's better to care composer.lock at the beginning.
Besides that, there is an advantage of a semantic version over an exact version. We may update the dependency many times during development and library often have some small change such as bug fix. Then it is easier to upgrade dependency which uses semantic version.
The best difference between composer update and composer install
composer install
To add dependencies you need to add it manually to the composer.json file.
If composer.lock file exists, install exactly what's specificated on this file
Otherwise read composer.json file to look out what dependencies needs to be installed
Write the composer.lock with the information of the project (installed dependencies)
Not any component will be updated with this command.
composer update
To add or remove dependencies you need to add it manually to the composer.json file
The composer.lock file will be ignored
composer.json file dependencies will be installed and updated (if a dependency is not installed it will be downloaded)
If you can't (or don't know how to add or remove a library which is in fact easy,just add the name of the dependency and version in the require property of the file) modify the composer.json file manually or you prefer use the command line instead, composer has special functions for this :
composer require
For example if we want to add a dependency with the command line we will simply execute
composer require twig/twig
composer.json file will be modified automatically and the new dependency will be added
the dependency will be downloaded to the project
composer remove
If you want to remove an unused dependency we will execute simply :
composer remove twig/twig --update-with-dependencies
Twig will be removed with all his dependencies

Why does composer removes my dependencies on deploy?

I'm having an issue with composer.
I'm working with git in a local environment. I'm the only one developer.
When I need some more dependencies (or need to change some versions), I edit the composer.json and run composer install locally.
Everything's fine.
Then, when everything works locally, I commit my changes (including composer.json and composer.lock) and push to my production server.
A post-receive script updates the sources and runs a composer install on the remote server.
What is expected :
Composer should install the new dependencies according to the composer.lock file.
I should be happy.
What happens :
Composer is angry :
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.
Composer removes all dependencies.
My production is broken.
I have a heart attack
I have to log in to my server via ssh and run a composer update to make things work fine, but I know that a composer update is not recommended on a production server.
Here's the output of the post-receive composer's section :
composer install
Loading composer repositories with package information
Installing dependencies (including require-dev) 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.
- Removing guzzle/guzzle (v3.9.3)
- Removing symfony/event-dispatcher (v2.7.1)
- Removing geoip/geoip (v1.15)
- Removing pimple/pimple (v3.0.0)
- Removing cocur/slugify (1.1.x-dev)
- Removing bentools/url (0.2)
- Removing bentools/simplexmlextended (1.2.0)
Generating autoload files
What am I doing wrong ?
Thanks,
Ben
This warning
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.
occurs when the md5sum of your composer.json differs from the one stored in the composer.lock:
{
"hash": "b15ed9405e8547867f74973ce8add172",
"packages": [ ... ]
}
Make sure your composer.json and composer.lock are identically with your local ones (compare their md5sums). I suspect that something in your deploy chain is not updating them correctly.
Make sure you added your dependencies locally with the require command:
composer require new/package ~2.5
or if composer.json was edited manually at least run
composer update new/package
after that for every additionally added package to ensure that it is added to your composer.lock properly.
Another approach:
run composer update --lock in production. This will update the hash in your lock file but won't upgrade your vendors.
Then run composer install to install the vendors from your comoser.lock.
When I need some more dependencies (or need to change some versions), I edit the composer.json and run composer install locally.
That's wrong. You can edit composer.json and then must run composer update, or you let Composer do the internal editing of the json file and just run composer require new/package (optionally with a version).
Either way, you should end up with a changed composer.json and composer.lock file, commit BOTH into your repository, and the expected outcome is that the lock file will contain all packages in the correct versions, which should be installed in production with a regular composer install run.
Note that your workflow is still very dangerous. If you push, and Github is down - how would you get the ZIPs to install?

Composer loading from cache

I ran into a problem using composer for installing/uninstalling some dependencies in laravel, which come back after deleting them from composer.json and deleting their vendor folder.
I initially used dflydev's markdown package, but now I want to change it to michelf's php-markdown, but I can't uninstall the old one since it comes back loaded from cache. I checked at AppData\Roaming\Composer and it is empty.
Any clue as to why this is happening?
- Installing dflydev/markdown (dev-master dee1f7a)
Loading from cache
You can use the following command to clear the cache irrespective of the OS you are on:
php composer.phar clear-cache
or if composer is installed globally
composer clear-cache
I think, you can run your composer commands with --no-cache option flag like
composer install --no-cache
Or
composer require <package-name> --no-cache
Or
composer update [<package-name>] --no-cache
If you want to clear all packages cache, please try following:
$ composer clearcache
Or to just clear one or a few packages:
$ composer clearcache packagename1 packagename2 ...
You can also use clear-cache which is an alias for clearcache.
Source : https://blog.liplex.de/clear-composer-cache/
composer caches packages under vendor/packagename convention. So you shouldn't run into any issue, just because the packagename is used in another vendor's package.
the cache locations are:
Windows: %LOCALAPPDATA%\Composer\files\vendor\packagename
Linux: ~/.composer/cache/files/vendor/packagename
Mac OS: ~/.composer/cache/files/packagename
Don't edit your composer.json file manually to remove a package - it will remain in composer.lock.
Use composer remove to delete the old package then composer require to install the replacement.
In some cases (for example OpenSuse 42.1) all user cache are puts in:
~/.cache/
For the composer, the same as other applications, the cache path is:
~/.cache/composer/
So, just remove this folder as follow:
rm -fR ~/.cache/composer
run the following command
rm -rf ~/.composer/cache*
if Permission denied add sudo
On Window, I see the composer cache file located in
C:\Users\{your_user}\AppData\Local\Composer\files
It stores ZIP files. The below image has 2 Zip files because I have downloaded 2 versions of monolog (1.0.1 and 1.0.2)
To remove the cache, simply delete the Zip file or folder.
So the only thing that worked for me on my Macbook was removing the package from my composer.json, deleting my composer.lock, running composer update, then adding the package back to composer.json, deleting my composer.lock(again), and running composer update (again). I had a local package in my instance of Laravel Nova that I changed to all lowercase from CamelCase and no matter what I did, it kept adding the package with the old CamelCase name. Didn't matter if I cleared caches or anything.

How to force composer to reinstall a library?

I'm using the ZF2 skeleton app and it has a .gitignore that prevents external libraries from being commited to git. While debugging I like to go and change stuff here and there in the libraries' source to learn how things work. If these were version controlled it would be very easy to revert them back to their original state.
How can I force Composer to reinstall a particular framework so that I can get a fresh -unmodified- copy again?
PS: Please don't suggest removing the .gitignore file since it's there for a reason; it prevents my third party libraries from getting into my app's repository. I can always install them during an automated deployment.
The same applies to Laravel framework: it also gitignores the vendor folder.
First execute composer clearcache
Then clear your vendors folder
rm -rf vendor/*
or better yet just remove the specific module which makes problems to avoid having to download all over again.
You can use the --prefer-source flag for composer to checkout external packages with the VCS information (if any available). You can simply revert to the original state. Also if you issue the composer update command composer will detect any changes you made locally and ask if you want to discard them.
Your .gitignore file is related to your root project (ZF2 skeleton) and it prevents the vendor dir (where your third party libs are) from committing to your own VCS. The ignore file is unrelated to the git repo's of your vendors.
I didn't want to delete all the packages in vendor/ directory, so here is how I did it:
rm -rf vendor/package-i-messed-up
composer install again
What I did:
Deleted that particular library's folder
composer update --prefer-source vendor/library-name
It fetches the library again along with it's git repo
The relevant feature request is https://github.com/composer/composer/issues/3112
In 2021-05 the "reinstall" command patch got merged: https://github.com/composer/composer/pull/9915 - it is available in composer version 2.1.0 and all later ones.
The reinstall command is merged and availabe since 2.1.0:
composer reinstall <package-name> # Removes and installs the package.
Short answer
you can execute it in one cli command with &&:
composer remove vendor/package && composer require vendor/package:version
Detailed answer
Remove existing package by command:
composer remove vendor/package
this will remove folder of package from /vendor, row from composer.json and whole record of package from composer.lock right way with removing not used dependencies and not removing dependencies which used by another packages
Then install preferred one with command:
composer require vendor/package:version
this will install package with desired version right way with adding row to composer.json, adding record to composer.lock and all needed dependent packages
if there would be package which is used in more that one package, Composer
will try to install version which fits all using packages. If it will not resolve this it will crash with corresponding error message
Links
How to install a specific version of package using Composer?
How to remove a package from Laravel using composer?
Install, Uninstall and Update Modules Themes etc with Composer: https://modulesunraveled.com/drupal-8-composer-and-configuration-management/installing-and-uninstalling-modules-composer
Reinstall the dependencies. Remove the vendor folder (manually) or via rm command (if you are in the project folder, sure) on Linux before:
rm -rf vendor/
composer update -v
https://www.dev-metal.com/composer-problems-try-full-reset/
As user #aaracrr pointed out in a comment on another answer probably the best answer is to re-require the package with the same version constraint.
ie.
composer require vendor/package
or specifying a version constraint
composer require vendor/package:^1.0.0
For some reason no one suggested the obvious and the most straight forward way to force re-install:
> composer remove vendor-name/package-name && composer vendor-name/package-name
Be aware that this exact command will install latest version of the package. If you was using old version of the package and package does not have backward compatibility this will brake version compatibility. You might consider backing up your composer.json first.
Since Composer 2.1 you can do
composer reinstall vendor/package
see https://getcomposer.org/doc/03-cli.md#reinstall
In 2022
You can use composer status to list the libraries you changed.
Then composer resinstall vendor/package to overwrite the changes.
This does not change the version of the installed library like the solutions with composer require or composer install.

Categories