Composer 資源庫(kù)

2018-09-28 20:23 更新

資源庫(kù)

本章將解釋包和庫(kù)的概念,什么樣的存儲(chǔ)庫(kù)是可用的,以及它們?nèi)绾喂ぷ鳌?/p>

概述

在此之前,我們看到存在不同類(lèi)型的資源庫(kù),我們需要了解一些基本概念,以理解 Composer 是如何構(gòu)建于其上的。

Composer 是一個(gè)依賴管理工具。它在本地安裝一些資源包。一個(gè)包本質(zhì)上就是一個(gè)包含東西的目錄。通常情況下它存儲(chǔ) PHP 代碼,但在理論上它可以是任何東西。并且它包含一個(gè)描述,其中有一個(gè)名稱和一個(gè)版本號(hào),這個(gè)名稱和版本號(hào)用于識(shí)別該包。

事實(shí)上,在 composer 內(nèi)部將每一個(gè)版本都視為一個(gè)單獨(dú)的包。盡管在你使用 composer 時(shí)這種區(qū)別無(wú)關(guān)緊要,但當(dāng)你想改變它時(shí),這就顯得至關(guān)重要。

除了名稱和版本號(hào),還存放了有用的元數(shù)據(jù)。與安裝關(guān)系最密切的是 source 信息,它申明了在哪里可以獲得資源包的內(nèi)容。包數(shù)據(jù)指向包內(nèi)容,并有兩種指向方式:dist 和 source。

Dist: dist 指向一個(gè)存檔,該存檔是對(duì)一個(gè)資源包的某個(gè)版本的數(shù)據(jù)進(jìn)行的打包。通常是已經(jīng)發(fā)行的穩(wěn)定版本。

Source: source 指向一個(gè)開(kāi)發(fā)中的源。這通常是一個(gè)源代碼倉(cāng)庫(kù),例如 git。當(dāng)你想要對(duì)下載下來(lái)的資源包進(jìn)行修改時(shí),可以這樣獲取。

你可以使用其中任意一個(gè),或者同時(shí)使用。這取決于其它的一些因素,比如“user-supplied 選項(xiàng)”和“包的穩(wěn)定性”,前者將會(huì)被優(yōu)先考慮。

資源庫(kù)

一個(gè)資源庫(kù)是一個(gè)包的來(lái)源。它是一個(gè) packages/versions 的列表。Composer 將查看所有你定義的 repositories 以找到你項(xiàng)目需要的資源包。

默認(rèn)情況下已經(jīng)將 Packagist.org 注冊(cè)到 Composer。你可以在 composer.json 中申明更多的資源庫(kù),把它們加入你的項(xiàng)目中。

資源庫(kù)的定義僅可用于“root 包”,而在你依賴的包中定義的資源庫(kù)將不會(huì)被加載。如果你想了解其中的原因,請(qǐng)閱讀 FAQ entry。

Types

Composer

主資源庫(kù)的類(lèi)型為 composer。它使用一個(gè)單一的 packages.json 文件,包含了所有的資源包元數(shù)據(jù)。

這也是 packagist.org 所使用的資源類(lèi)型。要引用一個(gè) composer 資源庫(kù),只需要提供一個(gè)存放 packages.json 文件的 目錄路徑。比如要引用 packagist.org 下的 /packages.json,它的 URL 就應(yīng)該是 packagist.org。而 example.org/packages.json 的 URL 應(yīng)該是 example.org。

packages

唯一必須的字段是 packages。它的 JSON 結(jié)構(gòu)如下:

{
    "packages": {
        "vendor/package-name": {
            "dev-master": { @composer.json },
            "1.0.x-dev": { @composer.json },
            "0.0.1": { @composer.json },
            "1.0.0": { @composer.json }
        }
    }
}

@composer.json 標(biāo)記將會(huì)從此包的指定版本中讀取 composer.json 的內(nèi)容,其內(nèi)至少應(yīng)包含以下信息:

  • name
  • version
  • dist or source

這是一個(gè)最簡(jiǎn)單的包定義:

{
    "name": "smarty/smarty",
    "version": "3.1.7",
    "dist": {
        "url": "http://www.smarty.net/files/Smarty-3.1.7.zip",
        "type": "zip"
    }
}

它還可以包含任何在 composer.json 架構(gòu) 中介紹的字段。

notify-batch

