如何将 Git 子模块与 Composer 加载的库一起使用? [英] How do I use a Git submodule with a Composer loaded library?

查看:19
本文介绍了如何将 Git 子模块与 Composer 加载的库一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Zend Framework 2 应用程序.它包含一些包含业务逻辑的库代码和一些其他实用程序,这些实用程序将在稍后创建的其他应用程序中通用.

I have a Zend Framework 2 application. It contains some library code containing business logic and some other utilities that will be common to other applications that will be created later.

我的目的是在使用 Composer 的项目之间共享它.问题是,我如何正确地做到这一点并简化开发?我几乎肯定需要从另一个项目中对库进行更改和添加.

My intention is to share it across projects using Composer. The question is, how do I do this properly and streamline the development? I will almost certainly need to make changes and additions to the library, from within the other project.

我尝试将 vendor/stuff 设置为包含所需包的 git 子模块,并像这样在主 composer.json 中引用它 (ref):

I tried setting up vendor/stuff as a git submodule containing the package needed, and referencing it in the primary composer.json like this (ref):

"repositories": [
    {
        "type": "git",
        "url": "vendor/stuff"
    }
],
"require": {
    "stuff/library": "master"
},

Composer 无法以这种方式加载它.它抱怨找不到包,大概是因为它忽略了 URL 既是本地的又是相对的事实.从技术上讲,它不需要;vendor/stuff 文件夹是通过 git 子模块命令单独初始化的.

Composer isn't able to load it in this way. It complains that the package could not be found, presumably because it's ignoring the fact that the URL is both local and relative. Technically, it doesn't need to; the vendor/stuff folder was initialised separately through git submodule commands.

推荐答案

不幸的是* Composer 不支持 Git 子模块,因为 Composer 的主要目的是提供类似的项目间依赖功能,尝试没有意义在 Composer 中复制子模块.

Unfortunately* Composer doesn't support Git submodules, as the main aim of Composer is to provide a similar inter-project dependency functionality and it would be pointless to try to replicate submodules in Composer.

我遇到了您正在尝试解决的相同问题,即在开发库的同时开发使用该库的应用程序.有几种方法可以仅使用 composer 来解决这个问题.

I have the same problem that you are trying to solve, of developing a library while simultaneously developing the application that uses that library. There are a couple of ways to solve that problem just using composer.

这是最快最脏的方法.只需执行 composer update 以在您的供应商目录中为库创建适当的目录,然后将其替换为包含您的库的目录中的符号链接.

This is the quickest and dirtiest way of doing it. Just do a composer update to create the appropriate directory for the library in your vendors directory, then replace it with symbolic link from your the directory that contains your library.

显然这不是很好,因为您可能会意外覆盖您可能通过运行 composer update 编辑过的代码.

Obviously this is not great as you can accidentally overwrite code that you may have edited by running composer update.

Composer 可以选择通过 Git 克隆 (--prefer-src) 下载源代码,而不是下载 zipball (--prefer-dist),后者是默认值.这允许您在 vendor 目录中编辑源代码,然后通过 Git 提交.

Composer has the option to download the source via a Git clone (--prefer-src) rather than downloading a zipball (--prefer-dist) which is the default. This allows you to edit the source code inside the vendors directory and then commit it through Git.

例如假设您有一个项目需要在其他库 symfony/yaml 中修复错误.您可以做的是:

e.g. Say you have project that requires amongst other libraries symfony/yaml which you want to fix a bug in. What you could do is:

  1. composer update - 这将下载项目的所有依赖项.

  1. composer update - This will download all of dependencies of the project.

composer update symfony/yaml --prefer-source - 现在只更新 vendor 目录中的 symfony/yaml 目录.

composer update symfony/yaml --prefer-source - This will now update just the symfony/yaml directory in the vendors directory.

修复bug,然后通过git提交.

Fix the bug and then commit it through git.

使用 Composer 本地存储库

我在开发项目时——实际上——过去的工作方式是使用 Composers 的能力来显式设置用于解决依赖关系的存储库.例如如果您的代码在:

Use Composer local repository

The way I ---actually--- used to work when I'm developing a project and it's requirement in tandem, is to use Composers ability to set explicitly set a repository to use to resolve dependencies. e.g. if your code is in:

/projects/library/
/projects/project/

在项目的 composer 文件中添加存储库条目:

In the composer file for your project add the repository entry:

"repositories": [
    {
        "type": "vcs",
        "url": "/projects/library/"
    }
]

运行 composer update 现在将查看/projects/library/中的 Git 条目,以解决对库的任何依赖项,优先于 Packagist 或其他存储库中列出的那些.

Running composer update will now look at the Git entries in /projects/library/ to resolve any dependencies on the library in preference to those listed in Packagist or other repository.

