source: trunk/scripts/_UpdateRev.groovy @ 671

Last change on this file since 671 was 531, checked in by gav, 14 years ago

Refactor UpadateRev script to improve handling when not running in a working copy.

  • Property svn:executable set to *
File size: 5.3 KB
RevLine 
[522]1import org.tmatesoft.svn.core.wc.*
2
3//includeTargets << grailsScript("Init")
4
5/**
[531]6* Check and update the app.vcsRevision property in application.properties file and metadata.
7* May be run directly by `grails update-rev` and normally run by _Events.groovy and eventCompileStart.
8* The revision in the properties file is checked against the version control system (VCS) revision
9* and updated if required.
10* The VCS revision is written to the properties file so that it is available in the compiled war.
11* The compile is intentionally allowed to go ahead if a handled exception occurs.
12* VCS currently supported: subversion.
[522]13*/
[531]14target(updateVcsRevision: "Check and update the app.vcsRevision property in application.properties file and metadata.") {
[522]15
16    def result = [:]
17
[531]18    // Properties file.
19    def url = basedir + "/application.properties"
20    def propertiesFile = new File(url)
21
[522]22    def fail = { Map m ->
[531]23        updateInMemoryMetadata('Unknown')
24        def writeResult = writePropertiesFileRevision(propertiesFile, 'Unknown')
25        if(writeResult.error) {
26            m.code= writeResult.error.code
27            m.args= writeResult.error.args
28        }
29
[522]30        result.error = [ code: m.code, args: m.args ]
[526]31        println "Error: UpdateRev script: " + result.error
[522]32        return result
33    }
34
[531]35    // Get propertiesFile revision.
36    def properitesFileResult = getPropertiesFileRevision(propertiesFile)
37    if(properitesFileResult.error)
38        return fail(code: properitesFileResult.error.code, args: properitesFileResult.error.args)
[522]39
[531]40    // Get VCS revision.
41    def vcsResult = getVcsRevision()
42    if(vcsResult.error)
43        return fail(code: vcsResult.error.code, args: vcsResult.error.args)
[522]44
45    // Compare and update.
[531]46    if(properitesFileResult.revision != vcsResult.revision) {
[522]47
[531]48        println "app.vcsRevision = "+properitesFileResult.revision +', VCS Revision = '+vcsResult.revision
[522]49
[531]50        updateInMemoryMetadata(vcsResult.revision)
[522]51
52        // Update application.properties file.
[531]53        def writeResult = writePropertiesFileRevision(propertiesFile, vcsResult.revision)
[522]54        if(writeResult.error)
55            return fail(code: writeResult.error.code, args: writeResult.error.args)
56
57    } // if(rev != rev)
[526]58    else {
[531]59        println "VCS Revisions match: app.vcsRevision = ${properitesFileResult.revision}, VCS Revision = ${vcsResult.revision}."
[526]60    }
[522]61
62    // Success.
63    return result
64
65} // updateVcsRevision()
66
67/**
68* Get the app.vcsRevision property from properties file.
69* @retuns A map containing revision and lineNumber otherwise an error map.
70*/
[531]71def getPropertiesFileRevision(propertiesFile) {
[522]72    def result = [:]
73
74    def fail = { Map m ->
75        result.error = [ code: m.code, args: m.args ]
76        return result
77    }
78
[531]79    if(!propertiesFile.isFile())
80        return fail(code:"application.properties.file.not.found", args:[propertiesFile.getAbsoluteFile()])
81
[522]82    propertiesFile.eachLine { line, lineNumber ->
83        // app.vcsRevision=$Rev: NUM $
84        if ( line =~ '^app.vcsRevision.' ) {
85            if(line.size() > 23) {
86                result.revision = line[22..-3]
87                result.lineNumber = lineNumber
88            }
89        }
90    }
91
92    if(!result.revision || !result.lineNumber)
93        return fail(code:"app.vcsRevision.not.found")
94
95    // Success.
96    return result
97
98} // getAppRevision()
99
100/**
101* Get the working copy's base revision from SVN.
102* @retuns A map containing revision otherwise an error map.
103*/
[531]104def getVcsRevision() {
[522]105    def result = [:]
106
107    def fail = { Map m ->
108        result.error = [ code: m.code, args: m.args ]
109        return result
110    }
111
112    def wc = new File(basedir)
113        if(!wc.isDirectory())
114            return fail(code:"vcs.working.copy.not.found", args:[basedir])
115
116    // Use svnkit to get the base revision.
117    def clientManager = SVNClientManager.newInstance()
118    def wcClient = clientManager.getWCClient()
119    try {
120        result.revision = wcClient.doInfo(wc, SVNRevision.BASE).getRevision().toString()
121    }
122    catch(org.tmatesoft.svn.core.SVNException e) {
123        fail(code:"vcs.exception", args:[e])
124    }
125
126    // Success.
127    return result
[531]128} // getVcsRevision()
[522]129
[531]130/**
131* Update the in memory metadata if already loaded.
132* Available vars: binding.variables.each { println it.key }
133*/
134def updateInMemoryMetadata(revision) {
135    if(binding.variables.containsKey('metadata')) {
136        def metadata = binding.variables['metadata']
137        metadata['app.vcsRevision'] = '$Rev: '+revision+' $'
138    }
139} // updateInMemoryMetadata()
140
[522]141/**
142* Write revision to properties file.
143* @retuns An error map if any errors.
144*/
[531]145def writePropertiesFileRevision(propertiesFile, revision) {
[522]146    def result = [:]
147
148    def fail = { Map m ->
149        result.error = [ code: m.code, args: m.args ]
150        return result
151    }
152
[531]153    if(!propertiesFile.isFile())
154        return fail(code:"application.properties.file.not.found", args:[propertiesFile.getAbsoluteFile()])
155
[522]156    def revisionString = 'app.vcsRevision=\\$Rev: '+revision+' \\$'
[531]157    println "Updating application.properties file with: ${revisionString}"
[522]158
159    def processFileInplace = { file, Closure processText ->
160        def text = file.text
161        file.write(processText(text))
162    }
163
164    processFileInplace(propertiesFile) { text ->
165        text.replaceAll('app.vcsRevision.*', revisionString)
166    }
167
168    // Success.
169    return result
170
[531]171} // writePropertiesFileRevision()
Note: See TracBrowser for help on using the repository browser.