Menu

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.21.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 澄清,我们正在尝试签出分支而不是标记。在上面的示例中,我们有两个版本分支: v1v2。要使 Composer 签出这些分支之一,必须指定一个类似于以下内容的版本约束: v1.x-dev.x是一个任意字符串,Composer 需要告诉它,我们谈论的是 v1 分支,而不是一个 v1 标记 (或者,你可以只命名分支v1.x而不是 v1)。对于具有类似版本名称的分支 (在本例中为 v1),您将追加-dev为后缀,而不是使用dev-作为前缀。

最小稳定性

还有一件事会影响从库的 VCS 中签出哪些文件并添加到项目中: Composer 允许您指定稳定约束以限制哪些标记被认为是有效的。在上面的示例中,请注意,库在最终正式发布之前发布了版本1.1 的 beta 版和两个候选版本。要在运行composer installcomposer 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 文件。你可以调整版本限制信息,这个工具可以将对应的所有分支高亮。

本文章首发在 Laravel China 社区
上一篇 下一篇
讨论数量: 0
发起讨论


暂无话题~