这确实意味着当您想要测试库代码中的更改时,您需要:

This does mean that when you want to test a change in the library code you need to:

  1. 提交它,使其有一个 Git 条目.

  1. Commit it, so that it has a Git entry.

在项目目录中运行 Composer update 以获取最新版本.

Run Composer update in the project directory to get the latest version.

但是您避免了将提交推送到外部存储库,这很好,因为这意味着您不会推送可能无法工作的代码,这意味着您可以离线工作,因为 Git 提交不需要互联网连接.

But you avoid having to push the commit to an external repository, which is good as it means you aren't pushing code that may not work, and it means you can work offline as Git commits don't require an internet connection.

虽然这显然是最好的工作方式,但它仍然有点危险,因为很容易意外签入包含本地目录引用的 composer.json 版本,这显然会破坏其他所有人的项目.

Although that is apparently the best way of working, it's still kind of dangerous as it is too easy to accidentally check in a version of your composer.json that has references to local directories, which obviously will break the project for everyone else.

为了避免这种情况,我制作了几个小脚本,i) 备份我真正的 composer.json 文件,ii) 添加一些本地存储库,iii​​) 运行 composer update iv) 恢复真正的 composer.json 文件.

To avoid this I made a couple of small scripts that i) backup my real composer.json file, ii) Add in some local repositories, iii) run composer update iv) Restore the real composer.json file.

cp -f composer.json composer.json.bak
php composerLocal.php
composer update
cp -f composer.json.bak composer.json

composerLocal.php

<?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);

?>

composer.local

"LOCALHACK",

"repositories": [
    {
        "type": "vcs",
        "url": "/projects/library1"
    },
    {
        "type": "vcs",
        "url": "/projects/library2"
    }   
],

然后将 "//": "LOCALHACK", 放置在您的项目 composer.json 文件中的某个位置.运行 localupdate.sh 现在可以安全地针对本地存储库执行 composer 更新,而不会提交错误版本的 composer.json.

And then place "//": "LOCALHACK", somewhere in your projects composer.json file. Running localupdate.sh now safely does a composer update against local repositories without any chance of committing a bad version of composer.json.

这就是我现在的工作方式:

This is how I tend to work now:

i) 项目中的 Composer 更新ii) 进入 vendor 目录并删除我想要同时开发的库.iii) 从您正在开发库的任何存储库中将 Git 克隆到相应的供应商目录中.

i) Composer update in the project ii) Go into the vendors directory and delete the library that I want to be developing at the same time. iii) Git clone from whichever repo you are developing the library in, into the appropriate vendors directory.

Composer 理解 git repos,因此不会覆盖 git 克隆的目录(尽管它似乎对编辑库的 composer.json 感到有些困惑).

Composer understands git repos, so won't overwrite a git cloned directory(, though it does seem to get a little confused about editing the composer.json of the library).

自己进行 git clone,让您可以完全控制安装的内容,并允许您从 composer 不知道的 repo 或未标记的版本进行安装,而无需在项目中编辑 composer.json.

Doing the git clone yourself, gives you complete control over what gets installed, and allows you to install from a repo that composer doesn't know about, or an untagged version, without having to edit the composer.json in the project.

这是自己进行 git clone 的关键特性;通过不接触项目的 composer.json,它是完全安全的,不可能签入已修改为使用本地/自定义 repos 的 composer.json.

That's the key feature of doing the git clone yourself; by not touching the composer.json of the project, it's completely safe, with no possibility of checking in a composer.json that has been modified to use local/custom repos.

  • 编辑 - 2014 年 9 月 6 日

composer.json 文件的验证已加强,文件中不再可能有 "//": "LOCALHACK" 条目.这也是 Composer 人员没有为 Composer 项目进行版本控制的另一个原因.

The validation for composer.json files has been tightened and it is no longer possible to have a "//": "LOCALHACK" entry in the file. Which is another reason why the Composer guys not having versioning for the Composer project is nuts.

* 我实际上认为 Git 子模块是一个愚蠢的、愚蠢的、愚蠢的实现,它以一种只会导致更多问题的方式解决"一个难题,因此 Composer 不支持它们比幸运"得多不幸的'.显然其他人确实使用它们,并且对它们感到满意,所以这只是我的意见,伙计,但如果你使用 Composer,你不应该需要子模块.

* I actually think Git Submodules are a dumb, dumb, dumb implementation to 'solve' a difficult problem in a way that only causes more problems down the road, and so Composer not supporting them is way more 'fortunate' than 'unfortunate'. Obviously other people do use them, and are happy with them, so that is just my opinion, man, but if you're using Composer you shouldn't have a need for submodules.

这篇关于如何将 Git 子模块与 Composer 加载的库一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