7

I'm confused by Composer's behaviour when I try to update a single package.

Per the docs and Stack Overflow answers like this one, I should be able to update a single package with a command like

composer update somevendor/somepackage

My expectation when I do this is that my vendor folder and composer.lock should be left unmodified with the exception of somevendor/somepackage and its dependencies. However, this is not the case. Instead, I see the hashes of some packages unrelated to the one I am updating change in composer.lock. Indeed, even if I try to update a nonexistent package by mashing the keyboard:

composer update adsfiodfsa/dsafiodsafio

... then even though Composer tells me that there's nothing to update:

$ composer update adsfiodfsa/dsafiodsafio
Package "adsfiodfsa/dsafiodsafio" listed for update is not installed. Ignoring.
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Writing lock file
Generating autoload files
Generating optimized class loader

... I still see that composer.lock has changed! Stranger still, the /vendor folder (which I added to my Git repo for the purpose of testing this) hasn't been modified, even though the lock file seems to be claiming that I have different versions of some packages now:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

    modified:   composer.lock

no changes added to commit (use "git add" and/or "git commit -a")

Is this intended behaviour, or a bug? If it's correct, can someone explain why my composer.lock file is changing despite nothing being updated? In case it helps, running a git diff on my composer.lock after the update (which doesn't modify the vendor folder) yields the following diff, which seems to clearly claim that some packages have changed:

diff --git a/composer.lock b/composer.lock
index e2f65b9..e6c9a95 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1,7 +1,7 @@
 {
     "_readme": [
         "This file locks the dependencies of your project to a known state",
-        "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
     "hash": "3d8098978270f73f9829e9d1138edef9",
@@ -583,7 +583,7 @@
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/dbal/zipball/9e7954694971a5fab6ebabb38f9ffeec49d0d2ad",
+                "url": "https://api.github.com/repos/doctrine/dbal/zipball/a0a43c0eb15ed66e71f8160b6bb25f4071ed22ca",
                 "reference": "9e7954694971a5fab6ebabb38f9ffeec49d0d2ad",
                 "shasum": ""
             },
@@ -879,7 +879,7 @@
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/firebase/firebase-token-generator-php/zipball/61691f56372d32515350dd5522c78be64a0e8d60",
+                "url": "https://api.github.com/repos/firebase/firebase-token-generator-php/zipball/1044f9f5ec8b270dc6c073c7bf2fe67081dbfbb2",
                 "reference": "61691f56372d32515350dd5522c78be64a0e8d60",
                 "shasum": ""
             },
@@ -1076,7 +1076,7 @@
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/RingPHP/zipball/dbbb91d7f6c191e5e405e900e3102ac7f261bc0b",
+                "url": "https://api.github.com/repos/guzzle/RingPHP/zipball/9465032ac5d6beaa55f10923403e6e1c36018d9c",
                 "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b",
                 "shasum": ""
             },
@@ -1425,7 +1425,7 @@
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bf2bff61743f20a13dc46ff1e3bbd0f19c997d2b",
+                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/77aef55318035d37dbd4e87ea0c37a191f3e766e",
                 "reference": "bf2bff61743f20a13dc46ff1e3bbd0f19c997d2b",
                 "shasum": ""
             },
@@ -2027,7 +2027,7 @@
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-fig/log/zipball/bf2c13de4300e227d7b2fd08027673a79c519987",
+                "url": "https://api.github.com/repos/php-fig/log/zipball/9e45edca52cc9c954680072c93e621f8b71fab26",
                 "reference": "bf2c13de4300e227d7b2fd08027673a79c519987",
                 "shasum": ""
             },
@@ -2211,7 +2211,7 @@
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/ac8b475454c120bfb31f5bef475233dd4fb6b626",
+                "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/21b7eb31c51d98e9da0543527a0242875f3d92b9",
                 "reference": "ac8b475454c120bfb31f5bef475233dd4fb6b626",
                 "shasum": ""
             },
@@ -2744,7 +2744,7 @@
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/7b1632cf2bdbc69c59a44942b70d5aae91034304",
+                "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/31652385d94eafc2103a98435d6d5bd7eea61736",
                 "reference": "7b1632cf2bdbc69c59a44942b70d5aae91034304",
                 "shasum": ""
             },
