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

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

问题描述

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



我的意图是使用Composer 。问题是,我该如何做到这一点,并精简开发?



我尝试设置 vendor / stuff

code>作为包含所需包的git子模块,并在主 composer.json 中引用它(ref)

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

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

解决方案

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



我有同样的问题,你想解决,开发一个库,同时开发应用程序使用该库。



为库目录创建一个符号链接



这是最快和最脏的方式。只需执行一个作曲家更新,在您的vendor目录中为库创建相应的目录,然后用包含您的库的目录中的符号链接替换它。





使用Composer prefer source选项









b

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



例如。说你有项目需要其他库 symfony / yaml ,你想修复一个错误。你能做的是:


  1. 作曲家更新 - 这将下载项目的所有依赖项。


  2. 作者更新symfony / yaml --prefer-source - 现在只更新 symfony / yaml 目录中。


  3. 修复错误,然后通过git提交。




使用Composer本地存储库



我的方式---开发项目和它的要求,是使用Composers能力设置显式设置存储库以用于解决依赖项。例如如果您的代码在:

  / projects / library / 
/ projects / project /



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

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

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



当你想要测试库代码的变化,你需要:


  1. 提交它,以便它有一个Git




  2. 在项目目录中运行Composer更新。 b
    $ b

    但是你不必将提交推送到外部存储库,这是好的,因为它意味着你不推送可能无法工作的代码,这意味着你可以脱机工作Git提交不需要互联网连接。






    虽然这显然是最好的工作方式,但它仍然是危险的它太容易意外检查你的composer.json的版本,引用本地目录,这显然会打破项目为所有人。



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



    localupdate.sh



      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 / code>您的项目中的某处 composer.json 文件。运行 localupdate.sh 现在可以安全地对本地存储库执行composer更新,而没有任何机会提交composer.json的错误版本。



    只需用Git克隆它



    这是我现在的工作方式:



    i )项目中的Composer更新
    ii)进入vendors目录并删除我想同时开发的库。



    Composer理解git repos,因此不会覆盖git clone目录(虽然它似乎对编辑composer.json的库有点困惑)。



    自己做git clone,给你完全控制对于安装的内容,并允许您从作者不知道的repo安装,或无标记的版本,而无需编辑项目中的composer.json。



    这是自己做git clone的关键功能;通过不接触项目的composer.json,它是完全安全的,没有检查已修改为使用本地/自定义repos的composer.json的可能性。




    • 编辑 - 2014年9月6日



    composer.json文件已经收紧,并且不再可能在文件中有//:LOCALHACK条目。这是另一个原因,为什么Composer家伙没有版本控制Composer项目是坚果。



    *我实际上认为Git子模块是一个愚蠢的, 一个困难的问题,只是导致更多的问题在路上,因此,作曲家不支持他们是更多的幸运比不幸的。显然,其他人使用它们,并且对他们很满意,所以这只是我的意见,人,但如果你使用Composer,你不应该需要子模块。


    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.

    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.

    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 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.

    解决方案

    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.

    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.

    Make a symbolic link for the library directory

    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.

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

    Use Composer prefer source option

    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.

    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 - This will download all of dependencies of the project.

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

    3. Fix the bug and then commit it through git.

    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/
    

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

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

    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. Commit it, so that it has a Git entry.

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

    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.


    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.

    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.

    localupdate.sh

    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"
        }   
    ],
    

    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.

    Just clone it yourself with Git

    This is how I tend to work now:

    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 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).

    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.

    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.

    • Edit - 6th Sept 2014

    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.

    * 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天全站免登陆