3.10. 版本限制
Composer 版本和 VCS 版本
Composer 很大程度上依赖于像 Git 这样的版本控制系统,所以说『版本』可能有点含糊不清。在版本控制系统的意义上,『版本』是包含特定数据的特定文件集。在 Git 术语中,它可以是 ref 或者某个特定提交,可以由分支 HEAD 或 tag 表示。当您在 VCS 中签出该版本时 - 例如,标记 v1.1
或提交 e35fa0d
等等 ,您需要一组已知的文件,并且您总是会获得相同的文件。
在 Composer 中对版本的定义是 —— 当我们引入一个包的时候,在 require 后面的字符串(例如 ~1.1
或 1.2.*
)实际上是对这个包的版本约束。 Composer 使用版本约束来确定应该从 VCS 中检出的文件集(或者只是验证在 composer.json
中具有 version
规范的 Statically-Maintained 库是否可以使用)。
VCS 标签 和 分支
以下的讨论中,我们假设使用如下列出的 library 仓库:
~/my-library$ git branch
v1
v2
my-feature
nother-feature
~/my-library$ git tag
v1.0
v1.0.1
v1.0.2
v1.1-BETA
v1.1-RC1
v1.1-RC2
v1.1
v1.1.1
v2.0-BETA
v2.0-RC1
v2.0
v2.0.1
v2.0.2
标签
通常情况, Composer 使用标签来处理版本控制 (标签不同与分支 -- 如果不明白什么是分支,请阅读 version control systems).
当你写版本限制条件时,Composer 所引用的是一个确切的标签 (例如, 1.1
) 或者一个合法的标签范围 (例如, >=1.1 <2.0
, 或者 ~4.0
)。 当 Composer 解析这些版本限制时, 它首先向 VCS 索取所有可用的标签的列表, 然后基于这个列表创建一个可用版本号的内部列表。如上边的例子, Composer 的内部列表包含了版本 1.0
, 1.0.1
, 1.0.2
, 1.1
的 beta 版本, 1.1
的第一和第二候选发行版本, 1.1
的最终发行版本, 等等.... (注意, Composer 会自动去掉标签名称中的 'v' 前缀来得到一个最终可用的版本号。)
当 Composer 从 VCS 得到一个完整的可用版本列表后, 它会找到一个与你项目中的版本限制所匹配的最高的版本 (项目中其他的一些依赖包包也许会要求一些更特定的版本,比项目所要求的更低或更高, 所以 Composer 选择的版本不一定总是最高的) 接着 Composer 会下载一个标签所对应的 zip 包并解压缩在 vendor
目录中相应的位置。
分支
如果希望 Composer 签出分支而不是标记,则需要使用特殊的dev-*
前缀 (有时是后缀,参考下面) 将其指向分支。如果您正在签出分支,则假定您希望在分支上工作
,而 Composer 实际上将 Repo 复制到vendor
目录中的正确位置。对于标签,它只复制正确的文件,而不实际克隆repo。(您可以使用--prefer-source和--prefer-dist修改此行为,请参阅安装选项.)
在上面的示例中,如果要签出 my-feature
分支,则可以将 dev-my-feature
指定为 require
子句中的版本约束。这将导致 Composer 将 my-library
库克隆到我的vendor
目录中,并签出 my-feature
分支。
当分支名称看起来像版本时,我们必须为 composer 澄清,我们正在尝试签出分支而不是标记。在上面的示例中,我们有两个版本分支: v1
和 v2
。要使 Composer 签出这些分支之一,必须指定一个类似于以下内容的版本约束: v1.x-dev
。.x
是一个任意字符串,Composer 需要告诉它,我们谈论的是 v1
分支,而不是一个 v1
标记 (或者,你可以只命名分支v1.x
而不是 v1
)。对于具有类似版本名称的分支 (在本例中为 v1
),您将追加-dev
为后缀,而不是使用dev-
作为前缀。
最小稳定性
还有一件事会影响从库的 VCS 中签出哪些文件并添加到项目中: Composer 允许您指定稳定约束以限制哪些标记被认为是有效的。在上面的示例中,请注意,库在最终正式发布之前发布了版本1.1
的 beta 版和两个候选版本。要在运行composer install
或composer update
时接收这些版本,我们必须显式告诉 Composer,我们可以使用发布候选版本和 beta 版 (如果我们想要的话)。这可以在composer.json
中使用项目范围内的minimum-stability
值来完成或在版本约束中使用 "stability flags"。在 架构 页上阅读更多内容。
编写版本约束
现在,您已经知道了Composer是如何看待版本的,让我们来谈谈如何为项目依赖项指定版本约束。
精确的版本约束
您可以指定包的确切版本。这将告诉Composer仅安装此版本。如果其他依赖项需要不同的版本,则规划求解最终将失败并中止任何安装或更新过程。
例如: 1.0.2
版本范围
通过使用比较运算符,可以指定有效版本的范围。有效的运算符是>
,>=
,<
,<=
,!=
。
您可以定义多个范围。用空格 (
) 或逗号(,
) 分隔的范围将被视为 逻辑 AND 。双管 (||
) 将被视为 逻辑 OR 。且优先级高于OR。
注意: 使用无限制范围时要小心,因为您可能会意外地安装破坏向后兼容性的版本。为了安全请考虑使用脱字符运算符。
例如:
>=1.0
>=1.0 <2.0
>=1.0 <1.1 || >=1.2
带连字符的版本范围 ( - )
包含了一系列的版本。通配符的右边限制了版本的最大范围。 举个例子 1.0 - 2.0
等价于 >=1.0.0 <2.1
,因为 2.0
等价于 2.0.*
。而 1.0.0 - 2.1.0
等价于 >=1.0.0 <=2.1.0
。
举例: 1.0 - 2.0
带通配符的版本范围 (.*)
你可以使用 *
通配符。 1.0.*
等价于>=1.0 <1.1
。
举例: 1.0.*
下一个重要的发布运算符
波形符版本范围 (~)
~
运算符最好用示例解释:~1.2
等价于>=1.2 <2.0.0
,而 ~1.2.3
等价于 >=1.2.3 <1.3.0
。正如您所看到的,它对于尊重 语义版本控制的项目来说是非常有用的。通常的用法是标记您所依赖的最小次要版本,如 ~1.2
(允许任何内容,但不包括 2.0)。因为理论上应该没有向后兼容性破坏直到 2.0,它会运行良好。另一种看待它的方法是使用~
指定一个最小版本,但允许指定的最后一个数字增长。
例如:~1.2
注意: 注意:虽然
2.0-beta.1
是在2.0
之前,但版本约束,如~1.2
不会安装它。正如上面所说的~1.2
只意味着.2
可以改变,但1.
部分是固定的。 注意:~
运算符对其主要发行号的行为有例外。这意味着,~1
与~1.0
是相同的,因为它不会允许主数字增加以试图保持向后兼容性。
脱字符版本范围 (^)
^
运算符的行为非常相似,但它更接近语义版本控制,并且始终允许不中断的更新。例如 ^1.2.3
等效于>=1.2.3 <2.0.0
因为直到 2.0 的版本都不应该破坏向后兼容性。 pre-1.0 版本也考虑安全性并把^0.3
当作为 >=0.3.0 <0.4.0
。
这是推荐的运算符,在编写库代码时具有最大的互操作性。
例如:^1.2.3
稳定性约束
如果您使用的约束没有显式定义稳定性, 则根据所使用的运算符, Composer将在内部默认为 -dev
或 -stable
。这种情况是透明的。
如果希望在比较中只显式考虑稳定版本, 请添加-stable
后缀。
例如:
约束 | 内部 |
---|---|
`1.2.3` | `=1.2.3.0-stable` |
`>1.2` | `>1.2.0.0-stable` |
`>=1.2` | `>=1.2.0.0-dev` |
`>=1.2-stable` | `>=1.2.0.0-stable` |
`<1.3` | `<1.3.0.0-dev` |
`<=1.3` | `<=1.3.0.0-stable` |
`1 - 2` | `>=1.0.0.0-dev <3.0.0.0-dev` |
`~1.3` | `>=1.3.0.0-dev <2.0.0.0-dev` |
`1.4.*` | `>=1.4.0.0-dev <1.5.0.0-dev` |
为了允许不同的稳定性, 而不是在约束级别强制执行它们, 您可以使用诸如 @<stability>
(例如 @dev
) 之类的稳定性标志, 让composer知道给定的软件包可以在不同的稳定性下安装, 而不是默认的最小稳定性设置.所有可用的稳定标志都列在架构页的 "最小稳定" 部分中。
总结
"require": {
"vendor/package": "1.3.2", // exactly 1.3.2
// >, <, >=, <= | specify upper / lower bounds
"vendor/package": ">=1.3.2", // anything above or equal to 1.3.2
"vendor/package": "<1.3.2", // anything below 1.3.2
// * | wildcard
"vendor/package": "1.3.*", // >=1.3.0 <1.4.0
// ~ | allows last digit specified to go up
"vendor/package": "~1.3.2", // >=1.3.2 <1.4.0
"vendor/package": "~1.3", // >=1.3.0 <2.0.0
// ^ | doesn't allow breaking changes (major version fixed - following semver)
"vendor/package": "^1.3.2", // >=1.3.2 <2.0.0
"vendor/package": "^0.3.2", // >=0.3.2 <0.4.0 // except if major version is 0
}
检测版本限制
你可以使用 semver.mwl.be 检测版本限制。填写包名字,它将自动添加默认版本限制信息,Composer 可以将其添加到 composer.json
文件。你可以调整版本限制信息,这个工具可以将对应的所有分支高亮。