source: trunk/scripts/_UpdateRev.groovy @ 531

Last change on this file since 531 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
Line 
1import org.tmatesoft.svn.core.wc.*
2
3//includeTargets << grailsScript("Init")
4
5/**
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.
13*/
14target(updateVcsRevision: "Check and update the app.vcsRevision property in application.properties file and metadata.") {
15
16    def result = [:]
17
18    // Properties file.
19    def url = basedir + "/application.properties"
20    def propertiesFile = new File(url)
21
22    def fail = { Map m ->
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
30        result.error = [ code: m.code, args: m.args ]
31        println "Error: UpdateRev script: " + result.error
32        return result
33    }
34
35    // Get propertiesFile revision.
36    def properitesFileResult = getPropertiesFileRevision(propertiesFile)
37    if(properitesFileResult.error)
38        return fail(code: properitesFileResult.error.code, args: properitesFileResult.error.args)
39
40    // Get VCS revision.
41    def vcsResult = getVcsRevision()
42    if(vcsResult.error)
43        return fail(code: vcsResult.error.code, args: vcsResult.error.args)
44
45    // Compare and update.
46    if(properitesFileResult.revision != vcsResult.revision) {
47
48        println "app.vcsRevision = "+properitesFileResult.revision +', VCS Revision = '+vcsResult.revision
49
50        updateInMemoryMetadata(vcsResult.revision)
51
52        // Update application.properties file.
53        def writeResult = writePropertiesFileRevision(propertiesFile, vcsResult.revision)
54        if(writeResult.error)
55            return fail(code: writeResult.error.code, args: writeResult.error.args)
56
57    } // if(rev != rev)
58    else {
59        println "VCS Revisions match: app.vcsRevision = ${properitesFileResult.revision}, VCS Revision = ${vcsResult.revision}."
60    }
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*/
71def getPropertiesFileRevision(propertiesFile) {
72    def result = [:]
73
74    def fail = { Map m ->
75        result.error = [ code: m.code, args: m.args ]
76        return result
77    }
78
79    if(!propertiesFile.isFile())
80        return fail(code:"application.properties.file.not.found", args:[propertiesFile.getAbsoluteFile()])
81
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*/
104def getVcsRevision() {
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
128} // getVcsRevision()
129
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
141/**
142* Write revision to properties file.
143* @retuns An error map if any errors.
144*/
145def writePropertiesFileRevision(propertiesFile, revision) {
146    def result = [:]
147
148    def fail = { Map m ->
149        result.error = [ code: m.code, args: m.args ]
150        return result
151    }
152
153    if(!propertiesFile.isFile())
154        return fail(code:"application.properties.file.not.found", args:[propertiesFile.getAbsoluteFile()])
155
156    def revisionString = 'app.vcsRevision=\\$Rev: '+revision+' \\$'
157    println "Updating application.properties file with: ${revisionString}"
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
171} // writePropertiesFileRevision()
Note: See TracBrowser for help on using the repository browser.