notify-batch 字段允許你指定一個(gè) URL,它將會(huì)在用戶安裝每一個(gè)包時(shí)被調(diào)用。該 URL 可以是(與其資源庫(kù)相同域名的)絕對(duì)路徑或者一個(gè)完整的 URL 地址。

例如使用下面的值:

{
    "notify-batch": "/downloads/"
}

對(duì)于 example.org/packages.json 包含的 monolog/monolog 包,它將會(huì)發(fā)送一個(gè) POST 請(qǐng)求到 example.org/downloads/,使用下面的 JSON request body:

{
    "downloads": [
        {"name": "monolog/monolog", "version": "1.2.1.0"},
    ]
}

version 字段將包含標(biāo)準(zhǔn)化的版本號(hào)。

notify-batch 字段是可選的。

includes

對(duì)于較大的資源庫(kù),可以拆分 packages.json 為多個(gè)文件。includes 字段允許你引用這些額外的文件。

實(shí)例:

{
    "includes": {
        "packages-2011.json": {
            "sha1": "525a85fb37edd1ad71040d429928c2c0edec9d17"
        },
        "packages-2012-01.json": {
            "sha1": "897cde726f8a3918faf27c803b336da223d400dd"
        },
        "packages-2012-02.json": {
            "sha1": "26f911ad717da26bbcac3f8f435280d13917efa5"
        }
    }
}

文件的 SHA-1 碼允許它被緩存,僅在 hash 值改變時(shí)重新請(qǐng)求。

此字段是可選的。你也許并不需要它來(lái)自定義存儲(chǔ)庫(kù)。

provider-includes and providers-url

的對(duì)于非常大的資源庫(kù),像 packagist.org 使用 so-called provider 文件是首選方法。provider-includes 字段允許你設(shè)置一個(gè)列表,來(lái)申明這個(gè)資源庫(kù)提供的包名稱。在這種情況下文件的哈希算法必須使用 sha256。

providers-url 描述了如何在服務(wù)器上找到這些 provider 文件。它是以資源庫(kù)的根目錄為起點(diǎn)的絕對(duì)路徑。

實(shí)例:

{
    "provider-includes": {
        "providers-a.json": {
            "sha256": "f5b4bc0b354108ef08614e569c1ed01a2782e67641744864a74e788982886f4c"
        },
        "providers-b.json": {
            "sha256": "b38372163fac0573053536f5b8ef11b86f804ea8b016d239e706191203f6efac"
        }
    },
    "providers-url": "/p/%package%$%hash%.json"
}

這些文件包含資源包的名稱以及哈希值,以驗(yàn)證文件的完整性,例如:

{
    "providers": {
        "acme/foo": {
            "sha256": "38968de1305c2e17f4de33aea164515bc787c42c7e2d6e25948539a14268bb82"
        },
        "acme/bar": {
            "sha256": "4dd24c930bd6e1103251306d6336ac813b563a220d9ca14f4743c032fb047233"
        }
    }
}

上述文件申明了 acme/fooacme/bar 可以在這個(gè)資源庫(kù)找到,通過(guò)加載由 providers-url 引用的文件,替換 %package% 為包名并且替換 %hash% 為 sha256 的值。這些文件本身只包含上文提到的 packages 的定義。

這些字段是可選的。你也許并不需要它們來(lái)自定義存儲(chǔ)庫(kù)。

stream options

packages.json 文件是用一個(gè) PHP 流加載的。你可以使用 options 參數(shù)來(lái)設(shè)定額外的流信息。你可以設(shè)置任何有效的PHP 流上下文選項(xiàng)。更多相關(guān)信息請(qǐng)查看 Context options and parameters。

VCS

VCS 表示版本控制系統(tǒng)。這包括像 git、svn 或 hg 這樣的版本管理系統(tǒng)。Composer 有一個(gè)資源類(lèi)型可以從這些系統(tǒng)安裝軟件包。

從 VCS 資源庫(kù)加載一個(gè)包

