我有一个Zend Framework 2应用程序。它包含一些库代码,其中包含业务逻辑和一些其他实用程序,这些实用程序将在以后创建的其他应用程序中使用。
我的目的是使用Composer在项目中共享它。问题是,我该如何正确地完成这项工作并简化开发?我几乎肯定需要在其他项目中对库进行更改和添加。
我尝试将vendor/stuff
设置为包含所需包的git子模块,并在主composer.json
中引用它(ref):
"repositories": [
{
"type": "git",
"url": "vendor/stuff"
}
],
"require": {
"stuff/library": "master"
},
Composer无法以这种方式加载它。它抱怨无法找到包,可能是因为它忽略了URL本地和相对的事实。从技术上讲,它不需要; vendor / stuff文件夹是通过git submodule命令单独初始化的。
答案 0 :(得分:42)
不幸的是* Composer不支持Git子模块,因为Composer的主要目的是提供类似的项目间依赖功能,尝试在Composer中复制子模块毫无意义。
我有同样的问题,你试图解决,开发一个库,同时开发使用该库的应用程序。有几种方法可以使用composer来解决这个问题。
这是最快捷,最脏的方式。只需做一个作曲家更新,为vendor目录中的库创建适当的目录,然后用包含库的目录中的符号链接替换它。
显然这并不好,因为你可能会意外地覆盖你可能通过运行composer update编辑过的代码。
Composer可以选择通过Git克隆(--prefer-src
)下载源代码,而不是下载默认的zipball(--prefer-dist
)。这允许您编辑供应商目录中的源代码,然后通过Git提交它。
e.g。假设您有其他库symfony/yaml
需要修复错误的项目。您可以做的是:
composer update
- 这将下载项目的所有依赖项。
composer update symfony/yaml --prefer-source
- 现在只更新供应商目录中的symfony/yaml
目录。
修复错误,然后通过git提交。
我实际上用来工作的方式 - 当我开发一个项目及其需求时,就是使用Composers的能力设置显式设置一个存储库来用来解决依赖。例如如果你的代码在:
/projects/library/
/projects/project/
在项目的composer文件中添加存储库条目:
"repositories": [
{
"type": "vcs",
"url": "/projects/library/"
}
]
运行composer update
现在将查看/ projects / library /中的Git条目,以解决对库的任何依赖关系,优先于Packagist或其他存储库中列出的依赖关系。
这确实意味着当您想要测试库代码中的更改时,您需要:
提交它,以便它有一个Git条目。
在项目目录中运行Composer更新以获取最新版本。
但是你不必将提交推送到外部存储库,这很好,因为这意味着你不会推送可能不起作用的代码,这意味着你可以脱机工作,因为Git承诺不要需要互联网连接。
虽然这显然是最好的工作方式,但它仍然有点危险,因为它很容易意外地检入你的composer.json版本,它引用了本地目录,这显然会打破适合所有人的项目。
为了避免这种情况,我制作了几个小脚本,i)备份我的真实composer.json文件,ii)添加一些本地存储库,iii)运行composer update
iv)恢复真正的composer.json文件。
cp -f composer.json composer.json.bak
php composerLocal.php
composer update
cp -f composer.json.bak composer.json
<?php
$srcFile = file_get_contents("composer.json");
$hackFile = file_get_contents("composer.local");
$finalString = str_replace('"LOCALHACK",', $hackFile, $srcFile);
file_put_contents("composer.json", $finalString);
?>
"LOCALHACK",
"repositories": [
{
"type": "vcs",
"url": "/projects/library1"
},
{
"type": "vcs",
"url": "/projects/library2"
}
],
然后将"//": "LOCALHACK",
放在项目composer.json
文件中的某个位置。现在安全地运行localupdate.sh
会对作者更新本地存储库,而不会有任何错误版本的composer.json。
这就是我现在的工作方式:
i)项目中的Composer更新 ii)进入供应商目录并删除我想要同时开发的库。 iii)从您正在开发库的任何repo中将Git克隆到相应的供应商目录中。
Composer理解git repos,因此不会覆盖git克隆目录(虽然它似乎对编辑库的composer.json感到有些困惑。)
自己进行git克隆,让您完全控制安装的内容,并允许您从作曲家不知道的repo或无标记版本进行安装,而无需编辑composer.json in该项目。
这是自己做git克隆的关键特性;通过不触及项目的composer.json,它是完全安全的,不可能检入已经修改为使用本地/自定义存储库的composer.json。
对composer.json文件的验证已经收紧,并且不再可能在文件中有"//": "LOCALHACK"
条目。这也是为什么Composer人员没有为Composer项目进行版本控制的另一个原因。
*我实际上认为Git Submodules是一个愚蠢,愚蠢,愚蠢的实现,以解决问题。一个困难的问题,只会导致更多的问题,所以作曲家不支持他们是更幸运的&#39;比不幸的#39;显然其他人确实使用它们,并对它们感到满意,所以这只是我的意见,伙计,但是如果您使用Composer,那么您就不需要子模块。
答案 1 :(得分:2)
Composer具有自动加载映射功能,如果您的库符合PSR-x标准,那么它可以满足您的要求。也可以按照类似的程序自动加载非psr-x库。
此处引用:https://getcomposer.org/doc/04-schema.md#autoload
让我们举个例子(假设您的图书馆遵循PSR-4标准)
假设你已经在lib / your-private-git-repo文件夹中克隆了子模块。
您所要做的就是添加到composer.json
文件自动加载部分:
{
"name": "YourNamespace/YourApplicationName",
"description": "Describe your library",
"license": "Your licen",
"keywords": ["some","keywords"],
"authors": [
{
"name": "Adamo Aerendir Crespi",
"email": "hello@aerendir.me"
}
],
"require": {
"joomla/framework": "*@stable"
},
"require-dev": {
"phpunit/phpunit": "*@stable"
},
"autoload": {
"psr-4": {
"YourNamespace\\YourSubmodule\\": "lib/your-private-git-repo/src"
}
}
}
请注意,这些行构成了代码底部的第六行
"autoload": {
"psr-4": {
"YourNamespace\\YourSubmodule\\": "lib/your-private-git-repo/src"
}
}
现在更新Composer
php composer.phar update
这样,Composer也会更新包含子模块的自动加载文件。
全部完成:现在您的子模块由Composer自动加载。
希望这会有所帮助。
答案 2 :(得分:0)
如果您的项目A包含git子模块,则从项目A调用composer install/update..
将忽略子模块中的所有composer依赖项。
简而言之,如果git子模块包含作曲者依赖性,则不要使用它。
这就是我宁愿这样做的方式:
1)如果不是正式包(例如fork或私有存储库),则将该存储库添加到composer.json
:
"repositories": [
{
"type": "vcs",
"url": "https://github.com/vendor_name/package_name.git"
}
],
2)需要带有--prefere-source
的软件包:
composer require vendor_name/package_name --prefer-source
注意:如果将official/mango
派生到自己的存储库ralf/mango
中,则需要指向ralf/mango
中的composer.json
,但致电作曲家需要Official / mango。 `您可以在docs中阅读详细信息。
现在您可以从供应商内部访问文件并进行推拉操作。--prefere-source
命令已经在供应商文件内部设置了git连接。
如果您想通过package/mango
之类的根文件夹(而不是vendor/official/mango
)访问该软件包,则可以设置符号链接。
答案 3 :(得分:0)
所需行为:
操作方法:
"require": {
"stuff/library_C": "master"
},
2.run composer install 。现在您的图书馆位于文件夹 vendor / stuff / library_C
3。现在,当您要在 project_A 或 project_B 中的 library_C 中编辑内容时,删除文件夹 vendor / stuff / library_C 并运行此命令
git submodule add -f https://github.com/stuff/library_C.git vendor/stuff/library_C
此命令将重新创建此文件夹 vendor / stuff / library_C ,但此文件夹现在是另一个git repo(子模块)
4。转到文件夹 vendor / stuff / library_C 更改所有内容,然后提交并推送,这就是全部!
之后,当您在其他项目中运行 composer update stuff / library_C 时,代码将被更新。
注意:运行 git子模块后添加 您将在分支机构主管上,因此必须签出到正确的分支机构或标签并在此处进行更改。