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

发布于 2024-08-27 11:56:54 字数 518 浏览 8 评论 0原文

这不是一个具体的问题,我更喜欢对我当前的方法进行批评。

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

我的方法的工作原理如下:

  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文件的内容替换。

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

This is not quite a specifc question, and more me like for a criticism of my current approach.

I would like to include the program version number in the program I am developing. This is not a commercial product, but a research application so it is important to know which version generated the results.

My method works as follows:

  1. There is a "pre-commit" hook in my .hg/hgrc file link to version_gen.sh
  2. version_gen.sh consists solely of:
    hg parent --template "r{rev}_{date|shortdate}" > version.num
  3. In the makefile, the line version="%__VERSION__% in the main script is replaced with the content of the version.num file.

Are there better ways of doing this? The only real short coming I can see is that if you only commit a specfic file, version.num will be updated, but it won't be commited, and if I tried to add always committing that file, that would result in an infite loop (unless I created some temp file to indicate I was already in a commit, but that seems ugly...).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

—━☆沉默づ 2024-09-03 11:56:54

问题

正如您所发现的,您确实创建了一个Catch-22 这里的情况。

在提交更改之前,您无法真正将有意义的信息放入 version.num 文件中,并且由于您将 version.num 存储在存储库中,因此无法提交更改存储库,直到您填充 version.num 文件。

我的解决方案

我的建议是:

  1. 摆脱“预提交”挂钩并hg忘记 version.num 文件。
  2. version.num 添加到您的 .hgignore 文件中。
  3. 调整 version_gen.sh 使其包含:

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

  4. 在 makefile 中,确保在使用 version.num 设置版本参数之前运行 version_gen.sh

我的原因

@Ry4an 建议,让构建系统在构建时将修订信息插入到软件中,使用来自版本控制系统的信息是一个更好的选择。唯一的问题是,如果您尝试从存储库的 hg archive 编译代码,构建系统无法提取相关信息。

然而,我倾向于阻止这种情况 - 在我自己的构建系统中,如果无法提取修订信息,则构建失败。

另外,如 @Kai Inkinen 建议,使用修订版号是不可移植的。一台机器上的版本 21 可能在另一台机器上版本 22。虽然这现在可能不是问题,但如果您开始与其他人合作,将来可能会成为问题。

最后,我在 我的问题,涉及与您自己的问题类似的问题:

我查看了 Mercurials 关键字扩展,因为它似乎是显而易见的解决方案。然而,我越看它并阅读人们的意见,我就越觉得这不是正确的做法。

我还记得在以前公司的项目中关键字替换给我带来的问题。 ...

此外,我并不特别希望必须启用 Mercurial 扩展才能完成构建。我希望该解决方案是独立的,这样就不容易因为未启用扩展或尚未安装正确的帮助程序软件而在没有嵌入版本信息的情况下意外编译应用程序。

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

...我拒绝使用关键字扩展,因为很容易最终将字符串“$Id$”编译到可执行文件中。如果关键字扩展内置于 Mercurial 而不是扩展中,并且默认情况下处于启用状态,我可能会考虑它,但就目前情况而言,它并不可靠。 – 马克·布斯

我认为没有更可靠的解决方案。如果有人不小心损坏了 .hg 或不是从克隆而是从存档构建怎么办? – 猫先生

@Mr.Cat - 我认为没有比关键字扩展更不太可靠的解决方案了。在任何您没有显式启用扩展(或者有人禁用它)的地方,您都会得到编译到目标文件中的文字字符串 "$ID$" ,而不会出现任何抱怨。如果 Mercurial 或存储库损坏(不确定您的意思),您无论如何都需要先修复它。至于hg archive,如果您尝试从存档构建它,我的原始解决方案将无法编译!这正是我想要的。我不希望任何源代码在没有版本控制的情况下被编译到我们的应用程序中! – 马克·布斯

The problem

As you've identified, you've really created a Catch-22 situation here.

You can't really put meaningful information in the version.num file until the changes are committed and because you are storing version.num in the repository, you can't commit changes to the repository until you have populated the version.num file.

My solution

What I would suggest is:

  1. Get rid of the "pre-commit" hook and hg forget the version.num file.
  2. Add version.num to your .hgignore file.
  3. Adjust version_gen.sh to consist of:

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

  4. In the makefile, make sure version_gen.sh is run before version.num is used to set the version parameter.

My reasons

As @Ry4an suggests, getting the build system to insert revision information into the software at build time, using information from the Version Control System is a much better option. The only problem with this is if you try to compile the code from an hg archive of the repository, where the build system cannot extract the relevant information.

I would be inclined to discourage this however - in my own build system, the build failed if revision information couldn't be extracted.