這里有幾個(gè)用例。最常見(jiàn)的是維護(hù)自己 fork 的第三方庫(kù)。如果你在項(xiàng)目中使用某些庫(kù),并且你決定改變這些庫(kù)內(nèi)的某些東西,你會(huì)希望你項(xiàng)目中使用的是你自己的修正版本。如果這個(gè)庫(kù)是在 GitHub 上(這種情況經(jīng)常出現(xiàn)),你可以簡(jiǎn)單的 fork 它并 push 你的變更到這個(gè) fork 里。在這之后你更新項(xiàng)目的 composer.json 文件,添加你的 fork 作為一個(gè)資源庫(kù),變更版本約束來(lái)指向你的自定義分支。關(guān)于版本約束的命名約定請(qǐng)查看 庫(kù)(資源包)。

例如,假設(shè)你 fork 了 monolog,在 bugfix 分支修復(fù)了一個(gè) bug:

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/igorw/monolog"
        }
    ],
    "require": {
        "monolog/monolog": "dev-bugfix"
    }
}

當(dāng)你運(yùn)行 php composer.phar update 時(shí),你應(yīng)該得到你修改的版本,而不是 packagist.org 上的 monolog/monolog

注意,你不應(yīng)該對(duì)包進(jìn)行重命名,除非你真的打算擺脫原來(lái)的包,并長(zhǎng)期的使用你自己的 fork。這樣 Composer 就會(huì)正確獲取你的包了。如果你確定要重命名這個(gè)包,你應(yīng)該在默認(rèn)分支(通常是 master 分支)上操作,而不是特性分支,因?yàn)榘拿秩∽阅J(rèn)分支。

如果其它包依賴你 fork 的這個(gè)分支,可能要對(duì)它做版本號(hào)的行內(nèi)別名設(shè)置,才能夠準(zhǔn)確的識(shí)別版本約束。更多相關(guān)信息請(qǐng)查看 別名。

使用私有資源庫(kù)

完全相同的解決方案,也可以讓你使用你 GitHub 和 BitBucket 上的私人代碼庫(kù)進(jìn)行工作:

{
    "require": {
        "vendor/my-private-repo": "dev-master"
    },
    "repositories": [
        {
            "type": "vcs",
            "url":  "git@bitbucket.org:vendor/my-private-repo.git"
        }
    ]
}

唯一的要求是為一個(gè) git 客戶端安裝 SSH 秘鑰。

Git 的備選方案

Git 并不是 VCS 資源庫(kù)唯一支持的版本管理系統(tǒng)。

以下幾種都是被支持的:

為了從這些系統(tǒng)獲取資源包,你必須安裝對(duì)應(yīng)的客戶端,這可能是不方便的?;谶@個(gè)原因,這里提供了 GitHub 和 BitBucket 的 API 的特殊支持,以便在無(wú)需安裝版本控制系統(tǒng)的情況下獲取資源包。在 VCS 資源庫(kù)提供的 dist 中獲取 zip 存檔。

VCS 驅(qū)動(dòng)將基于 URL 自動(dòng)檢測(cè)版本庫(kù)類(lèi)型。但如果可能,你需要明確的指定一個(gè) git、svnhg 作為資源庫(kù)類(lèi)型,而不是 vcs。

If you set the no-api key to true on a github repository it will clone the repository as it would with any other git repository instead of using the GitHub API. But unlike using the git driver directly, composer will still attempt to use github's zip files.

Subversion 選項(xiàng)

由于 Subversion 沒(méi)有原生的分支和標(biāo)簽的概念,Composer 假設(shè)在默認(rèn)情況下該代碼位于 $url/trunk、$url/branches$url/tags 內(nèi)。如果你的存儲(chǔ)庫(kù)使用了不同的布局,你可以更改這些值。例如,如果你使用大寫(xiě)的名稱,你可以像這樣配置資源庫(kù):

{
    "repositories": [
        {
            "type": "vcs",
            "url": "http://svn.example.org/projectA/",
            "trunk-path": "Trunk",
            "branches-path": "Branches",
            "tags-path": "Tags"
        }
    ]
}

如果你的存儲(chǔ)庫(kù)目錄中沒(méi)有任何分支或標(biāo)簽文件夾,你可以將 branches-pathtags-path 設(shè)置為 false。

如果是一個(gè)位于子目錄的包,例如, /trunk/foo/bar/composer.json/tags/1.0/foo/bar/composer.json,那么你可以讓 composer 通過(guò) "package-path" 選項(xiàng)設(shè)置的子目錄進(jìn)行訪問(wèn),在這個(gè)例子中可以將其設(shè)置為 "package-path": "foo/bar/"。

PEAR

