Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read or reverse-engineer composer.lock file?

I've inherited a project that was built with PHP 5.3.x, Symfony2, and Composer for dependency management.

The composer.json file has lots of lines like this: "vendorname/library" : "dev-master" for the version of the libraries in use. It was last edited in August of 2012, and clearly worked then since the composer.lock file exists and the project is running on a server at our host.

Thankfully with 1 small tweak to composer.lock, I got composer install to work, but what I'm trying to do now is fix some failures I'm getting when running composer update. There are plenty of posts online about composer dependency hell - and I'm in a leaky boat on the river styx headed there pulling my hair out.

In short, a couple years back when composer.lock was created, the project worked with the then-current versions of "dev" of dozens of included vendor libraries, but now that I am trying to clean up the mess, I'd like to put proper versions into composer.json and try to update things from a known state.

How do I discover what versions actually get installed by composer install? Or what keys/values in the composer.lock file tell you this?

I have plenty of github commit hashes in the composer.lock file but it's not clear given an arbitrary commit hash what the closest tagged version would be to replace that respective line in composer.json with.

Here's an example line from composer.json:

"doctrine/doctrine-bundle"              : "dev-master",

and here is the corresponding node in composer.lock for that module:

{
    "name": "doctrine/doctrine-bundle",
    "version": "dev-master",
    "target-dir": "Doctrine/Bundle/DoctrineBundle",
    "source": {
        "type": "git",
        "url": "http://github.com/doctrine/DoctrineBundle.git",
        "reference": "d3c930599723c8343472a5791b0f5909a4111a73"
    },
    "dist": {
        "type": "zip",
        "url": "https://github.com/doctrine/DoctrineBundle/zipball/d3c930599723c8343472a5791b0f5909a4111a73",
        "reference": "d3c930599723c8343472a5791b0f5909a4111a73",
        "shasum": ""
    },
    "require": {
        "doctrine/dbal": ">=2.2,<2.4-dev",
        "php": ">=5.3.2",
        "symfony/doctrine-bridge": "2.1.*",
        "symfony/framework-bundle": "2.1.*"
    },
    "require-dev": {
        "doctrine/orm": ">=2.2,<2.4-dev",
        "symfony/validator": "2.1.*",
        "symfony/yaml": "2.1.*"
    },
    "suggest": {
        "doctrine/orm": "The Doctrine ORM integration is optional in the bundle."
    },
    "type": "symfony-bundle",
    "extra": {
        "branch-alias": {
            "dev-master": "1.0.x-dev"
        }
    },
    "autoload": {
        "psr-0": {
            "Doctrine\\Bundle\\DoctrineBundle": ""
        }
    },
    "license": [
        "MIT"
    ],
    "authors": [
        {
            "name": "Fabien Potencier",
            "email": "[email protected]"
        },
        {
            "name": "Benjamin Eberlei",
            "email": "[email protected]"
        },
        {
            "name": "Symfony Community",
            "homepage": "http://symfony.com/contributors"
        }
    ],
    "description": "Symfony DoctrineBundle",
    "homepage": "http://www.doctrine-project.org",
    "keywords": [
        "DBAL",
        "Database",
        "ORM",
        "Persistence"
    ],
    "support": {
        "source": "https://github.com/doctrine/DoctrineBundle/tree/master",
        "issues": "https://github.com/doctrine/DoctrineBundle/issues"
    },
    "time": "2012-09-10 15:12:44"
}

I am guessing that composer installs the dist->url or source->url from composer.lock, but I have several dozen modules to go through and wondering how to find the closest (by date) tag for each referenced library to create a sane composer.json file to move forward with updating our code.

like image 316
phpguru Avatar asked Dec 04 '14 22:12

phpguru


2 Answers

First you need to find out which packages are dependent on a dev-master version.

composer show -i

This will list all your packages along with the version installed. Something like this:

symfony/http-foundation               dev-master 1234abc
symfony/http-kernel                   v2.5.7

You will see some of the packages are listed as having the version dev-master <commit>. Take note of the names of these packages.

Now you can make it a bit easier on yourself by installing the source code for the packages in your vendor directory.

composer install --prefer-source

Now for each package you noted above, cd into the package directory and find the latest tag.

cd vendor/symfony/http-foundation
git describe # Shows the latest tag

Now you can use that tag to determine which version you want to install. For example if git describe returned v2.2.3, you could change the version number in your composer.json to 2.2.*.

"symfony/http-foundation": "2.2.*"

This part could be tricky if the latest tag is "far away" from the installed commit. If you run into too many problems, you can always install an exact commit hash by putting dev-master#<commit> into your version requirement.

"symfony/http-foundation": "dev-master#1234abc"
like image 140
Justin Howard Avatar answered Nov 05 '22 18:11

Justin Howard


Thanks to other answers I start digging and found that you can have useful informations with:

composer show -t

It will produce a dependency tree, and next to every package there will be version.

like image 21
Vladimir Vukanac Avatar answered Nov 05 '22 18:11

Vladimir Vukanac