Also, as @Kai Inkinen suggests, using the revision number is not portable. Rev 21 on one machine might be rev 22 on another. While this may not be a problem right now, it could be in the future, if you start colaborating with other people.

Finally, I explain my reasons for not liking the Keyword extension in a question of mine, which touches on similar issues to your own question:

I looked at Mercurials Keyword extension, since it seemed like the obvious solution. However the more I looked at it and read peoples opinions, the more that I came to the conclusion that it wasn't the right thing to do.

I also remember the problems that keyword substitution has caused me in projects at previous companies. ...

Also, I don't particularly want to have to enable Mercurial extensions to get the build to complete. I want the solution to be self contained, so that it isn't easy for the application to be accidentally compiled without the embedded version information just because an extension isn't enabled or the right helper software hasn't been installed.

Then in comments to an answer which suggested using the keyword extension anyway:

... I rejected using the keyword extension as it would be too easy to end up with the string "$Id$" being compiled into the executable. If keyword expansion was built into mercurial rather than an extension, and on by default, I might consider it, but as it stands it just wouldn't be reliable. – Mark Booth

A don't think that there can be a more reliable solution. What if someone accidentally damages .hg or builds not from a clone but from an archive? – Mr.Cat

@Mr.Cat - I don't think there can be a less reliable solution than the keywords extension. Anywhere you haven't explicitly enabled the extension (or someone has disabled it) then you get the literal string "$ID$" compiled into the object file without complaint. If mercurial or the repo is damaged (not sure which you meant) you need to fix that first anyway. As for hg archive, my original solution fails to compile if you try to build it from an archive! That is precisely what I want. I don't want any source to be compiled into our apps without it source being under revision control! – Mark Booth

葬心 2024-09-03 11:56:54

您尝试执行的操作称为“关键字扩展”,Mercurial 核心不支持该操作

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

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

What you are trying to do is called Keyword Expansion, which is not supported in Mercurial core.

You can integrate that expansion in make file, or (simpler) with the Keyword extension.

This extension allows the expansion of RCS/CVS-like and user defined keys in text files tracked by Mercurial.
Expansion takes place in the working directory or/and when creating a distribution using "hg archive"

你爱我像她 2024-09-03 11:56:54

令人担忧的是您使用了预提交挂钩。您不应该将 version_gen.sh 的其余部分放入源文件中,而应放入构建/发布工件中,您可以使用“更新”挂钩更准确地执行此操作。

您不希望 Makefile 在每次提交时都在存储库中实际更改,这只会使合并变得糟糕。您希望在构建之前检查文件后插入版本,这就是更新挂钩的作用。

That you use a pre-commit hook is what's concerning. You shouldn't be putting the rest of version_gen.sh into the source files thesemves, just into the build/release artifacts which you can do more accurately with an 'update' hook.

You don't want the Makefile to actually change in the repo with each commit, that just makes merges hell. You want to insert the version after checking out the files in advance of a build, which is is what an update hook does.

痴情换悲伤 2024-09-03 11:56:54

在像 Mercurial 这样的分布式系统中,实际的“版本号”并不一定在每个环境中都意味着相同的事情。即使这是一个单人项目,并且您非常小心地只拥有中央存储库,您仍然可能想要使用 sha1-sum 来代替,因为这对于给定存储库状态来说确实是唯一的。 sha1 可以通过模板 {node} 获取

作为建议,我认为更好的工作流程是使用标签,顺便说一句,这些标签也是存储库本地的,直到您将它们推送到上游。不要将您的号码写入文件,而是使用有意义的标签(例如
)来标记您的发布代码
RELEASE_2

RELEASE_2010-04-01
或者也许编写此脚本并使用模板来创建标签?

然后,您可以将标记添加到非版本化(在 .hgignore 中)的 version.num 文件中,以添加到构建中。通过这种方式,您可以为版本指定有意义的名称,并将版本与唯一标识符联系起来。

In distributed systems like Mercurial, the actual "version number" does not necessarily mean the same thing in every environment. Even if this is a single person project, and you are really careful with having only your central repo, you would still probably want to use the sha1-sum instead, since that is truly unique for the given repository state. The sha1 can be fetched through the template {node}

As a suggestion, I think that a better workflow would be to use tags instead, which btw are also local to your repository until you push them upstream. Don't write your number into a file, but instead tag your release code with a meaningful tag like
RELEASE_2
or
RELEASE_2010-04-01
or maybe script this and use the template to create the tag?

You can then add the tag to your non-versioned (in .hgignore) version.num file to be added into the build. This way you can give meaningful names to the releases and you tie the release to the unique identifier.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文