Custom variables for Mercurial possible? - mercurial

When I commit my changes I add a technical description to it. But for a changelog I need the information if the change is relevant for our customer. This information should be required to add as a developer.
I saw that can get a different log via
hg log --template 'author: {author}\n'
But as variables I can only use build in variables like {author}.
I want to use own variables that are also visible in html-view.
Is that possible?

Related

Mercurial - Add tag to committed files on commit

We are looking for a way to add / update a custom tag at the beginning of each file being committed during a commit. Its some kind of local timestamp we need.
I was thinking of hooks.
Unfortunately I cannot find a useful hook for that:
precommit: unsuitable as it fires before hg knows any metadata of the commit
pretxncommit: unsuitable, as the documentation clearly states that we should not change the working dir at this point
commit: unsuitable, as it fires when the commit has already happened.
EDIT:
I can not use hg's inline changeset-hash and / or datetime. For the following reason:
Our files get later imported into an external system (we do not have control over) which does not support any kind of versioning.
To simplify stuff: let's say tag is an ever-incrementing no. (everytime we commit). This tag is then used to help getting an idea of the version / status of the file on the system in respect to the file in the repo - like "no. of changes we're missing" and such.
Any ideas?
I would suggest a two-stage solution. First, create an alias along the following lines:
[alias]
tcommit = !tag-changed-files && $HG commit "$#"
Here, tag-changed-files would retrieve a list of modified and added/moved files via $HG status -ma -n or $HG status -ma -n -0 and tag them. I am assuming that re-tagging files that have been modified but aren't being committed yet is a harmless operation; more on that below. Note that you can even redefine commit if you absolutely want to via:
[alias]
commit = !tag-changed-files && $HG --config alias.commit=commit commit "$#"
However, this is potentially problematic, because it may confuse scripts.
You could also integrate the commit step in the program if you wanted to, and even try and parse the command line arguments to only tag those files that you are committing. For this approach, using hglib might be appropriate to avoid the overhead of invoking Mercurial multiple times. (Note that hglib and other tools that use the command server ignore aliases and command defaults, so this works even if you alias commit).
Second, you'd install a pretxncommit hook that verifies that files that are being committed have indeed been tagged appropriately (to ensure that the tag-changed-files program hasn't been bypassed by accident).
This should work without a problem on full commits; for partial commits, any files that were changed but have not been committed would also have been retagged, but since they will be either committed later (and get tagged properly at that point) or reverted, that should be harmless.
an idea of the version / status of the file on the system in respect to the file in the repo
Just one idea
Stop reinvent the wheel
Incremental counter is just shit, if you task is "to know, which version is on LIVE and which - in Mercurial's tip" (and this is your real business-task, yes?!)
Keyword Extension give you last changes per file.
If you want to inject changeset of repository into files (it's reasonable good way), re-read this part of wiki-page
If you just want to version your entire repo, do not use this
extension but let your build system take care of it. Something along
the lines of
hg -q id > version
before distribution might be well enough if file-wise keyword
expansion in the source is not absolutely required
You can insert hg id output into files at export stage (in planetmaker's sed-style), bu you can also have this additional metadata in files permanently in VCS with special encode|decode filters
There is - to my knowledge - no intrinsic system in mercurial which supports what you describe. However I can recommend an approach which somewhat is adopted from building a software release package from the repository: Make a small export script which replaces a certain KEYWORD in your files with the version information you need. A Makefile target could look like which creates a zip export for revision XXX with version information in all files which support it (thus contain the verbatim KEYWORD - use something truely unique here):
VERSION=$(hg log -rXXX --template="Version: {node|short} from {date|isodate}")
export:
hg archive -rXXX -t files export
for i in $(hg ma -rXXX); do sed -i "s/KEYWORD/$VERSION/g" $i; done
zip -9rq export.zip export
I use a similar approach in my Makefiles where I create versioned export for the source of a particular revision of my software.
EDIT: if your purpose (as stated by the comment) is only to implant the number of commits made to that file: then you can use indeed a pre-commit hook and modify the file. You can count the number of modifications made to a file with hg log FILENAME --template="{node}\n" | wc -l. Do that for every file and do the sed replacement in the header of each file in the pre-commit hook.

Generating a file with Tag or Branch Name in mercurial

I need in my source code to have a text file which contains the current Tag and Branch name.
Generally I want it for browsers "cache killer", I can read this file and append it to every script/css call.
for example: <script src='file.js?v=1.0'></script> the 1.0 will be coming from this generated config file.
I am working in PHP and C# So I need this kind of functionality built in the source control.
Is it possible? I dont want to do it manually, to risky.
Thanks
hg log -r. --template='{branch}-{latesttag}' would give you the branchname of the currently checked-out revision and the last tag preceeding it in its list of ancestors. Either use that call to hg directly or write it to a config file.
See hg help templates and maybe also hg help revsets

How to convert Mercurial diff output to HTML?

Is there a way to add the HTML tags to Hg diff output? Currently our team of developers receives diffs over email every day and we would like to improve their readability, for example add line highlight and change title styles. I know it can be done in SVN via the special script, but I can't seem to find the instructions on how to do it in Hg. Thanks in advance.
I've never used it, it's only from a search on Google but you can try this:
http://colorer.sourceforge.net/
hg diff | colorer -h > diff.html
You can combine the output of this command with a hook after a commit. So, after every commit, mercurial can send an email with the diff in HTML. You just need to put the glue between the line above an the examples given for setting hooks in Mercurial.

Mercurial hook to test that username is valid when pushing to repository

I have a "central" repository that I want to ensure that no one pushes changes in to with a wrong user name.
But I can not figure out how to make a hook that tests the user name against a positive list. I have found in the Mercurial API a ctx.user() call that seems to be what I want to test my positive list against.
Also the hook could be a precommit hook that is distributed as part of the repository clone or it could be a hook on the central repository as a pre-incoming or something like that.
Any help or pointers would be greatly appreciated.
I have posted two functional examples on Bitbucket. Both examples are for searching a commit message for some specifically formatted text (like an issue tracked case ID), but could be easily modified to check a user against a list of valid users.
The first example is actually a Mercurial extension that wraps the 'commit' command. If it fails to find the appropriate text (or valid user in your case), it will prevent the commit from occurring at all. You can enable this in your .hgrc file by adding these lines:
[extensions]
someName = path/to/script/commit-msg-check.py
The second example uses a in-process pretxncommit hook, which runs between when the commit has been made, but before it becomes permanent. If this check fails it will automatically roll back the commit. You can enable this in your .hgrc file by adding these lines (assuming you kept the same file/function names):
[hooks]
pretxncommit.example = python:commit-msg-check-hook.CheckForIssueRecord
You can execute any Python code you like inside of these hooks, so user validation could be done in many ways.
Thanks for the examples dls.
In the end I decided to run it as a pretxnchangegroup hook and then use the hg log and grep to test the author field of the commits:
[hooks]
pretxnchangegroup.usercheck = hg log --template '{author}\n' -r \
$HG_NODE: | grep -qe 'user1\|user2\|etc'
It does of course not provide a very good feedback other than usercheck failed. But I think it is good enough for now.

How can I label my build with revision number and not the GUID (in TeamCity)?

I am trying to do "continuous integration" with TeamCity. I would like to label my builds in a incremental way and the GUID provided by the VCS is not as usefull as a simple increasing number. I would like the number to actually match the revision in number in Mercurial.
My state of affairs:
Mercurial info:
I would like the build to be labeled 0.0.12 rather than the GUID.
Would someone be so kind and save me hours of trying to figure this out ?
As Lasse V. Karlsen mentioned those numerical revision numbers are local-clone specific and can be different for each clone. They're really not suitable for versioning -- you could reclone the same repo and get different revision numbers.
At the very least include the node id also creating something like 0.0.12-6ec760554f2b then you still get sortable release artifacts but are still firmly identifying your release.
If you're using numeric tags to tag releases there's a particularly nice option:
% hg log -r tip --template '{latesttag}.{latesttagdistance}'
which, if the most recent tag on that clone was called 1.0.1 and was 84 commits ago gives a value like:
1.0.1.84
Since you can have different heads that are 84 commits away from a tag in different repos you should still probably include the node id like:
% hg log -r tip --template '{latesttag}.{latesttagdistance}-{node|short}'
giving:
1.0.1.84-ec760554f2b
which makes a great version string.
The best and easiest way to see rev. number in TeamCity build number is to use Build Script Interaction with TeamCity. Namely, it has a possibility to set Build Number.
So, add to your project a new very first build step Command Line with following Command Executable
for /f %%i in ('c:\tortoisehg\hg id -n') do echo ##teamcity[buildNumber '%%i']
And you will get the Mercurial revision number as a label for your every build.
Of course you can change the command in quotes to anything you wish.
I believe my answer is way more correct than the accepted one.
EDIT:
Also you can do the same via MSBuild task rather than Command Executable. Have a MSBuild project file with following code, setup TeamCity to run it as first step, and it will alter its global variable buildNumber:
<Message Text="##teamcity[buildNumber '$(CurrentVersion)']" Importance="High" />
Where CurrentVersion is a string containing full version (for example "1.0.56.20931").
hg id produces the hash (6ec760554f2b), hg id -n produces the local revision number (12).
(Note this is an answer purely from the hg side, how you then get that into TeamCity, I don't know, as I've never used it.)
I managed to use it in Teamcity using a workaround:
<Exec Command="hg log -r tip --template {latesttag}.{latesttagdistance} > $(BuildAgentTempDir)\version.txt"/>
<ReadLinesFromFile File="$(BuildAgentTempDir)\version.txt">
<Output TaskParameter="Lines" ItemName="versionInfo"/>
</ReadLinesFromFile>
<TeamCitySetBuildNumber BuildNumber="#(versionInfo)-{build.number}" />
If you see the MSBuild task "TeamCitySetBuildNumber" I'm using the "{build.number}" variable because it substitutes this with what you set in the build number originally. I used %build.vcs.number% in my original settings (in the Web UI) and the result is just what Ry4an wrote above!
Hope it works for you!
When I used to use Subversion I used to do something similar in TeamCity. The format was:
{Major}.{Minor}.{TeamCity Build No.}.{Subversion Revision No.}
This allowed me to look at an assembly and see which build it came from on TeamCity and the revision number from subversion.
I have now moved to Git which has put me in the same situation as you. After playing with various ideas I have come to the conclusion that I don't actually need the revision, the build is good enough. Because TeamCity is such a powerful tool, all you need is the build number, given the build number you can look at the build history and determine the revision from that.
{Major}.{Minor}.{Macro}.{TeamCity Build No.}
Additionally you can get TeamCity to label your repository with the build number allowing you to look up a given build in your source control.
When providing your build number with numeral mercurial revision, you must be aware, that those numbers are clone-specific and can differ from clone to clone.
In our project we had the same issue. We're using TeamCity 7.1.1. We solved it in the following way:
Add Command line build step to your configuration.
Make this build step run first.
In the build step properties select "Run: 'Executable with parameters'"
Add the following text to Command Executable:
for /f %%i in ('hg id -n') do echo ##teamcity[buildNumber '%%i']
Save changes.
You can also use previously generated build number when performing step 3.
Example:
for /f %%i in ('hg id -n') do echo ##teamcity[buildNumber '%system.build.number%.%%i']
You can use this to make build counter present in your build number.
Read this to get more information!
Remember that teamcity compiles configurations build number before build starts and the correct build number will appear only after your build step will finish its job. That's why, in some cases (f.e. inserting your mercurial revision into artifact's name) you should define build number's value in preceding configuration and refer to it.
Example:
%dep.bt82.build.number%
Read this to get more information!