pear 類(lèi)型資源庫(kù),使得從任何 PEAR 渠道安裝資源包成為可能。Composer 將為所有此類(lèi)型的包增加前綴(類(lèi)似于 pear-{渠道名稱}/)以避免沖突。而在之后使用別名時(shí)也增加前綴(如 pear-{渠道別名}/)。

例如使用 pear2.php.net

{
    "repositories": [
        {
            "type": "pear",
            "url": "http://pear2.php.net"
        }
    ],
    "require": {
        "pear-pear2.php.net/PEAR2_Text_Markdown": "*",
        "pear-pear2/PEAR2_HTTP_Request": "*"
    }
}

在這種情況下渠道的簡(jiǎn)稱(別名)是 pear2,因此 PEAR2_HTTP_Request 包的名稱應(yīng)該寫(xiě)作 pear-pear2/PEAR2_HTTP_Request。

注意: pear 類(lèi)型的資源庫(kù)對(duì)每個(gè) requires 都要做完整的請(qǐng)求,因此可能大大降低安裝速度。

自定義供應(yīng)商別名

通過(guò)自定義供應(yīng)商名稱,對(duì) PEAR 渠道包進(jìn)行別名是允許的。

例:

假設(shè)你有一個(gè)私人 PEAR 庫(kù),并希望使用 Composer 從 VCS 集成依賴。你的 PEAR 庫(kù)包含以下資源包:

  • BasePackage。
  • IntermediatePackage 依賴于 BasePackage。
  • TopLevelPackage1TopLevelPackage2 都依賴于 IntermediatePackage。

如果沒(méi)有一個(gè)供應(yīng)商別名,Composer 將使用 PEAR 渠道名稱作為包名的一部分:

  • pear-pear.foobar.repo/BasePackage
  • pear-pear.foobar.repo/IntermediatePackage
  • pear-pear.foobar.repo/TopLevelPackage1
  • pear-pear.foobar.repo/TopLevelPackage2

假設(shè)之后的某個(gè)時(shí)間,你希望將你的 PEAR 包遷移,使用 Composer 資源庫(kù)和命名方案,并且采用 foobar 作為供應(yīng)商名稱。這樣之前使用 PEAR 包的項(xiàng)目將不會(huì)看到更新的資源包,因?yàn)樗鼈冇胁煌墓?yīng)商名稱(foobar/IntermediatePackagepear-pear.foobar.repo/IntermediatePackage)。

你可以通過(guò)從一開(kāi)始就為 PEAR 資源庫(kù)指定 vendor-alias 來(lái)避免這種情況的發(fā)生,以得到一個(gè)不會(huì)過(guò)時(shí)的包名。

為了說(shuō)明這一點(diǎn),下面的例子會(huì)從你的 PEAR 資源庫(kù)中得到 BasePackageTopLevelPackage1TopLevelPackage2 資源包,并從 Github 資源庫(kù)中獲取 IntermediatePackage 資源包:

{
    "repositories": [
        {
            "type": "git",
            "url": "https://github.com/foobar/intermediate.git"
        },
        {
            "type": "pear",
            "url": "http://pear.foobar.repo",
            "vendor-alias": "foobar"
        }
    ],
    "require": {
        "foobar/TopLevelPackage1": "*",
        "foobar/TopLevelPackage2": "*"
    }
}

Package

如果你想使用一個(gè)項(xiàng)目,它無(wú)法通過(guò)上述任何一種方式支持 composer,你仍然可以使用 package 類(lèi)型定義資源庫(kù)。

基本上,你可以定義與 packages.jsoncomposer 類(lèi)型資源庫(kù)相同的信息,但需要為每個(gè)這樣的資源包分別定義。同樣,至少應(yīng)該包含以下信息:name、version、(distsource)。

這是一個(gè) smarty 模板引擎的例子:

{
    "repositories": [
        {
            "type": "package",
            "package": {
                "name": "smarty/smarty",
                "version": "3.1.7",
                "dist": {
                    "url": "http://www.smarty.net/files/Smarty-3.1.7.zip",
                    "type": "zip"
                },
                "source": {
                    "url": "http://smarty-php.googlecode.com/svn/",
                    "type": "svn",
                    "reference": "tags/Smarty_3_1_7/distribution/"
                },
                "autoload": {
                    "classmap": ["libs/"]
                }
            }
        }
    ],
    "require": {
        "smarty/smarty": "3.1.*"
    }
}

