具有动态的克隆项目包含在composer.json中

时间:2015-09-18 22:15:12

标签: php git composer-php

我有一个应用服务器,它就像一个博客系统(我的wordpress杀手)。它基于github托管的php,并使用composer来管理依赖项。每个安装都托管在我的服务器中(我为它们安装)。当客户端需要新的“插件/插件”时,我创建了一个新的包并将其托管在私有存储库托管中。当我需要添加新包时会出现问题:

Client 1.
- package for calculate prices

Client 2.
- package for show a welcome message

Client 3.
- package for add a calendar

我的应用程序将准备好在所有实例中使用所有包,因为我通过composer需要它们:

"require": {
        "killer/calculate": "dev-master",
        "killer/message": "dev-master",
        "killer/calendar": "dev-master"
}

现在成像,如果我有2K客户端,并且每个人都在请求自定义包。我如何提供一个应用程序(大量克隆),但只是在每个安装中保留每个客户端需要的软件包?

假设解决方案

我正在搜索(如果可能的话)以下内容。对于每个安装,请手动创建文件,其内容指定所需的包。例如,假设每个客户端的安装都是这样的:

//composer.json
"require": {
}

//plugins.json  (this file is ignored via .gitignore)
{
    "killer/calculate": "dev-master"
}

然后,以某种方式告诉composer.json要求plugins.json的数据。通过这种方式,我避免为所有客户创建一个巨大的composer.json共享不必要的包。

4 个答案:

答案 0 :(得分:6)

允许composer.json扩展另一个文件有一个feature request。你应该对它进行评论以引起一些注意。

您使用该功能的方法是创建一个包含所有常规default.json内容的composer.json文件,其中包含列出您需要的所有常用软件包的require部分。< / p>

// default.json
{
    "require": {
        "php": ">=5.4.0"
    }
}

然后为每个项目提供composer.json文件,扩展和/或覆盖default.json,如下所示:

// composer.json
{
    "require": {
        "killer/calculate": "dev-master"
    },
    "extends": "default.json"
}

最终结果将是:

{
    "require": {
        "php": ">=5.4.0",
        "killer/calculate": "dev-master"
    }
} 

如果您无法等待合并请求,那么您可以从合并请求的作者中查看composer fork并尝试一下。

答案 1 :(得分:3)

听起来你已经创建了自己的包生态系统。因此,您可以独立于Packagist工作,只需自己托管所有软件包,可能使用Satis。

我的主要建议是将您的应用程序作为一个包引入此生态系统。

您的应用程序composer.json仅包含与应用程序本身相关的软件包。

{
  "name": "better/application",
  "require": {
     "another/library": "1.0.0",
     "another/framework": "1.2.3",
     "another/generator": "2.1.3"
  }, 
  "require-dev" : {
     "phpunit/phpunit" : "4.*",
  }
} 

我认为,“克隆”客户/客户端的应用程序并不是一个好主意,因为它忽略了插件依赖于应用程序的特定版本,这并不总是“最新”或“开发者” ”。让Composer为每个客户端按版本提取应用程序。

  

通过这种方式,我避免为所有客户创建一个巨大的composer.json共享不必要的包。

  • 为每个新客户/客户创建一个存储库
  • composer.json
  • 中添加应用程序本身和客户端请求的包
  • 在顶部添加客户端配置

例如,Client1的composer.json

{
  "name": "better/application-for-client1",
  "require": {
     "better/application": "1.0.0",
     "better/app-calculate": "1.2.3"
  }
} 

例如,Client2的composer.json

{
  "name": "better/application-for-client2",
  "require": {
     "better/application": "1.0.1",
     "better/app-calculate": "1.2.4",
     "better/app-message": "2.0.0"
  }
} 

每个客户可能都有自己的设置,需要使用不同版本的应用程序和不同的附加应用程序包/插件(此处使用前缀“app-”表示)。

最后,您有一个客户的两个基本文件:composer.json和配置文件。

(应用程序如何检测可用模块是另一个故事。至少,当您在应用程序的引导期间注册Composers Autoloader时,自动加载将开箱即用。)

(旁注:如果您的应用程序是一个多站点应用程序,那么您可以用“符号链接”替换“克隆”。对于多站点,我的意思是使用站点ID从一个中心位置运行的应用程序(通常是客户)如果你有一个包含所有开发包的应用程序文件夹放在一个整体文件夹中,那么通过清理开发内容来构建一个relase文件夹,这样你就可以得到一个带有空白默认配置的发行版本。然后对应用程序进行符号链接,请求包到客户文件夹并将配置放在最上面。这种方法可以节省相当多的磁盘空间,根本不涉及Composer。)

答案 2 :(得分:2)

我还鼓励你使用Jens A. Koch在他的回答中提出的方法,为每个客户提供一个composer.json文件,并要求主应用程序和所有必需的插件。 Composer非常支持这种情况,我想指出你的出发点:

作曲家类型

Composer允许为包指定types。您可以定义自己的类型来为应用程序标记插件。许多开源项目(例如Symfony with bundle)都采用了这种方法来实现插件生态系统。

自定义安装程序

您可以注册custom installers,该cplusplus' entry on map::insert()可以针对特定type作曲家包(即您为插件定义的类型)执行。然后,您可以自定义插件的安装过程,这意味着您可以:

  • 将您的自定义插件移动到特定位置
  • 自动调整插件配置,
  • 最重要的是:提供一种机制,允许主应用程序查看哪些插件可用。

答案 3 :(得分:1)

嗯..需要所有包裹..

这意味着一个大的composer.json,因为您的系统正在运行/与您的系统兼容。也许你将不得不引入一个版本控制系统..所以你最终可能会得到v1_composer.json ..

但是每个客户端只加载所需的包。例如,为每个客户端生成一个requires.php,其中包含必要的require语句,这些语句链接到您的共享库。这将是最快速的解决方案,效率最高,因为您共享可以共享的代码,并且只在需要时加载它

结论

尽可能多地共享代码......但在不需要时不要使用它。