source: trunk/scripts/_UpdateRev.groovy @ 894

Last change on this file since 894 was 890, checked in by gav, 14 years ago

Small adjustment to updateRev script, to use last committed revision instead of the repository head revision.

  • 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 last committed revision.
117    def clientManager = SVNClientManager.newInstance()
118    def wcClient = clientManager.getWCClient()
119    try {
120        result.revision = wcClient.doInfo(wc, SVNRevision.BASE).getCommittedRevision().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.