如何使用内置的composer-plugin创建单片Composer包?

时间:2016-09-08 11:18:51

标签: php json composer-php composer-plugin

我希望我的软件包附带一个内置的composer-plugin。

我有这样的结构:

composer.json
src/
    ...
plugin/
    composer.json
    src/
        ...

composer.json配置如下:

{
    "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 plugin/composer.json就像这样:

{
    "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包的任何类时生成致命的“类未找到错误”。

好像作曲家忘记了foo/bar-plugin需要foo/bar的事实,并且由于某种原因,它的类不能自动加载。

有什么理由不应该这样吗?为什么不呢?

当然我可以将这些东西打包在单独的外部软件包中,但这没有多大意义,因为这些软件包只会依赖于彼此 - 它们实际上是一个单元,将它们打包为两个软件包将导致每次小的更改都会导致主要版本的增加,因为foo/bar的每个版本基本上都会中断foo/bar-plugin

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

1 个答案:

答案 0 :(得分:1)

如果插件基本上是包的一部分,则不应使用它。 Composer提供替代方案。

正如Jens在对你的问题的评论中提到的那样,有一些脚本'密钥composer.json。您可以在里面调用shell命令,但也可以调用静态类方法。

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

  

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

(我的旁注 - 这也大致适用于插件)。

无论如何 - 为您提供解决方案:丢弃'插件'做法。而是修改您的composer.json文件,使其如下所示:

composer.json

{
    "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 /作曲/ Plugin.php

<?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的

<?php

namespace Foo\Bar;

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

运行此选项并检查它是如何播放的。