This is pretty much a FAQ (with many different solutions), but here is my approach (for Grails 1.2+, 1.3.0RC1+)…
It’s rather simple: simply hook into Grails’ compilation lifecycle by adding the following to scripts/_Events.groovy:
// I COULD try munging resources.xml but then I would have to be careful that I didn't
// tread over anything else in that file. This way, it's all separated out and under control...
eventCompileStart = {binding ->
// Capture the computer name in a cross-platform manner
// http://www.ehatchersolutions.com/JavaDevWithAnt/ant.html
ant.property(environment: "env")
ant.property(name: 'env.COMPUTERNAME', value: "${ant.antProject.properties.'env.HOSTNAME'}")
def now = new Date().format('dd/MMM/yyyy; kk:mm:ss')
ant.echo(message: 'Writing temporary.BuildInfo.groovy...')
ant.echo(message: "buildTime: ${now}")
ant.echo(message: "buildHost: ${ant.antProject.properties.'env.COMPUTERNAME'}")
ant.echo(message: "buildWho: ${ant.antProject.properties."user.name"}")
ant.mkdir(dir: 'src/groovy/temporary')
new File('src/groovy/temporary/BuildInfo.groovy').withWriter {writer ->
writer << """
package temporary
public interface BuildInfo {
String buildTime = '${now}'
String buildHost = '${ant.antProject.properties.'env.COMPUTERNAME'}'
String buildWho = '${ant.antProject.properties."user.name"}'
}
"""
}
}
Remember to add the src/groovy/temporary directory to your VCS’s ignore list, otherwise you’ll get all sorts of nastiness happening on checkin/update/… Indeed, one of the drivers that led me to this this approach was that I wanted to capture this sort of stuff without needing to update any of my versioned files (application.properties or resources.{groovy,xml}, for instance).
Once the interface has been created it can be used as needed. Here’s a bit of GSP, for example:
<div style="color:#48802c;font-size:xx-small">
My Big Project<br />
Environment: ${grails.util.Environment.current.name}.<br />
Built by ${BuildInfo.buildWho}@${BuildInfo.buildHost}, at ${BuildInfo.buildTime}.
</div>
The thing I appreciate about this approach is that it can be modified to grab a snapshot of almost any darned thing you want to capture…the output from a script (conceivably even ‘grails stats’, although I haven’t tried this), Hudson build number, the result of a network ping test, database-y stuff…the skies the limit…
The major drawback: this script runs every time grails starts up…even if it is for something like run-app. I have learned to live with that however (although if anyone knows how to do better, please drop me a line…).
