使用Mercurial钩子将版本号嵌入到我的应用程序中的方法有多好?

Sle*_*led 7 mercurial makefile build version

这不是一个特别的问题,我更喜欢批评我目前的方法.

我想在我正在开发的程序中包含程序版本号.这不是商业产品,而是研究应用程序,因此了解哪个版本生成结果非常重要.

我的方法如下:

  1. 我的.hg/hgrc文件链接到version_gen.sh有一个"预提交"钩子
  2. version_gen.sh仅包含: hg parent --template "r{rev}_{date|shortdate}" > version.num
  3. 在makefile中,version="%__VERSION__%主脚本中的行将替换为version.num文件的内容.

有更好的方法吗?我能看到的唯一真正的缺点是,如果你只提交一个specfic文件,version.num将被更新,但它不会被提交,如果我试图添加总是提交该文件,那将导致infite循环(除非我创建了一些临时文件来表明我已经在提交中,但这看起来很难看......).

Mar*_*oth 6

问题

正如您所知,您确实在这里创建了Catch-22情况.

在提交更改之前,您无法在version.num文件中真正放置有意义的信息,并且因为您要存储version.num在存储库中,所以在填充version.num文件之前,您无法提交对存储库的更改.

我的解决方案

我建议的是:

  1. 摆脱了"预提交"钩的hg forgetversion.num文件.
  2. 添加version.num到您的.hgignore文件中.
  3. 调整version_gen.sh为:

    hg parent --template "r{node|short}_{date|shortdate}" > version.num

  4. 在makefile中,确保version_gen.shversion.num用于设置version参数之前运行.

我的理由

正如@ Ry4an建议,得到了构建系统中插入修改的信息以构建时的软件,使用信息版本控制系统是一个更好的选择.唯一的问题是,如果您尝试从hg archive存储库中编译代码,那么构建系统无法提取相关信息.

但是我倾向于劝阻这一点 - 在我自己的构建系统中,如果无法提取修订信息,则构建失败.

另外,正如@Kai Inkinen建议的那样,使用修订版是不可移植的.一台机器上的第21版可能是另一台机器上的第22版.虽然现在这可能不是问题,但如果你开始与其他人合作,它可能在未来.

最后,我解释了我不喜欢我的问题中的关键字扩展的原因,这涉及到与您自己的问题相似的问题:

我查看了Mercurials关键字扩展,因为它似乎是一个明显的解决方案.然而,我越是看着它并阅读人们的意见,我就越能得出这样的结论:这不是正确的事情.

我还记得关键字替换在之前公司的项目中引起的问题....

此外,我并不特别想要启用Mercurial扩展来完成构建.我希望解决方案是自包含的,因此,如果没有嵌入的版本信息而不是因为没有启用扩展或没有安装正确的帮助软件而意外编译应用程序是不容易的.

然后在评论中建议使用keyword扩展的答案:

...我拒绝使用关键字扩展名,因为它很容易以字符串"$ Id $"编译到可执行文件中.如果将关键字扩展内置到mercurial而不是扩展中,并且默认情况下打开,我可能会考虑它,但就目前而言,它只是不可靠. - 马克布斯

A不认为可以有更可靠的解决方案.如果有人意外损坏了.hg或者不是从克隆而是从存档中构建的,该怎么办? - Mr.Cat

@ Mr.Cat - 我认为可能没有比关键字扩展更不可靠的解决方案.在没有明确启用扩展程序的任何地方(或有人已禁用它),您将获得"$ID$"编译到目标文件中的文字字符串,而不会抱怨.如果mercurial或repo损坏(不确定你的意思),你还是需要先修复它.至于hg archive,如果您尝试从存档构建它,我的原始解决方案将无法编译!这正是我想要的.我不希望任何源代码被编译到我们的应用程序中,如果它不受源代码的修改控制! - 马克布斯


Von*_*onC 1

您尝试做的事情称为关键字扩展,Mercurial core 不支持它。

您可以将该扩展集成到make 文件中,或者(更简单)与关键字扩展集成

此扩展允许在 Mercurial 跟踪的文本文件中扩展类似 RCS/CVS 和用户定义的密钥。
扩展发生在工作目录中或/和使用“ hg archive”创建发行版时