我正在尝试将mercurial版本烘焙到我的Bazel文件中,以便我可以得到这样的内容:
# These I set manually, since they're "semantic"
MAJOR_VERSION = 2
MINOR_VERSION = 3
BUGFIX_VERSION = 1
# This should be the result of `hg id -n`
BUILD_VERSION = ?
apple_bundle_version(
name = "my_version",
build_version = "{}.{}.{}.{}".format(MAJOR_VERSION, MINOR_VERSION, BUGFIX_VERSION, BUILD_VERSION),
short_version_string = "{}.{}.{}".format(MAJOR_VERSION, MINOR_VERSION, BUGFIX_VERSION),
)
这显然不是密封的,所以我知道这违反了Bazel的一些假设,所以我对其他选择持开放态度。
以下是一些可能的选择:
实际上在Bazel分析期间运行hg id -n
,我不知道该怎么做。
将构建版本传递给via命令行,例如--define=build_version=$(hg id -n)
。不幸的是,这需要一个单独的命令来包装bazel build
。
手动设置BUILD_VERSION
。显然,这会很烦人。
有没有办法做#1?我有什么其他选择?
答案 0 :(得分:8)
是的,您可以使用自定义--workspace_status_command
以及处理信息并生成包含此数据的源文件的规则来执行此操作。
编辑:我删除了有关--stamp
旗帜的部分,但不需要。
--workspace_status_command=/path/to/binary
构建一个运行hg
的自定义二进制文件或shell脚本,并输出所需的信息。genrule
撰写stamp=1
。--workspace_status_command=/path/to/binary
--workspace_status_command=<path>
标志允许您指定二进制文件。
Bazel在每次构建之前运行此二进制文件。二进制文件应该将键值对写入stdout。 Bazel将钥匙分成两个桶:&#34;稳定&#34;和&#34;易变的&#34;。 (名称&#34;稳定&#34;和&#34;易变?&#34;有点反直觉,所以不要过多考虑它们。)
然后Bazel将键值对写入两个文件:bazel-out/stable-status.txt
包含密钥的名称以STABLE_
开头的所有键和值bazel-out/volatile-status.txt
包含其余的键及其值合同是:
stable-status.txt
的内容发生更改,则会使依赖于它们的操作无效,例如genrule.cmd
如果该genrule stamp=1
。换句话说,如果一个稳定的键的值发生变化,它将使Bazel重建标记的动作。因此,稳定状态不应包含时间戳等内容,因为它们会一直更改,并且会使Bazel重建每个构建的标记操作。volatile-status.txt
文件。为了避免一直重建标记动作,Bazel假装易失性文件永远不会改变。换句话说,如果易失性状态文件是唯一内容已更改的文件,则不会使依赖于它的操作无效。如果操作的其他输入已更改,则Bazel会重建该操作,然后操作可以使用更新的易失性状态。但仅仅是不稳定的状态改变不会使行动失效。 my-status.sh
的示例:
#!/bin/bash
echo STABLE_GIT_BRANCH $(git rev-parse HEAD)
echo MY_TIMESTAMP $(date)
genrule
写一个stamp=1
。这个属性没有记录,让我感到惊讶。我将提交一个关于此的错误。
foo/BUILD
的示例:
genrule(
name = "x",
srcs = ["input.txt"],
outs = ["x.txt"],
cmd = " ; ".join([
"( echo 'volatile data:'",
"cat bazel-out/volatile-status.txt",
"echo ---",
"echo 'stable data:'",
"cat bazel-out/stable-status.txt",
") > $@",
]),
stamp = 1,
)
...仅bazel-out/volatile-status.txt
更改时:
$ bazel build --workspace_status_command=/tmp/foo/ws.sh //foo:x &>/dev/null && cat bazel-genfiles/foo/x.txt
volatile data:
BUILD_TIMESTAMP 1512379211456
MY_TIMESTAMP Mon Dec 4 10:20:11 CET 2017
---
stable data:
BUILD_EMBED_LABEL
BUILD_HOST <redacted>
BUILD_USER <redacted>
STABLE_GIT_BRANCH d3fed125d00f6f61bfbfe05f4566656cdac1ea6e
$ cat bazel-out/volatile-status.txt
BUILD_TIMESTAMP 1512379425898
MY_TIMESTAMP Mon Dec 4 10:23:45 CET 2017
$ bazel build --workspace_status_command=/tmp/foo/ws.sh //foo:x &>/dev/null && cat bazel-genfiles/foo/x.txt
volatile data:
BUILD_TIMESTAMP 1512379211456
MY_TIMESTAMP Mon Dec 4 10:20:11 CET 2017
---
stable data:
BUILD_EMBED_LABEL
BUILD_HOST <redacted>
BUILD_USER <redacted>
STABLE_GIT_BRANCH d3fed125d00f6f61bfbfe05f4566656cdac1ea6e
$ cat bazel-out/volatile-status.txt
BUILD_TIMESTAMP 1512379441919
MY_TIMESTAMP Mon Dec 4 10:24:01 CET 2017
...当稳定状态或genrule的输入发生变化时:
$ echo bar > foo/input.txt
$ bazel build --workspace_status_command=/tmp/foo/ws.sh //foo:x &>/dev/null && cat bazel-genfiles/foo/x.txt
volatile data:
BUILD_TIMESTAMP 1512379566646
MY_TIMESTAMP Mon Dec 4 10:26:06 CET 2017
---
stable data:
BUILD_EMBED_LABEL
BUILD_HOST <redacted>
BUILD_USER <redacted>
STABLE_GIT_BRANCH d3fed125d00f6f61bfbfe05f4566656cdac1ea6e
$ git checkout HEAD~1 &>/dev/null
$ bazel build --workspace_status_command=/tmp/foo/ws.sh //foo:x &>/dev/null && cat bazel-genfiles/foo/x.txt
volatile data:
BUILD_TIMESTAMP 1512379594890
MY_TIMESTAMP Mon Dec 4 10:26:34 CET 2017
---
stable data:
BUILD_EMBED_LABEL
BUILD_HOST <redacted>
BUILD_USER <redacted>
STABLE_GIT_BRANCH b3da717469e23f5293297175a80709956416fd2c
答案 1 :(得分:3)
默认情况下,apple_bundle_version
规则使用正则表达式来解析您在Bazel命令行上传递给--embed_label
的任何内容。
因此,实现这一目标的最简单方法是首先编写类似这样的内容:
bazel build //your:target --embed_label="$(hd id -n)"
这会将BUILD_EMBED_LABEL
设置为工作区信息文件中的Mercurial版本,例如:
BUILD_EMBED_LABEL 156
BUILD_HOST ...
BUILD_USER ...
然后你必须告诉apple_bundle_version
你的版本号应该是什么样的:
VERSION_PREFIX = "{}.{}.{}".format(MAJOR, MINOR, BUGFIX)
apple_bundle_version(
name = "my_version",
# This is where you define that BUILD_EMBED_LABEL will look like
# this, where each thing inside {} is one of the capture groups
# below. So in this case, it will be a number.
build_label_pattern = "{build}",
capture_groups = {
"build": "\d+",
},
# CFBundleVersion should be the VERSION_PREFIX above, plus a dot
# followed by {build} extracted from BUILD_EMBED_LABEL.
build_version = VERSION_PREFIX + ".{build}",
# CFBundleShortVersionString will just be the VERSION_PREFIX.
short_version_string = VERSION_PREFIX,
)
这样的事情应该可以解决问题。
如果您不想在每次构建时手动传递hg id -n
的结果,apple_bundle_version
规则是可扩展的,因此您可以自动执行此操作。 version
及其相关规则ios_application
属性的唯一要求是它指向返回AppleBundleVersionInfo
提供商的目标 - 它不必是apple_bundle_version
}。
该提供程序传播包含您的包版本和短包版本字符串的小JSON文件,因此您可以编写自己的规则,将hg id -n
作为自定义操作调用,将其写入具有右侧的JSON格式文件密钥,然后将该目标用作应用程序的version
属性。