依赖管理工具 Composer 提供了多种在 PHP:超文本预处理器 (PHP) 项目中引入 Git 仓库的方法。
在许多情况下,仓库已在 Packagist 上创建,因此使用 Composer 引入它们非常简单。但是,当仓库尚未在 Packagist 上创建为软件包时,您该怎么办?您可以使用 Composer 直接从仓库引入软件包。本文将解释如何操作。
注意: 本文中的一些术语可能会令人困惑,因为多个词语被用来描述不同的事物。这里有一个快速词汇表,希望能有所帮助
- 项目: 您正在构建的自定义软件。这可以是网站、命令行实用程序、应用程序或您能想到的任何其他东西。
- 软件包: 您想要下载并在项目中使用任何第三方软件。它可以是库、Drupal 主题、WordPress 插件或任何其他数量的东西。
- Git 仓库: 也称为 Git repo,这是软件包的版本控制主机。常见的托管平台包括 GitHub、GitLab 或 Bitbucket,但任何可通过 URL 访问的 Git 仓库都适用于本教程。
- Composer 仓库: 在
composer.json
文件中,有一个名为 “repositories” 的可选属性。此属性是您可以定义 Composer 在下载软件包时查找新位置的地方。
当使用 Composer 将 Git repo 添加到您的项目时,您可能会发现自己处于两种情况:要么 repo 包含一个 composer.json
文件,该文件定义了在需要时应如何处理 repo;要么不包含。在两种情况下,您都可以使用不同的方法将 Git 仓库添加到您的项目中。
包含 composer.json 的 Git 仓库
当仓库包含 composer.json
文件时,它定义了自身的一些方面,这些方面对于 Composer 如何管理软件包很重要。这是一个软件包可能包含的简单 composer.json
文件示例
{
"name": "mynamespace/my-custom-library",
"type": "library"
}
此示例显示了 composer.json
文件可以定义的两个重要属性
- 名称: 软件包的命名空间名称。在本例中,“mynamespace” 是软件包 “my-custom-library” 的命名空间。
- 类型: repo 代表的软件包类型。软件包类型用于安装逻辑。Composer 开箱即用地支持以下软件包类型:library、project、metapackage 和 composer-plugin。
您可以通过查看任何流行的 GitHub 项目的 composer.json
文件来验证这一点。它们都在文件顶部附近定义了软件包名称和软件包类型。当仓库在其 composer.json
文件中定义了此信息时,在您的项目中引入仓库就非常简单。
引入包含 composer.json 文件的 Git 仓库
在您确定了包含 composer.json
文件的 Git 仓库后,您可以将该仓库作为软件包引入到您的项目中。
在您的项目的 composer.json
文件中,您需要定义一个新的属性(假设它尚不存在),名为 “repositories”。repositories 属性的值是一个对象数组,每个对象都包含有关您要包含在项目中的仓库的信息。请考虑以下自定义项目的 composer.json
文件。
{
"name": "mynamespace/my-project-that-uses-composer",
"repositories": [
{
"type": "vcs",
"url": "https://github.com/mynamespace/my-custom-library.git"
}
],
"require": {
"mynamespace/my-custom-library": "dev-master"
}
}
您在这里做了两件重要的事情。首先,您定义了一个新的仓库,Composer 在引入软件包时可以引用它。其次,您正在从新定义的仓库中引入软件包。
注意: 软件包版本是 require 语句的一部分,而不是 repository 属性的一部分。您可以通过选择名为 “dev-<分支名称>” 的版本来引入 repo 的特定分支。
如果您在此文件的上下文中运行 composer install
,Composer 将在定义的 URL 处查找项目。如果该 URL 代表一个包含 composer.json
文件的 Git repo,该文件定义了其名称和类型,则 Composer 会将该软件包下载到您的项目中并将其放置在适当的位置。
自定义软件包类型
上面显示的示例软件包类型为 “library”,但对于 WordPress 和 Drupal,您处理的是插件、模块和主题。当在您的项目中引入特殊的软件包类型时,重要的是将它们安装在项目文件结构中的特定位置。如果您能说服 Composer 将这些类型的软件包视为特殊情况,那岂不是很好吗?幸运的是,您有福了。有一个官方的 Composer 插件可以为您做到这一点。
Installers Composer 插件包含处理各种项目众多不同软件包类型所需的自定义逻辑。当处理具有众所周知且受支持的软件包安装步骤的项目时,它非常有用。
此项目允许您为各种项目定义软件包类型,例如 drupal-theme、drupal-module、wordpress-plugin、wordpress-theme 等。在 drupal-theme 软件包的情况下,Installers 插件会将所需的 repo 放置在 Drupal 安装的 /themes/contrib
文件夹中。
这是一个 composer.json
文件的示例,该文件可能作为 Drupal 主题项目自身的 Git 仓库存在
{
"name": "mynamespace/whatever-i-call-my-theme",
"type": "drupal-theme",
"description": "Drupal 8 theme",
"license": "GPL-2.0+"
}
请注意,这里唯一有意义的区别是类型现在是 drupal-theme。定义了 drupal-theme 类型后,任何使用 Installers 插件的项目都可以轻松地在其 Drupal 项目中引入您的 repo,并且它将被视为贡献主题。
使用 Composer 引入任何 Git 仓库
当您要包含在项目中的 repo 没有使用 composer.json
文件定义关于自身的任何信息时,会发生什么?当 repo 没有定义其名称或类型时,您必须在项目的 composer.json
文件中为 repo 定义该信息。看一看这个例子
{
"name": "mynamespace/my-project-that-uses-composer",
"repositories": [
{
"type": "package",
"package": {
"name": "mynamespace/my-custom-theme",
"version": "1.2.3",
"type": "drupal-theme",
"source": {
"url": "https://github.com/mynamespace/my-custom-theme.git",
"type": "git",
"reference": "master"
}
}
}
],
"require": {
"mynamespace/my-custom-theme": "^1",
"composer/installers": "^1"
}
}
请注意,您的仓库类型现在是 “package”。您将在其中定义有关您要引入的软件包的所有信息。
创建一个名为 “package” 的新对象,您可以在其中定义 Composer 需要知道的所有基本信息,以便能够将此任意 git repo 包含在您的项目中,包括
- 名称: 命名空间的软件包名称。它应该与您要引入的仓库匹配,但不是必须的。
- 类型: 软件包的类型。这反映了您希望 Composer 如何处理此仓库。
- 版本: repo 的版本号。您需要自己 придумать 一个。
- 来源: 包含以下仓库信息的对象
- URL: 可以在其中找到软件包 repo 的 Git 或其他版本控制系统 (VCS) URL
- 类型: 软件包的 VCS 类型,例如 git、svn、cvs 等
- 引用: 您要下载的分支或标签
我建议您查看关于 Composer 软件包仓库的 官方文档。请注意,也可以将 zip 文件作为 Composer 软件包包含在内。本质上,您现在负责 Composer 如何处理此仓库的所有部分。由于仓库本身没有向 Composer 提供任何信息,因此您有责任确定几乎所有内容,包括软件包的当前版本号。
这种方法允许您将几乎任何东西作为 Composer 软件包包含在您的项目中,但它有一些明显的缺点
- 除非您更改
version
字段,否则 Composer 不会更新软件包。
- Composer 不会更新提交引用。如果您使用
master
作为引用,则必须删除软件包才能强制更新,并且您将不得不处理不稳定的 lock 文件。
自定义软件包版本
在您的 composer.json
文件中维护软件包版本并非总是必要的。Composer 足够智能,可以查找 GitHub releases 并将其用作软件包版本。但最终您可能会想要包含一个只有几个分支且没有官方 releases 的简单项目。
当仓库没有 releases 时,您将负责决定仓库分支代表您项目的哪个版本。换句话说,如果您希望 composer 更新软件包,则需要在运行 composer update
之前增加项目中 composer.json
文件中定义的 “version”。
覆盖 Git 仓库的 composer.json
当定义类型为 package 的新 Composer 仓库时,您可以覆盖软件包自身的 composer.json
定义。考虑一个 Git 仓库,它在 composer.json
中将自身定义为 library,但您知道该代码实际上是一个 drupal-theme。您可以使用上述方法将 Git 仓库作为 drupal-theme 包含在您的项目中,从而允许 Composer 在需要时适当地处理代码。
示例:引入 Guzzle 作为 drupal-theme,只是为了证明您可以这样做。
{
"name": "mynamespace/my-project-that-uses-composer",
"repositories": [
{
"type": "package",
"package": {
"name": "mynamespace/guzzle-theme",
"version": "1.2.3",
"type": "drupal-theme",
"source": {
"url": "https://github.com/guzzle/guzzle.git",
"type": "git",
"reference": "master"
}
}
}
],
"require": {
"mynamespace/guzzle-theme": "^1",
"composer/installers": "^1"
}
}
这可行!您已下载 Guzzle 库并将其放置在 Drupal 项目的 /themes
文件夹中。这不是一个非常实用的例子,但它突出了软件包类型方法提供的控制程度。
总结
Composer 提供了许多选项,用于在项目中包含任意软件包。确定如何将这些软件包包含在项目中主要取决于谁定义软件包信息。如果 Git 仓库包含 composer.json
文件,该文件定义了其名称和类型,则您可以让 Composer 依赖仓库自身进行定义。
但是,如果您要包含一个未定义其名称和类型的仓库,则由您的项目来定义和维护该信息以供您自己内部使用。或者,如果仓库未定义 composer.json
文件,请考虑提交 pull request 来添加它。
本文最初发表于 Daggerhart Lab 博客,并已获得许可转载。
评论已关闭。