如何阅读或反向工程 composer.lock 文件?

Posted

技术标签:

【中文标题】如何阅读或反向工程 composer.lock 文件?【英文标题】:How to read or reverse-engineer composer.lock file? 【发布时间】:2015-02-02 23:54:24 【问题描述】:

我继承了一个使用 php 5.3.x、Symfony2 和 Composer 构建的项目,用于依赖管理。

composer.json 文件有很多这样的行:"vendorname/library" : "dev-master" 表示正在使用的库的版本。它最后一次编辑是在 2012 年 8 月,并且由于 composer.lock 文件存在并且项目正在我们主机的服务器上运行,因此显然可以正常工作。

谢天谢地,通过对 composer.lock 的 1 个小调整,我得到了 composer install 的工作,但我现在要做的是修复我在运行 composer update 时遇到的一些故障。网上有很多关于作曲家依赖地狱的帖子——我在冥河上的一艘漏水的船上,往那里拉我的头发。

简而言之,几年前创建 composer.lock 时,该项目使用了当时包含的数十个供应商库的“dev”版本,但现在我正试图清理混乱,我'想将正确的版本放入 composer.json 并尝试从已知状态更新内容。

我如何发现 composer install 实际安装了哪些版本?或者 composer.lock 文件中的什么键/值告诉你这个?

我在 composer.lock 文件中有很多 github 提交哈希,但是对于任意提交哈希,并不清楚用什么最接近的标记版本来替换 composer.json 中的相应行。

这是来自 composer.json 的示例行:

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

这是 composer.lock 中该模块对应的节点:


    "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": "fabien@symfony.com"
        ,
        
            "name": "Benjamin Eberlei",
            "email": "kontakt@beberlei.de"
        ,
        
            "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"

我猜 composer 从 composer.lock 安装 dist->url 或 source->url,但是我有几十个模块要通过,并且想知道如何为每个引用的库找到最接近的(按日期)标签创建一个健全的 composer.json 文件以继续更新我们的代码。

【问题讨论】:

要查找当前安装的版本,您可以使用composer show -i,来自this answer。应该让你开始。 【参考方案1】:

首先您需要找出哪些包依赖于dev-master 版本。

composer show -i

这将列出您的所有软件包以及安装的版本。像这样的:

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

您将看到一些软件包的版本为dev-master &lt;commit&gt;。记下这些包的名称。

现在,您可以通过在 vendor 目录中安装软件包的源代码来简化自己的工作。

composer install --prefer-source

现在对于上面提到的每个包,cd 进入包目录并找到最新标签。

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

现在您可以使用该标签来确定要安装的版本。例如,如果git describe 返回v2.2.3,您可以将composer.json 中的版本号更改为2.2.*

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

如果最新标签与已安装的提交“相距甚远”,这部分可能会很棘手。如果您遇到太多问题,您始终可以通过将dev-master#&lt;commit&gt; 放入您的版本要求中来安装精确的提交哈希。

"symfony/http-foundation": "dev-master#1234abc"

【讨论】:

这很简单,如果从那时起没有标记包,但在该主分支上进行了一些开发,那么真正的工作就开始了。您想避免使用任何分支,但这是第二步:替换没有标记的软件。【参考方案2】:

感谢其他答案,我开始挖掘并发现您可以通过以下方式获得有用的信息:

composer show -t

它会产生一个依赖树,每个包旁边都会有版本。

【讨论】:

以上是关于如何阅读或反向工程 composer.lock 文件?的主要内容,如果未能解决你的问题,请参考以下文章

composer.json和composer.lock

如何从供应商目录生成 laravel composer.json?

从composer.lock(不是composer.json)重新安装供应商

如何使用composer进行包管理更合适

如何使用composer进行包管理更合适

错误:无法解析“composer.lock”;它必须是 Composer 生成的有效锁文件