vendor-patch / dflydev.embedded-composer
将 Composer 集成到另一个应用程序中+分支
Requires
- php: >=7.2 || >=8.2
- composer/composer: ^1.0 || >=2.0
Requires (Dev)
Suggests
- frdlweb/recommendations: *
- symfony/console: *
- symfony/http-kernel: *
This package is auto-updated.
Last update: 2024-09-14 05:24:05 UTC
README
将 Composer 集成到另一个应用程序中。
安装
通过 Composer 作为 dflydev/embedded-composer 安装。
我为什么要嵌入 Composer 呢?
想象一下,一个以 phar 形式发布的控制台应用程序。如果希望该应用程序能够根据其所在的目录进行扩展(比如说,一个目录应使用一组插件,而另一个目录应使用完全不同的插件集),那么不能简单地在这两个目录中定义一个 composer.json
并运行 composer install
。
为什么不行?因为应用程序附带了一套特定的依赖。Composer 在不引入冲突风险的情况下不能添加更多依赖。答案是,将 Composer 集成到应用程序中,以便 Composer 可以将已安装的应用程序依赖与特定目录的 composer.json
中定义的依赖合并。
最终结果是,一套满足特定目录要求的依赖,同时考虑了控制台应用程序已安装的依赖。
虽然这对于分发的 phar 应用程序是必需的,但这种技术可以应用于任何需要运行时扩展的全局安装的应用程序。
使用方法
基础知识
以下是一个示例 bin/myapp
样式的脚本,它可以用于通过 Composer 安装(vendor/bin/myapp
)或全局安装(/usr/local/bin/myapp
)。
myapp.php (bin)
一个用于从应用程序初始化嵌入式 Composer 的共享代码块。
<?php // assume $classLoader is somehow defined prior to this block of // code and contains the Composer class loader from the command // // see next two blocks of code use Dflydev\EmbeddedComposer\Core\EmbeddedComposerBuilder; use Symfony\Component\Console\Input\ArgvInput; $input = new ArgvInput; $projectDir = $input->getParameterOption('--project-dir') ?: '.'; $embeddedComposerBuilder = new EmbeddedComposerBuilder( $classLoader, $projectDir ); $embeddedComposer = $embeddedComposerBuilder ->setComposerFilename('myapp.json') ->setVendorDirectory('.myapp') ->build(); $embeddedComposer->processAdditionalAutoloads(); // application is now ready to be run taking both the embedded // dependencies and directory specific dependencies into account.
myapp (bin)
示例 bin 脚本(bin/myapp
),它在其找到正确的自动加载器后需要共享代码块。
#!/usr/bin/env php <?php if ( // Check where autoload would be if this is myapp included // as a dependency. (!$classLoader = @include __DIR__.'/../../../autoload.php') and // Check where autoload would be if this is a development version // of myapp. (based on actual file) (!$classLoader = @include __DIR__.'/../vendor/autoload.php') ) { die('You must set up the project dependencies, run the following commands: composer install '); } include('myapp.php');
myapp-phar-stub (bin)
示例 phar stub(bin/myapp-phar-stub
),可以在需要之前用于引导 phar 应用程序。
#!/usr/bin/env php <?php if (!$classLoader = @include __DIR__.'/../vendor/autoload.php') { die ('There is something terribly wrong with your archive. Try downloading it again?'); } include('myapp.php');
还有什么...
通过名称查找已安装的包
可以使用 findPackage
方法搜索 Composer 安装的任何包
<?php $package = $embeddedComposer->findPackage('acme/myapp');
Composer 目前尚未在 installed.json
中安装表示本地存储库的根包。为此有一个 PR 旨在将其添加到 Composer 核心,但在那时之前,可以使用以下方法作为替代。
将以下 post-autoload-dump
脚本添加到根包的 composer.json
{ "scripts": { "post-autoload-dump": "Dflydev\\EmbeddedComposer\\Core\\Script::postAutoloadDump" } }
这将把额外的存储库写入到 vendor/dflydev/embedded-composer/.root_package.json
,嵌入式 Composer 会自动使用它,如果找到它的话。如果根包需要包含在分发中,则确保该文件是 phar 构建的组成部分。
创建 Composer 安装程序实例
安装程序实例适用于处理针对外部配置的 install
和 update
操作。它将在解决依赖关系时考虑内部(嵌入式)配置。
<?php // requires creating an IOInterface instance $installer = $embeddedComposer->createInstaller($io);
创建纯 Composer 实例
<?php // requires creating an IOInterface instance $composer = $embeddedComposer->createComposer($io);
许可
MIT,请参阅 LICENSE。
社区
如果您有疑问或想帮忙,请加入我们 irc.freenode.net 上的 #dflydev 频道。
非原创
这里的许多工作都得到了 Composer 团队和许多在 #composer-dev
的人的支持。
实际代码最初是作为 Sculpin 的一部分出现的,后来被独立成一个项目。