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.
精彩评论