@@ -3405,7 +3405,7 @@
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpspec/phpspec/zipball/73d0335bf8473be8bcfab5a9d66adce8d0db3857",
+                "url": "https://api.github.com/repos/phpspec/phpspec/zipball/147ff359413be67781d1dd1f3be5d7a4d4af769a",
                 "reference": "73d0335bf8473be8bcfab5a9d66adce8d0db3857",
                 "shasum": ""
             },
@@ -3483,7 +3483,7 @@
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373",
+                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/5a355f91730c845301a9e28f91c8a5053353c496",
                 "reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373",
                 "shasum": ""
             },
@@ -3543,7 +3543,7 @@
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9ef4b8cbf3e839a44a9b375d8c59e109ac7aa020",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/688b6a58acb19c1899dc887b1efb6403dc6dc0bd",
                 "reference": "9ef4b8cbf3e839a44a9b375d8c59e109ac7aa020",
                 "shasum": ""
             },
@@ -3861,7 +3861,7 @@
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/74ffb87f527f24616f72460e54b595f508dccb5c",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/5034a3d9f2057a7b7d6ad03a984509dadfdda3cc",
                 "reference": "74ffb87f527f24616f72460e54b595f508dccb5c",
                 "shasum": ""
             },
Community
  • 1
  • 1
Mark Amery
  • 143,130
  • 81
  • 406
  • 459

2 Answers2

1

The readme section would indicate that you have updated your version of composer since the lock file was created causing the basic metadata of the lock to be updated.

The way whitelisting works with in the installer is that each package that is not whitelisted has the constraint updated to the exact version that is installed.

So what is occurring is that every package is technically being considered for installation in the case of missing packages and to properly discover and resolve dependencies of the whitelisted packages. It's as if you temporarily changed your composer.json to have explicit versions declared for every package you did not whitelist and a full update is performed.

When the lock file is regenerated Composer\Package\Locker will iterate over all of the packages that have been considered for installation and pass them to Composer\Package\Dumper\ArrayDumper which will spit out the source and dist metadata for each package to create your output.

When you have packages installed with a hash reference that equates to something along the lines of #9e7954694971a5fab6ebabb38f9ffeec49d0d2ad for the version. As stof points out in composer/composer#1458 the handling of explicit hashes for a version is done at the installer level, and does not know how to generate a proper dist url for it, that is done at the vcs driver level. The metadata being used to create the dist url for the lock file when hashed comes from dev-master which is why the api urls would update.

The installer doesn't use the dist url to install the package, the dist url being used when installing comes from the repository that provides the package in the pool being used by the solver.

Steve Buzonas
  • 5,300
  • 1
  • 33
  • 55
  • https://github.com/composer/composer/issues/1458#issuecomment-18857768 seems very likely to be related to my issue - it similarly shows the dist's `reference` and `url` getting out of sync without an obvious reason - but I confess that as someone with only a basic knowledge of Composer much of your answer - like the distinction between "installer level" and "vcs driver level" - went over my head. – Mark Amery Jun 09 '15 at 21:40
  • I'll add more details in a few. Short answer is the URL isn't important. It gets rebuilt when it's actually installing based on the reference and the class that provides the package. It is confusing and misleading though. – Steve Buzonas Jun 09 '15 at 22:34
  • Is there a best practice or workaround to handle this kind of change with version control? I would rather not commit url updates for packages other than the one I'm updating/installing, but I can't find a way to make composer not make those changes to composer.lock if any vcs packages have new upstream versions. –  Nov 10 '15 at 18:11
  • @tubes the url doesn't actually get locked from an installation perspective. I would say best practice is to disregard the fact that they may get updated in the lock file because it isn't used by anything that really matters. They are generated on the fly at install time based on the repository driver. It is an item that is known and on a list of things to fix because it's confusing. – Steve Buzonas Nov 10 '15 at 23:01
0

Leave looking to complicated solutions and start

composer init 

again.

ganji
  • 752
  • 7
  • 17