【问题标题】:Composer - using a local repositoryComposer - 使用本地存储库
【发布时间】:2013-06-29 20:33:07
【问题描述】:

我是 Composer 初学者,我正在尝试使一个项目依赖于另一个项目,而这两个项目都只存在于我的本地计算机上。

我的库项目(ProjectA)中的composer.json是:

{
    "name" : "project/util",
    "type" : "library"
}

我在这个项目的基础文件夹中初始化了 git。

我在项目中的composer.json依赖第一个(ProjectB):

{
    "repositories": [
        {
            "name" : "util", 
            "type" : "git",
            "url" : "/d/workspaces/util"
        }   
    ],

    "require": {
        "project/util" : "*"
    },
}

当我从 ProjectB 运行 composer install 时,我收到以下错误:

[RuntimeException]
Failed to clone , could not read packages from it
fatal: repository '' does not exist

我认为存储库的 url 有问题,但我不知道还要在那里写什么。

【问题讨论】:

    标签: git composer-php


    【解决方案1】:

    我认为您只是语法错误。类型应该只是 VCS,然后 composer 算出它是什么类型的 VCS。

    所以在您的项目 B 中,存储库的条目应该是:

    "repositories": [
        {
            "type": "vcs",
            "url" : "/d/workspaces/util"
        }
    ],
    

    您无需命名/d/workspaces/util 中可用的库。 Composer 将扫描该目录中的 composer.json 文件并知道那里可用的项目名称,并优先使用该目录中的项目而不是 packagegist 或其他存储库中列出的版本。

    【讨论】:

    • 好的,当我改用vcs时,我得到这个消息:[运行时异常]目录不存在:/d/workspaces/util
    • 呃,想必那么目录不存在,或者无法访问?
    • 我认为该目录只是拼写错误。您确定必须以/d/workspaces/util 而不是d:/workspaces/util 的形式提供吗?
    • 必须如何提供?
    【解决方案2】:

    除了 Danack 的解决方案:将路径从 /d/ 更改为 d:/ 对我有用。

    像这样:

    "repositories": [
        {
            "type": "vcs",
            "url" : "d:/workspaces/util"
        }
    ],
    

    【讨论】:

      【解决方案3】:

      使用 Composer 自动加载本地包(每次更改时都无需使用 packagegist)。

      有很多方法可以做到这一点,我将介绍其中的两种:

      在所有情况下,我们都有 2 个主要参与方:
      - 本地包(我们不想在 packagist 上发布的代码,以便能够在我们的项目编写器中自动加载它)。
      - 主项目(需要使用本地包代码的代码库,可以是另一个包或任何项目)。


      方法一:(直接命名空间)

      打开主项目composer.json 文件并使用任何方法(PSR-4、PSR-0、...)自动加载本地包命名空间。

      示例:

      如果在本地包的 composer.json 中我们有:

        "autoload": {
          "psr-4": {
            “Local\\Pack\\": "library"
          }
        },
        "autoload-dev": {
          "psr-4": {
            "Local\\Pack\\Tests\\": "tests"
          }
        },
      

      那么在主项目的composer.json中我们应该有:

        "autoload": {
          "psr-4": {
            "Mahmoudz\\Project\\": "src",
            "Local\\Pack\\": "../path/to/local/pack/library”                   << referencing the other local package
          }
        },
        "autoload-dev": {
          "psr-4": {
            "Mahmoudz\\Project\\Tests\\": "tests"
          }
        },
      

      优点:
      - 您不会触及供应商目录(错误地运行 composer update 不会覆盖您的本地更改)
      - 你不需要你的包在 packagist 上就可以使用它
      - 您在一个地方(本地包)工作,更改会自动加载到主项目中
      缺点:
      - 您不能在生产环境中发布 composer.json(需要在发布前进行编辑以需要真正的包)

      方法二:(本地仓库)

      从本地存储库下载本地包。

      本地包:
      1.在包中初始化git(即使你不想使用它——不需要提交任何东西)
      2.添加composer.json文件。在文件中确保您具有以下内容:

      "name": "vendor-name/package-name",  
      
      "autoload": { …   // use whichever method you prefer, but make sure it’s being loaded correctly
      
      "minimum-stability": "dev"  
      
      1. composer dump-autoload

      主要项目:
      1. 编辑您的 composer.json 以包含以下内容:

        "repositories": [
          {
            "type": "vcs",
            "url": "/full/path/to/the/local/package/package-name"
          }
        ],
        "require": {
          "vendor-name/package-name": "dev-master"
        },
      
      1. composer 更新供应商名称/包名称
      2. 现在检查您的供应商目录,您应该会看到供应商名称/包名称

      注意:每当您在本地包(而不是供应商)中进行更改时,您需要 git commit 然后您可以作曲家更新主项目,它会将 repo 的最新副本获取到主项目供应商目录。

      优势:
      - 你不接触供应商目录(错误地运行 composer update 不会覆盖你的本地更改) - 你不需要你的包在 packagist 上才能使用它
      缺点: - 您必须继续提交您的更改(在本地包中),然后在主项目中运行 composer update
      - 您不能在生产环境中发布 composer.json(需要在发布前进行编辑以需要真正的包)

      【讨论】:

      • 谢谢,太好了! 注意: 如果您使用的是 vcs 方法(#2),请不要忘记提交您的 composer.json 更改。很容易忘记,你会摸不着头脑,为什么作曲家会用“找不到包版本”错误来吐出你的包。
      • 你的第一个方法救了我的命!赞一个!
      • 第二种方法和@mangonights 评论也救了我...谢谢大家
      • 我使用了第二种方法,我得到了这个错误:在...的任何分支或标签中找不到有效的composer.json,无法从中加载包。为了修复它,我使用了@mangonights 回复,并将更改提交到我的本地存储库,这解决了我的问题
      • 方法 1 在开发效率方面确实很棒,因为我不必为“composer update”命令浪费时间。然而,composer Autoloader 不能很好地处理传递依赖。换句话说,如果“ProjectA”依赖于“ProjectB”而后者依赖于“ProjectC”,那么方法1并没有真正起作用,除非我在ProjectA的composer.json文件中明确指定“ProjectA”同时依赖于“ProjectB/ProjectC” ”。但是如果你有 20 多个小项目,这种方法不能很好地扩展。自动装载机管理成为噩梦。 @Mahmoud,你对此有什么想法吗?
      【解决方案4】:

      我发现本教程非常有用:https://johannespichler.com/developing-composer-packages-locally/ 当我遇到本地包生产问题时

      请注意 symlink 条件允许供应商文件夹成为符号链接,这意味着您不再需要在每次想要查看更改时都使用 composer update

      "options": {
              "symlink": true
            }
      

      【讨论】:

        【解决方案5】:

        最简单的方法是使用 type=path https://getcomposer.org/doc/05-repositories.md#path

        {
        "repositories": [
            {
                "type" : "path",
                "url" : "/d/workspaces/util"
            }   
        ],
        
        "require": {
            "project/util" : "*"
        },
        

        }

        【讨论】:

          【解决方案6】:

          注意:此答案假定您有类似包注册表或 GIT 存储库的东西 可以检索您的软件包的版本。如果你还没有这个。 https://getcomposer.org/doc/05-repositories.md

          Composer 使我们能够自动加载本地开发包,而不会污染 composer.lock 文件。 当 Composer 发现两个或多个包之间存在冲突时,它只会自动加载其中一个包。

          您可以使用autoload-dev 自动加载特定文件夹以进行开发。 (https://getcomposer.org/doc/04-schema.md#autoload-dev)

          autoload-dev(和autoload)设置不会触及 composer.lock 文件

          在您的 projects composer.json 文件中:

          "repositories": {
              "99999999": {
                  "type": "composer",
                  "url": "https://gitlab.com/api/v4/group/99999999/-/packages/composer/packages.json"
              }
          }
          "require": {
              "a-vendor-name/test-package": "1.0.*"
          }, 
          "autoload-dev": {
              "classmap": [
                  "./../../packages/a-vendor-name/test-package"
              ],
              "exclude-from-classmap": [
                  "vendor/a-vendor-name/test-package"
              ]
          }
          

          在本例中,packages 目录位于项目根目录之外,并包含其自己的 package GIT 存储库。

          autoload-dev 因为我们只希望在开发时加载此文件夹。 (https://getcomposer.org/doc/04-schema.md#autoload-dev)

          classmap 从本地目录加载包。 (https://getcomposer.org/doc/04-schema.md#classmap)

          exclude-from-classmap 禁用在供应商目录中加载包。 还将抑制有关具有相同命名空间的多个类的警告。 (https://getcomposer.org/doc/04-schema.md#exclude-files-from-classmaps)

          运行开发(默认行为):

          composer update a-vendor-name/test-package // or any other composer command 
          

          您的包仍会从您的包注册表下载。这个下载的包不仅在您的应用程序代码中被忽略,还可以根据项目 composer.json 文件对其进行更新。这反过来会更新 composer.lock 文件,正确的方式

          使用--no-dev 标志运行DTAP / PRODUCTION

          composer update a-vendor-name/test-package --no-dev // or any other composer command 
          

          【讨论】:

            【解决方案7】:

            除了@Glen Solsberry 的解决方案,如果你像我一样在 docker 容器中运行,你可以在你的 docker-compose.yml 文件中添加一个卷,比如:

            services:
              theservicename:
                ...
                volumes:
                  - ../:/var/www
                  - /path/to/src/package:/var/www/vendor/path/to/src/package
                ...
            

            当您在本地进行更改时,它们将反映在容器中。

            【讨论】:

              猜你喜欢
              • 2017-05-16
              • 1970-01-01
              • 2015-03-22
              • 2016-07-18
              • 2019-01-22
              • 1970-01-01
              • 1970-01-01
              • 2016-09-20
              • 2019-12-11
              相关资源
              最近更新 更多