Mercurial keyword extension to expand with every commit

I need to use the hg keyword extension to insert the date and version of the assembly into the source file. Leaving aside the entire argument “you really don't want to do this”, how can I do this?

This is what my source file ( lib/foo/version.rb ) looks like (which happens to be Ruby, but it’s only relevant from the point of view that I don’t have a “compilation” in my assembly that I could do -DREVISION = "$ (hg id)" in):

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

The problem is that $ Revision $ and $ Date $ are expanded with a set of changes and a commit date for this file, while I need a set of tips and a commit date for the entire repository.

I do not see an explicit template that I can use in hg help templates , nor does it add a keyword extension to the global scope. Am I trying to do this?

+6
mercurial keyword commit
source share
2 answers

You can set the post-commit hook, which updates the file:

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

Then you will probably add the version file to the .hgignore file - it will change after each commit and therefore will always be dirty. You can also add an encoding filter that clears 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 set of changes it actually contains, Mercurial will see that it contains the unexpanded keywords $Date$ and $Version$ :

  $ 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 $"
+3
source share

If you use your code from verification, you can directly call hg and cache the value. Something like:

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

and if you do not use the code inside the check on a system with Mercurial installed, then your deployment script can easily get / use the value - perhaps using hg archive to send a tarball which then automatically includes .hg_archive.txt .

I guarantee you a more beautiful way to do this than expanding your keywords, no matter what your setting.

0
source share

All Articles