通常你不需要去定義 source,因?yàn)槟悴⒉皇钦娴男枰?/p>

注意: 該資源庫(kù)類(lèi)型存在以下限制,因此應(yīng)盡可能避免使用:

  • Composer 將不會(huì)更新資源包,除非你修改了 version 字段。
  • Composer 將不會(huì)更新 commit references,因此如果你使用 master reference,將不得不刪除該程序包以強(qiáng)制更新,并且將不得不面對(duì)一個(gè)不穩(wěn)定的 lock 文件。

Hosting your own

盡管大部分的時(shí)間,你大概都會(huì)把資源包放在 packagist.org 上,但這里還將告訴你一些用例,以便你可以自行托管資源庫(kù)。

  • Private company packages: 如果你是一個(gè)公司的職員,對(duì)公司內(nèi)部的資源包使用 composer,你可能會(huì)想讓這些包保持私有的狀態(tài)。

  • Separate ecosystem: 如果你的項(xiàng)目有自己的生態(tài)系統(tǒng),并且自己的資源包不需要被其它項(xiàng)目所復(fù)用,你可能會(huì)想將它們從 packagist.org 上分離出來(lái)。其中一個(gè)例子就是 wordpress 的插件。

對(duì)于自行托管的軟件包,建議使用 composer 類(lèi)型資源庫(kù)設(shè)置,它將提供最佳的性能。

這里有一些工具,可以幫助你創(chuàng)建 composer 類(lèi)型的資源庫(kù)。

Packagist

packagist 的底層是開(kāi)源的。這意味著你可以只安裝你自己拷貝的 packagist,改造并使用它。這真的是很直接簡(jiǎn)單的事情。然而,由于其規(guī)模和復(fù)雜性,對(duì)于大多數(shù)中小型企業(yè)還是建議使用 Satis。

Packagist 是一個(gè) Symfony2 應(yīng)用程序,并且托管在 GitHub 上 github.com/composer/packagist。它內(nèi)部使用了 composer 并作為 VCS 資源庫(kù)與 composer 用戶之間的代理。它擁有所有 VCS 資源包的列表,定期重新抓取它們,并將其作為一個(gè) composer 資源庫(kù)。

要設(shè)置你的副本,只需要按照 github.com/composer/packagist 的說(shuō)明進(jìn)行操作。

Satis

Satis 是一個(gè)靜態(tài)的 composer 資源庫(kù)生成器。它像是一個(gè)超輕量級(jí)的、基于靜態(tài)文件的 packagist 版本。

你給它一個(gè)包含 composer.json 的存儲(chǔ)庫(kù),定義好 VCS 和 資源庫(kù)。它會(huì)獲取所有你列出的包,并打印 packages.json 文件,作為 composer 類(lèi)型的資源庫(kù)。

更多詳細(xì)信息請(qǐng)查看 github.com/composer/satis 和 Satis article。

Artifact

在某些情況下,或許沒(méi)有能力擁有之前提到的任何一種線上資源庫(kù)。Typical example could be cross-organisation library exchange through built artifacts。當(dāng)然大部分的時(shí)間他們都是私有的。為了簡(jiǎn)化維護(hù),可以簡(jiǎn)單的使用 artifact 資源庫(kù)類(lèi)型,來(lái)引用一個(gè)包含那些私有包的 ZIP 存檔的文件夾:

{
    "repositories": [
        {
            "type": "artifact",
            "url": "path/to/directory/with/zips/"
        }
    ],
    "require": {
        "private-vendor-one/core": "15.6.2",
        "private-vendor-two/connectivity": "*",
        "acme-corp/parser": "10.3.5"
    }
}

每個(gè) zip artifact 都只是一個(gè) ZIP 存檔,放置在 composer.json 所在的根目錄:

unzip -l acme-corp-parser-10.3.5.zip

composer.json
...

如果有兩個(gè)不同版本的資源包,它們都會(huì)被導(dǎo)入。當(dāng)有一個(gè)新版本的存檔被添加到 artifact 文件夾,并且你運(yùn)行了 update 命令,該版本就會(huì)被導(dǎo)入,并且 Composer 將更新到最新版本。

禁用 Packagist

你可以在 composer.json 中禁用默認(rèn)的 Packagist 資源庫(kù)。

{
    "repositories": [
        {
            "packagist": false
        }
    ]
}
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)