Composer 自定義安裝程序

2018-09-28 20:24 更新

自定義安裝程序

概要

有時需要在包的安裝過程中執(zhí)行其它的動作,例如:將它安裝在默認(rèn)的 vendor 以外的其它目錄。

在這些情況下,你可以考慮創(chuàng)建一個自定義安裝程序來處理特定的邏輯。

調(diào)用自定義安裝程序

假設(shè)你的項(xiàng)目已經(jīng)有了一個自定義的安裝模塊,那么如何根據(jù) 安裝類型 正確調(diào)用你包文件中的安裝程序就成為了一個問題。

參見見下一章,如何通過指令創(chuàng)建自定義安裝程序。

任何自定義安裝程序都要通過 type 屬性來識別。一旦被確認(rèn),它將完全覆蓋默認(rèn)的安裝程序,并執(zhí)行自己的安裝邏輯。

一個實(shí)際用例:

phpDocumentor 的特殊模板需要安裝在 /vendor 以外的其它目錄中。 因此他們選擇 phpdocumentor-template 安裝類型 并為此類型創(chuàng)建了一個插件,以便將他們的模板發(fā)送到正確的目錄中。

在這樣一個模板包的例子中 composer.json 將使用以下設(shè)置:

{
    "name": "phpdocumentor/template-responsive",
    "type": "phpdocumentor-template",
    "require": {
        "phpdocumentor/template-installer-plugin": "*"
    }
}

重要提示: 為了確保這個模板安裝程序在安裝模板包之前就已存在,模板包必須寫入對此安裝程序包的依賴。

創(chuàng)建一個安裝程序

一個自定義安裝程序通常是以 Composer 插件的形式存在,并包含有一個類,它實(shí)現(xiàn)了 Composer\Installer\InstallerInterface 這個接口。

一個基本的安裝程序插件必須由3個文件組成:

  1. 包文件:composer.json
  2. 插件類,例如:My\Project\Composer\Plugin.php,其中的類必須實(shí)現(xiàn) Composer\Plugin\PluginInterface 接口。
  3. 安裝程序類,例如:My\Project\Composer\Installer.php,其中的類必須實(shí)現(xiàn) Composer\Installer\InstallerInterface 接口。

composer.json

此處的包文件和普通資源包是相同的,但需要滿足以下條件:

  1. type 屬性必須是 composer-plugin。
  2. extra 屬性必須包含 class 元素,它定義了插件類的名稱(包含命名空間)。如果這個包有多個插件類,可以使用數(shù)組的形式進(jìn)行定義。

實(shí)例:

{
    "name": "phpdocumentor/template-installer-plugin",
    "type": "composer-plugin",
    "license": "MIT",
    "autoload": {
        "psr-0": {"phpDocumentor\\Composer": "src/"}
    },
    "extra": {
        "class": "phpDocumentor\\Composer\\TemplateInstallerPlugin"
    },
    "require": {
        "composer-plugin-api": "1.0.0"
    }
}

插件類

這個類定義了 Composer 的插件,它必須實(shí)現(xiàn) Composer\Plugin\PluginInterface 這個接口。它可以在 activate() 方法中注冊自定義安裝程序。

這個類可以被放在任何位置、使用任何名字,只要能夠根據(jù) extra.class 中的定義被自動加載即可。

實(shí)例:

<?php

namespace phpDocumentor\Composer;

use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;

class TemplateInstallerPlugin implements PluginInterface
{
    public function activate(Composer $composer, IOInterface $io)
    {
        $installer = new TemplateInstaller($io, $composer);
        $composer->getInstallationManager()->addInstaller($installer);
    }
}

自定義安裝程序類

這個類用于執(zhí)行自定義的安裝過程,它必須實(shí)現(xiàn) Composer\Installer\InstallerInterface 這個接口(或者繼承了另一個實(shí)現(xiàn)此接口的安裝程序類)。它將會對安裝類型中定義的字符串執(zhí)行 supports() 方法驗(yàn)證,一旦通過就采用對應(yīng)的安裝程序。

注意: 請慎重選擇你的 安裝類型 名稱,建議遵循這樣的格式:vendor-type。例如:phpdocumentor-template。

InstallerInterface 類定義了以下方法(請查閱源碼以獲得更詳細(xì)的信息):

  • supports() 在這里測試你發(fā)布的這個安裝程序名稱是否通過 安裝類型 匹配(參見示例)。只有正確匹配的資源包才會使用此安裝程序進(jìn)行安裝。
  • isInstalled() 確定支持的資源包是否已安裝。
  • install() 這里你可以定義在安裝時需要執(zhí)行的動作。
  • update() 這里你可以定義在更新時需要執(zhí)行的動作。當(dāng) Composer 調(diào)用更新參數(shù)時這是必須的。
  • uninstall() 這里你可以定義在移除一個包時需要執(zhí)行的動作。
  • getInstallPath() 這個方法需要返回一個資源包將要安裝的位置。相對于 composer.json 文件的位置。

實(shí)例:

<?php

namespace phpDocumentor\Composer;

use Composer\Package\PackageInterface;
use Composer\Installer\LibraryInstaller;

class TemplateInstaller extends LibraryInstaller
{
    /**
     * {@inheritDoc}
     */
    public function getPackageBasePath(PackageInterface $package)
    {
        $prefix = substr($package->getPrettyName(), 0, 23);
        if ('phpdocumentor/template-' !== $prefix) {
            throw new \InvalidArgumentException(
                'Unable to install template, phpdocumentor templates '
                .'should always start their package name with '
                .'"phpdocumentor/template-"'
            );
        }

        return 'data/templates/'.substr($package->getPrettyName(), 23);
    }

    /**
     * {@inheritDoc}
     */
    public function supports($packageType)
    {
        return 'phpdocumentor-template' === $packageType;
    }
}

這個例子演示了,簡單的繼承 Composer\Installer\LibraryInstaller 類來剝離 phpdocumentor/template- 前綴,并用剩余的部分重新組裝了一個完全不同的安裝路徑。

并非安裝在 /vendor 目錄,任何使用這個安裝程序的資源包,將被放置在 /data/templates/<stripped name> 目錄中。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號