作曲家需要本地包装

我有几个库[ Foo 和 Bar ]正在协同开发,但在技术上仍然是独立的东西。以前我只是重新定义了自动加载程序来喜欢 "Foo\\": "../Foo/src",但是现在我已经添加了一个 Guzzle 依赖关系到 Foo,Bar 翻转它的盖子,因为它不是它的依赖关系之一。

目录结构:

/home/user/src/
Foo/
src/
FooClient.php
composer.json
Bar/
src/
BarClient.php
composer.json

理论自动加载语句: [ in Bar/poser.json ]

"require": {
"local": "../Foo/composer.json"
}

示例代码:

require('vendor/autoload.php');


$f = new \Bar\BarClient(new \Foo\FooClient());

如何在不设置本地 Composer 回购的情况下解决这个问题?我想把它们作为独立的包来维护,只是其中一个需要另一个,因此处理另一个的依赖关系。

回答后编辑:

多亏了信息狂人,我做了以下几件事:

初始化 git 回购:

cd ~/src/Foo && git init && echo -e "vendor\ncomposer.lock" > .gitignore && git add ./ && git commit -m "Initial Commit"

添加了作曲家配置:

"require": {
"sammitch/foo": "dev-master"
},
"repositories": [{
"type": "vcs",
"url": "/home/sammitch/src/Foo"
}],

然后是 composer update

132291 次浏览

您可以使用 Composer 的 储存库特性

Https://getcomposer.org/doc/05-repositories.md#path

{
"repositories": [
{
"type": "path",
"url": "../../packages/my-package"
}
],
"require": {
"my/package": "*"
}
}

指定磁盘上的文件路径,而不是使用 http 格式。

链接到本地正在开发的软件包的方法是首先在主项目的 composer.json a 储存库中添加,如下所示:

"repositories": [
{
"type": "path",
"url": "/full/or/relative/path/to/development/package"
}
]

您还需要在您的开发包的 composer.json中指定一个版本,或者我这样做的方式是使用 @dev要求该包,如下所示:

composer require "vendorname/packagename @dev"

它应该输出:

- Installing vendor/packagename (dev-develop)
Symlinked from /full/or/relative/path/to/development/package

请求命令中的 @dev非常重要,编写器使用它来获取源代码并将其符号链接到新的包。

它是添加到版本约束中的稳定性标志(参见 软件包链接)。

这些选项允许您进一步限制或扩展 超出 最小稳定性范围的包的稳定性 设定。

最小稳定性标志是:

可用的选项(按稳定性顺序)有 devalphabetaRCstable

花了一些时间,我终于明白了解决方法。也许对于像我这样的人来说,它会很有用,也会为你节省一些时间,所以我决定在这里分享它。

假设您有以下目录结构(相对于您的项目根目录) :

composer.json
config
config/composition-root.php
local
local/bar-project
local/bar-project/composer.json
local/bar-project/src
local/bar-project/src/Bar.php
public
public/index.php
src
src/Foo.php

在这个例子中,你可以看到 local文件夹是为你公司的嵌套项目准备的,例如 bar-project。但如果您愿意,可以配置任何其他布局。

每个项目都必须有自己的 composer.json文件,例如根 composer.jsonlocal/bar-project/composer.json。其内容如下:

(根 composer.json:)

{
"name": "your-company/foo-project",
"require": {
"php": "^7",
"your-company/bar-project": "@dev"
},
"autoload": {
"psr-4": {
"YourCompany\\FooProject\\": "src/"
}
},
"repositories": [
{
"type": "path",
"url": "local/bar-project"
}
]
}

(local/bar-project/composer.json:)

{
"name": "your-company/bar-project",
"autoload": {
"psr-4": {
"YourCompany\\BarProject\\": "src/"
}
}
}

例如,如果您希望将每个项目放在单独的兄弟目录中,如下所示:

your-company
your-company/foo-project
your-company/foo-project/composer.json
your-company/foo-project/config
your-company/foo-project/config/composition-root.php
your-company/foo-project/public
your-company/foo-project/public/index.php
your-company/foo-project/src
your-company/foo-project/src/Foo.php
your-company/bar-project
your-company/bar-project/composer.json
your-company/bar-project/src
your-company/bar-project/src/Bar.php

- 那么您需要链接到 repositories部分的相应目录:

  "repositories": [
{
"type": "path",
"url": "../bar-project"
}
]

之后,不要忘记 composer update(甚至 rm -rf vendor && composer update -v作为 医生说) ! 在引擎盖下,作曲家将创建一个目标为 local/bar-project(或者分别为 ../bar-project)的 vendor/your-company/bar-project符号链接。

假设你的 public/index.php只是 front controller,例如:

<?php
require_once __DIR__ . '/../config/composition-root.php';

那么你的 config/composition-root.php会是:

<?php


declare(strict_types=1);


use YourCompany\BarProject\Bar;
use YourCompany\FooProject\Foo;


require_once __DIR__ . '/../vendor/autoload.php';


$bar = new Bar();
$foo = new Foo($bar);
$foo->greet();

执行此操作的命令行方式是

composer config repositories.package_name local path/to/package
composer require group/package_name

如果 group/package _ name 在存储库和本地都可用,则使用本地版本。

可以将 local命令替换为 vcs 以引用直接存储库,或者将 composer替换为缺省值。