哈希计算
缓存或选择性测试执行等功能需要一种方法来确定目标是否已更改。Tuist 会为依赖关系图中的每个目标计算一个哈希值,以判断目标是否发生了变化。哈希值基于以下属性计算:
- 目标的属性(例如名称、平台、产品等)
- 目标包含的文件
- 目标依赖项的哈希值
缓存属性#
此外,在计算 缓存的哈希值时,我们还会对以下属性进行哈希处理。
Swift 版本#
我们会对运行命令 /usr/bin/xcrun swift --version 获取的 Swift 版本进行哈希处理,以防止因目标与二进制文件之间的 Swift 版本不匹配而导致编译错误。
早期版本的二进制缓存依赖于 BUILD_LIBRARY_FOR_DISTRIBUTION 构建设置来启用 模块稳定性,从而允许使用任意编译器版本的二进制文件。然而,这在包含不支持模块稳定性的目标的项目中引发了编译问题。生成的二进制文件绑定到用于编译它们的 Swift 版本,因此该 Swift 版本必须与用于编译项目的 Swift 版本一致。
配置#
在计算缓存哈希值时,Tuist 会将每个项目和目标的设置限定为已解析的构建配置。即通过 --configuration 指定的配置;若未指定,则使用项目的 defaultConfiguration;若仍未指定,则使用第一个调试配置。Tuist 会对该配置的名称、变体、构建设置以及配置文件内容进行哈希处理,并结合适用于它的共享基础设置。添加、移除或更改其他配置不会影响已解析配置的缓存哈希值。由于只有已解析的配置才起作用,因此通过显式传递 --configuration 填充的缓存可以被解析到相同配置但未传递该标志的命令读取。
调试#
如果你在不同环境或多次调用中使用缓存时发现非确定性行为,这可能与环境的差异或哈希逻辑中的缺陷有关。我们建议按照以下步骤调试此问题:
- 运行
tuist hash cache或tuist hash selective-testing(分别用于 二进制缓存 或 选择性测试 的哈希值),复制哈希值,重命名项目目录,然后再次运行该命令。哈希值应当一致。 - 如果哈希值不一致,则生成的项目很可能依赖于环境。在这两种情况下都运行
tuist graph --format json并比较生成的图。或者,生成项目并使用 Diffchecker 等差异比较工具对比它们的project.pbxproj文件。 - 如果哈希值相同但在不同环境(例如 CI 和本地)之间存在差异,请确保所有地方都使用了相同的 配置 和 Swift 版本。Swift 版本与 Xcode 版本绑定,因此请确认 Xcode 版本一致。
如果哈希值仍然表现出非确定性,请告知我们,我们可以协助调试。
改进我们的调试体验已在路线图中。当前的 print-hashes 命令缺乏理解差异所需的上下文,将被一个更友好的命令取代,该命令将使用树状结构来展示哈希值之间的差异。