强制composer到符号链接本地包

时间:2017-11-10 21:52:14

标签: composer-php

我试图找到一种强制作曲家的正确方法 符号链接本地包。

我知道有一个问题How to force Composer to download a local package?,但它没有回答我的问题。我需要确保它按预期工作,因为我将在CI工作流程中使用它。

让项目的composer.json像:

{
    "name": "Some project",
    "type": "project",
    "minimum-stability": "dev",
    "prefer-stable": true,
    "repositories": [{
        "type": "path", 
        "url": "packages/*/*"
    }]
}

并打包了composer.json(packages / sample / package):

{
    "name": "Sample package",
    "version": "1.0.0"
}

我们假设:

  • sample/package:1.0.0发布在packagist(commit aaaaaa)中 - 未经修改composer.json
  • 在本地{li> sample/package已在提交bbbbbb 上签出
  • 我无法修改本地version的{​​{1}}

命令1:

sample/package

从packagist(版本$ composer require sample/package ,提交1.0.0)获取包。

命令2:

aaaaaa

包从本地版本符号链接到供应商目录(版本$ composer require sample/package:@dev ,提交1.0.0,符号链接)。

问题是:

  1. 为什么 Command 1 尽管有bbbbbb选项从packagist下载包?版本约束minimum-stability允许您强制执行不同的稳定性,但已使用项目配置降低到@dev
  2. Command 2 会不会在每种情况下都为本地包创建符号链接?
  3. 是否有比 Command 2 更好的方法来确保本地包被符号链接?

4 个答案:

答案 0 :(得分:9)

为什么Command 1尽管有最小稳定性选项,还是从packagist下载包?版本约束@dev允许您强制执行不同的稳定性,但它已经通过项目配置降低到dev。

我最好的猜测是,当composer require sample/package中没有提供版本限制时,由于"prefer-stable": true,Composer仍会尝试找到要安装的稳定版本。当您将此选项设置为false(或明确提供包的@dev版本约束)时,您应该看到Composer使用最新的可用版本(dev-master在提交bbbbbb上)。

在每种情况下,Command 2都会为本地包创建符号链接吗?

并非在所有情况下。您可以使用"symlink": true选项强制Composer始终对包进行符号链接。

来自https://getcomposer.org/doc/05-repositories.md#path

  

如果可能的话,本地包将被符号链接,在这种情况下,控制台中的输出将从../../packages/my-package读取符号链接。如果无法进行符号链接,则将复制包。在这种情况下,控制台将从../../packages/my-package输出镜像。

     

您可以强制使用符号链接"symlink": true或使用"symlink": false选项镜像,而不是默认回退策略。从单片存储库部署或生成包时,强制镜像非常有用。

是否有比Command 2更好的方法来确保本地包被符号链接?

您应该避免从"prefer-stable": true删除composer.json,因为这会影响所有依赖项。

我建议您确保明确要求@dev的{​​{1}}版本,并为本地存储库设置sample/package。这将导致类似:

"symlink": true

答案 1 :(得分:0)

如果@Maciek Lewkowicz提供的非常有用的信息不起作用,则可能是您处于这种情况:

  1. 您使用的是特定分支(例如dev-master);
  2. 您正在使用的分支来自远程存储库;
  3. 您正在尝试符号链接同一分支,但这一次使用路径(因此,您在composer.json中所做的唯一更改是软件包的来源,并在repositories键中设置了仓库composer.json文件中的内容。

在这种情况下,简单的composer update将不起作用:Composer不会拦截更改:因为Composer与将存储库从远程路径更改为本地路径无关。它只会检查分支是否相同,因此根本不会更新。

因此,在这种情况下,任何操作都将无效:使用symlink: force将无效,也将无法更改有关源的首选项,等等。

唯一可行的是更改分支。

例如,您的composer.json如下所示:

{
    ...
    "require": {
        ...
-       "your/package": "dev-master",
+       "your/package": "dev-dev",
        ...
    },
    ...
    "repositories": [
        {
            "type": "path",
            "url": "/Path/To/Your/Local/package"
        }
    ]
}

这里dev-dev是一个名为dev的新分支:将分支从dev-master更改为dev-dev将迫使Composer重新下载软件包,因为所需的分支不是{ {1}}。

在再次下载该软件包时,Composer还将检查新源现在是否是本地路径,因此将符号链接该文件夹。

答案 2 :(得分:0)

这可能不起作用的另一个原因是,您在repository中有多个条目。 Compose将使用首先在其中找到软件包的存储库定义。

在我们的例子中,我们使用自定义的Satis存储库。在satis repo之后定义本地软件包时,它将永远不会进行符号链接,并始终使用Satis版本。首先定义本地包时,它确实起作用。

工作示例:

    "repositories": {
        "our/local-package": {
            "type": "path",
            "url": "../../some-local-package",
            "options": {
                "symlink": true
            }
        },
        "satis": {
            "type": "composer",
            "url": "http://our.satis.url/"
        }
    }

然后致电composer require our/local-package:@dev

答案 3 :(得分:0)

为了在这里已经很好的答案上扩大一点,我遇到了相同的问题,但是解决方案略有不同:

如果本地包和远程存储库中具有相同的“版本”(分支,标签,哈希),以防作曲家无法解析本地包的依赖关系,则它将默默地将版本从远程仓库,只要可以解决这些依赖关系。

为了进行调试,您可以在本地软件包100的“版本”属性中添加一些怪异版本(例如package.json),然后在该版本中使用它,从而向您显示哪个依赖项无法实现(然后您将其更改)。