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
Related
This question already has answers here:
Composer: how can I install another dependency without updating old ones?
(5 answers)
Closed 2 years ago.
I want to install zizaco/entrust package in laravel 5.8, in their github page it was said to include "zizaco/entrust": "5.2.x-dev" in composer.json file and run composer update command. I did so as below and ran composer update command.
"require" : {
"php" : "^7.1.3",
"fideloper/proxy" : "^4.0",
"laravel/framework" : "5.8.*",
"laravel/tinker" : "^1.0",
"laravel/ui" : "^1.2",
"maatwebsite/excel" : "^3.1",
"zizaco/entrust" : "5.2.x-dev"
},
but composer update command updates all packages to latest versions (these packages i included in "require" field as above) when installing zizaco/entrust package. So is if there are some coding faults in latest updated packages then whole site can break. FYI after i run the above command i see local git showing changes in many files in folders under vendor folder, it means that there are some updates in packages right?. so it's recommended that composer install command should be run so that those dependency packages will not be updated to latest versions.
So, in my case after including "zizaco/entrust": "5.2.x-dev" in require field in composer.json as above, if i run composer install then it don't install zizaco/entrust package. Furthermore, if i run composer require zizaco/entrust 5.2.x-dev then it still installs latest versions of dependency packages.
So how do i prevent installing latest versions of dependency packages i included in "require" field in composer.json file and i only install zizaco/entrust package.
So that my laravel 5.8 site don't break for updating any packages to latest versions because of malfunction codes or whatever in latest versions. It's very important to handle this scenario because we need to install packages in laravel site for various needs.
You've got two options: use composer require to specify the package to install, or manually update your composer.json file and use composer update [package].
Composer Require
composer require zizaco/entrust:5.2.x-dev
This will automatically update your composer.json file and install the specified version. This will not update any of your other dependencies. While the documentation specifies the package and version should be separated by a colon (:), I tested it with a space and it seemed to work.
Composer Update [package]
composer update zizaco/entrust
If you have manually updated your composer.json file, you will need to run composer update and specify the package to update. If you specify a package to update, only that package will be affected. When you don't specify the package to update, composer will look for updates for all packages.
A Note On Composer Install
composer install will not help you here. If you already have a composer.lock file (which you will since you're just attempting to add a new package), composer install will only look at your composer.lock file and attempt to install everything that is defined there. That means, if you manually update your composer.json file, and run composer install, it will not install the new requirement you specified.
Only when you don't already have a composer.lock file will composer install attempt to resolve dependencies and install them.
Run composer install instead. Alternatively you could use composer require <package name>.
Composer install looks in your composer.lock for exact versions, and only in composer.json for packages that are missing.
Composer update will look in composer.json for version constraint which roughly means "a range of versions". This is why different versions are getting installed.
Step 1:
You just need to add your package to the composer.json file and run the command:
composer install
composer install will check for the new package and install that, besides that it will check for any deprecation in other packages.
Step 2:
You can directly run your command in composer
composer require package/name
For example, if I need to install firebase, run below command from the project root:
composer require firebase/php-jwt
Installing new packages from the terminal automatically adds it into the composer.json file and it does not update previously installed packages.
Hope this helps!!
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.
I thought the workflow with composer was like this:
Define your dependencies and other data in your composer.json
Run composer install or later composer update
Include composer.json and composer.lock in your versioned repository
After cloning your repository, run composer install and you're ready
But, at step 4, when I clone my repository to the remote server and run composer install I am getting an error
[ErrorException]
Undefined index: hash
A quick search says that I have to delete my composer.lock, which is up to date with my local repository. So, what am I doing wrong ? Isn't composer.lock there to make sure that both my repositories have the same versions on the included dependencies ? I don't feel like it should be excluded from my repository ...
UPDATE
And I see frameworks like OctoberCMS to include composer.lock into their .gitignore. I'm really confused, composer's documentation clearly states that the composer.lock is the one that actually locks your dependencies to the same version, composer.json is just the guidelines on what version to pick.
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?
After removing a dependency from composer.json and running install or update, should I expect the files to be removed automatically from disk?
I had to remove them manually, not sure if I am supposed to.
Running a composer update will remove packages you removed from your composer.json.
Since install uses composer.lock instead of composer.json it will not remove packages removed from your composer.json. However, you should get a message that your lock file is out of sync with your composer.json and you should run an update.