首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用内置的composer-plugin创建一个整体式的Composer包?

如何使用内置的composer-plugin创建一个整体式的Composer包?
EN

Stack Overflow用户
提问于 2016-09-08 19:18:51
回答 1查看 660关注 0票数 16

我希望我的包与一个内置的composer插件一起发货。

我有一个这样的结构:

代码语言:javascript
复制
composer.json
src/
    ...
plugin/
    composer.json
    src/
        ...

composer.json的配置如下:

代码语言:javascript
复制
{
    "name": "foo/bar",
    "type": "library",
    "autoload": {
        "psr-4": {
            "Foo\\Bar\\": "src/"
        }
    },
    "repositories": [
        {
            "type": "path",
            "url": "./tools",
            "options": {
                "symlink": false
            }
        }
    ],
    "require": {
        "foo/bar-plugin": "*"
    }
}

内置composer插件的plugin/composer.json如下所示:

代码语言:javascript
复制
{
    "name": "foo/bar-plugin",
    "type": "composer-plugin",
    "require": {
        "composer-plugin-api": "^1",
        "composer/composer": "^1",
        "foo/bar": "*"
    },
    "autoload": {
        "psr-4": {
            "Foo\\Bar\\Plugin\\": "src/"
        }
    },
    "extra": {
        "class": "Foo\\Bar\\Plugin\\MyComposerPlugin"
    }
}

注意这里有一个双向依赖关系--插件依赖于foo/bar,而项目本身依赖于foo/bar-plugin

这就是奇怪的地方。在使用composer installcomposer update进行全新安装的过程中,一切都很好--插件做它自己的事情,这意味着现在只需要在控制台上宣布它自己。

现在,在安装之后,如果我只输入composer,我应该会看到插件宣布自己,和以前一样,对吧?

相反,只要它试图引用属于foo/bar包的任何类,它就会生成一个致命的"class not found error“。

这就好像composer忘记了这样一个事实:foo/bar-plugin需要foo/bar,而且出于某种原因,它的类是不可自动加载的。

这有什么不可能的原因吗?为什么不行?

当然,我可以只将这些东西打包到单独的外部包中,但这没有多大意义,因为这些包只是相互依赖-它们实际上是一个单元,将它们打包为两个包将导致一片混乱,每个小的变化都会导致主要版本的增加,因为基本上每个foo/bar版本都会破坏foo/bar-plugin

理想情况下,我想简单地将composer-plugin直接添加到主包中,但由于某些原因,这似乎是不可能的?似乎只有类型为composer-plugin的包才能添加插件?

EN

回答 1

Stack Overflow用户

发布于 2017-08-09 20:06:38

如果插件本质上是包的一部分,那么您就不应该这样使用它。Composer提供了其他选择。

正如延斯在对你的问题的评论中提到的那样,在composer.json中有“脚本”键。您可以在内部调用shell命令,也可以调用静态类方法。

关于插件解决方案- composer在其网站上明确提到了这一点:

在安装或更新之前,

Composer不会假设依赖项的状态。因此,不应在pre--cmd或pre-install-cmd事件挂接中指定需要Composer管理的依赖项的脚本。如果您需要在安装或更新之前执行脚本,请确保它们包含在您的根包中。

(我的侧记--这也大致适用于插件)。

不管怎样--给你提供一个解决方案:放弃“插件”方法。而是修改您的composer.json文件,使其如下所示:

composer.json

代码语言:javascript
复制
{
    "name": "foo/bar",
    "type": "library",
    "autoload": {
        "psr-4": {
            "Foo\\Bar\\": "src/"
        }
    },
    "require": {
    },

    "scripts": {
        "post-install-cmd": [
            "Foo\\Bar\\Composer\\Plugin::postInstall"
        ],
        "post-update-cmd": [
            "Foo\\Bar\\Composer\\Plugin::postUpdate"
        ]        
    }

}

此外,在src/Composer文件夹中创建Plugin.php

src/Composer/Plugin.php

代码语言:javascript
复制
<?php

namespace Foo\Bar\Composer;

use Foo\Bar\Test;

/**
 * Composer scripts.
 */
class Plugin
{
    public static function postInstall()
    {
        print_r("POST INSTALL\n");
        print_r(Test::TEST_CONST);
        print_r("\n");
    }

    public static function postUpdate()
    {
        print_r("POST UPDATE\n");
        print_r(Test::TEST_CONST);
        print_r("\n");
    }
}

如您所见,它打印来自Test类的常量。在src/中创建

src/Test.php

代码语言:javascript
复制
<?php

namespace Foo\Bar;

/**
 * Test class.
 */
class Test
{
    const TEST_CONST = "HERE I AM";
}

运行这个并检查它是如何运行的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39389543

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档