开发者

Mercurial keywords extension to expand on every commit

I need to use the hg keyword extension to embed the build date and revision into a source file. Leaving aside the whole "you really don't want to be doing that" argument, how can I do this?

Here's what my source file (lib/foo/version.rb) looks like (which happens to be Ruby, but that's only relevant from the point of view that I don't have a "compile" step in my build which I could do a -DREVISION="$(hg id)" in):开发者_如何学Python

module Foo
  VERSION = {
    :date => "$Date$",
    :changeset => "$Revision$"
  }
end

The problem is that $Revision$ and $Date$ are expanded with the changeset and commit date of that file, whereas what I need is the tip changeset and commit date of the whole repository.

I don't see an obvious template I can use in hg help templates, nor does the keyword extension mention anything with global scope. Is what I'm trying to do possible?


You can install a post-commit hook that updates the file:

[hooks]
post-commit = sed -i lib/foo/version.rb \
  -e "s|\$Date.*\$|\$Date: $(date)\$|" \
  -e "s|\$Version.*\$|\$Version: $(hg id -i)\$|"

You should then probably add the version file to the .hgignore file -- it will change after every commit and thus always be dirty. You could also add a encode filter that will clean up the version file:

[encode]
lib/foo/version.rb =  sed -e "s|\$Date.*\$|\$Date\$|" \
                          -e "s|\$Version.*\$|\$Version\$|"

This script will make Mercurial see the file as clean -- no matter what date and changeset has it really contains, Mercurial will see it as containing un-expanded $Date$ and $Version$ keywords:

$ hg commit -m test
$ hg tip
changeset:   7:df81c9ddc9ad
tag:         tip
user:        Martin Geisler 
date:        Wed Apr 06 14:39:26 2011 +0200
summary:     test

$ hg status
$ hg cat version.py
date = "$Date$"
version = "$Version$"
$ cat version.py
date = "$Date: Wed Apr  6 14:39:26 CEST 2011$"
version = "$Version: df81c9ddc9ad$"


If you're running your code from a checkout you can invoke hg directly and cache the value. Something like:

module Foo
  VERSION = {
    :version => system("hg log --template '{note|short}-{latesttag}-{latesttagdistance}' -r .")
  }
end

and if you're not running the code from inside a checkout on a system with Mercurial installed, then your deploy script can easily get/use the value -- perhaps by using hg archive to get the tarball to send which then automatically includes a .hg_archive.txt.

I guarantee you there's a prettier way to do this than the keywords extension no matter what your setup is.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