When your application goes to production, you should be prepared for handling bugs. Users and customers will find them and hopefully report them. I’ve been multiple times in a situation where a well written bug report including a stacktrace doesn’t help me much because the stacktrace doesn’t match the current development state of the code. Therefore it simplifies life if the bug report contains a build number or a SCM revision number. With this small recipe, you can easily add this information to your application.
Find out your current SCM revision
Every version control system does this differently, so here’s a short summary of what command might be used for what SCM:
SCM | command to get revision information |
---|---|
Mercurial | hg id -i -n -b -t |
Git | git rev-parse HEAD |
Subversion | svnversion |
If your SCM of choice is not listed and you know the command, please let me know by posting a comment.
Create a template that contains the revision information
For the following, I’ll use mercurial, it should be easy to adopt this to the SCM of choice. Using a Gant-Script scripts/_Events.groovy
you could hook into the build process and easily generate a Grails template that just contains the output of one of the above commands.
eventCompileStart = { msg ->
def proc = "hg id -i -n -b -t".execute()
proc.waitFor()
new FileOutputStream("grails-app/views/_version.gsp", false) << proc.in.text
}
This recreated grails-app/views/_version.gsp
upon each build, so we’re sure to have always the most recent revision ids there. It is crucial that the file containing the revision information is itself not under version control. To exclude this file you have to list it in .hgignore
, .gitignore
or use svn propedit svn:ignore
.
Using the _version.gsp template
The final step is to embed the previously created _version.gsp
somewhere in your code. For my usecase, I want to have the revision ids available on each and every page, so I’ll put it into the layout template grails-app/views/layout/main.gsp
:
<div >
<p><g:message code="meta.app.version" default="Version: {0}" args="[meta(name: 'app.version')]"/> SCM: <g:render template="/version"/></p>
</div>
Be sure not to omit the leading “/” in the g:render tag, otherwise _version.gsp gets not found in case of a deeper nested view path.