/* * Copyright 2004-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Gant script that handles upgrading of a Grails applications * * @author Graeme Rocher * @author Sergey Nebolsin * * @since 0.4 */ import org.codehaus.groovy.grails.plugins.GrailsPluginUtils import grails.util.Metadata includeTargets << grailsScript("_GrailsPlugins") target(upgrade: "main upgrade target") { depends(createStructure, parseArguments) boolean force = argsMap.force || !isInteractive ?: false if (appGrailsVersion != grailsVersion) { def gv = appGrailsVersion == null ? "pre-0.5" : appGrailsVersion event("StatusUpdate", ["NOTE: Your application currently expects grails version [$gv], " + "this target will upgrade it to Grails ${grailsVersion}"]) } if (!force) { ant.input(message: """ WARNING: This target will upgrade an older Grails application to ${grailsVersion}. However, tag libraries provided by earlier versions of Grails found in grails-app/taglib will be removed. The target will not, however, delete tag libraries developed by yourself. Are you sure you want to continue? """, validargs: "y,n", addproperty: "grails.upgrade.warning") def answer = ant.antProject.properties."grails.upgrade.warning" if (answer == "n") exit(0) if ((grailsVersion.startsWith("1.0")) && !(['utf-8', 'us-ascii'].contains(System.getProperty('file.encoding')?.toLowerCase()))) { ant.input(message: """ WARNING: This version of Grails requires all source code to be encoded in UTF-8. Your system file encoding indicates that your source code may not be saved in UTF-8. You can re-encode your source code manually after upgrading, but if you have used any non-ASCII chars in your source or GSPs your application may not operate correctly until you re-encode the files as UTF-8. Are you sure you want to upgrade your project now? """, validargs: "y,n", addproperty: "grails.src.encoding.warning") answer = ant.antProject.properties."grails.src.encoding.warning" if (answer == "n") exit(0) } } clean() def coreTaglibs = new File("${basedir}/plugins/core") ant.delete(dir: "${coreTaglibs}", failonerror: false) ant.sequential { def testDir = "${basedir}/grails-tests" if (new File("${testDir}/CVS").exists()) { println """ WARNING: Your Grails tests directory '${testDir}' is currently under CVS control so the upgrade script cannot move it to the new location of '${basedir}/test/integration'. Please move the directory using the relevant CVS commands.""" } else if (new File("${testDir}/.svn").exists()) { println """ WARNING: Your Grails tests directory '${testDir}' is currently under SVN control so the upgrade script cannot move it to the new location of '${basedir}/test/integration'. Please move the directory using the relevant SVN commands.""" } else { if (new File(testDir).exists()) { move(todir: "${basedir}/test/integration") { fileset(dir: testDir, includes: "**") } delete(dir: testDir) } } delete(dir: "${basedir}/tmp", failonerror: false) // Unpack the shared files into a temporary directory, and then // copy over the IDE files. def tmpDir = new File("${basedir}/tmp-upgrade") grailsUnpack(dest: tmpDir.path, src: "grails-shared-files.jar") copy(todir: "${basedir}") { fileset(dir: tmpDir.path, includes: "*") } delete(dir: tmpDir.path) launderIDESupportFiles() copy(todir: "${basedir}/web-app") { fileset(dir: "${grailsHome}/src/war") { include(name: "**/**") exclude(name: "WEB-INF/**") present(present: "srconly", targetdir: "${basedir}/web-app") } } copy(file: "${grailsHome}/src/war/WEB-INF/sitemesh.xml", tofile: "${basedir}/web-app/WEB-INF/sitemesh.xml", overwrite: true) copy(file: "${grailsHome}/src/war/WEB-INF/applicationContext.xml", tofile: "${basedir}/web-app/WEB-INF/applicationContext.xml", overwrite: true) if (!isPluginProject) { // Install application-only files if needed, exact "one file only" matches ['Config.groovy'].each() {template -> if (!new File(baseFile, '/grails-app/conf').listFiles().find { it.name.equals(template) }) { copy(tofile: "${basedir}/grails-app/conf/${template}") { fileset(file: "${grailsHome}/src/grails/grails-app/conf/${template}") { present(present: "srconly", targetdir: "${basedir}/grails-app/conf") } } } } // Install application-only files if needed, with suffix matching ['DataSource.groovy'].each() {template -> if (!new File(baseFile, '/grails-app/conf').listFiles().find { it.name.startsWith(template) }) { copy(tofile: "${basedir}/grails-app/conf/${template}") { fileset(file: "${grailsHome}/src/grails/grails-app/conf/${template}") { present(present: "srconly", targetdir: "${basedir}/grails-app/conf") } } } } } // Both applications and plugins can have UrlMappings, but only install default if there is nothing already ['UrlMappings.groovy'].each() {template -> if (!new File(baseFile, '/grails-app/conf').listFiles().find { it.name.endsWith(template) }) { copy(tofile: "${basedir}/grails-app/conf/${template}") { fileset(file: "${grailsHome}/src/grails/grails-app/conf/${template}") { present(present: "srconly", targetdir: "${basedir}/grails-app/conf") } } } } // if Config.groovy exists and it does not contain values for // grails.views.default.codec or grails.views.gsp.encoding then // add reasonable defaults for them def configFile = new File(baseFile, '/grails-app/conf/Config.groovy') if (configFile.exists()) { def configSlurper = new ConfigSlurper() def configObject = configSlurper.parse(configFile.toURI().toURL()) def defaultCodec = configObject.grails.views.default.codec def gspEncoding = configObject.grails.views.gsp.encoding if (!defaultCodec || !gspEncoding) { configFile.withWriterAppend { it.writeLine '\n// The following properties have been added by the Upgrade process...' if (!defaultCodec) it.writeLine 'grails.views.default.codec="none" // none, html, base64' if (!gspEncoding) it.writeLine 'grails.views.gsp.encoding="UTF-8"' } } } if (new File("${basedir}/spring").exists()) { move(file: "${basedir}/spring", todir: "${basedir}/grails-app/conf") } if (new File("${basedir}/hibernate").exists()) { move(file: "${basedir}/hibernate", todir: "${basedir}/grails-app/conf") } def appKey = baseName.replaceAll(/\s/, '.').toLowerCase() replace(dir: "${basedir}/web-app/WEB-INF", includes: "**/*.*", token: "@grails.project.key@", value: "${appKey}") copy(todir: "${basedir}/web-app/WEB-INF/tld", overwrite: true) { fileset(dir: "${grailsHome}/src/war/WEB-INF/tld/${servletVersion}") fileset(dir: "${grailsHome}/src/war/WEB-INF/tld", includes: "spring.tld") fileset(dir: "${grailsHome}/src/war/WEB-INF/tld", includes: "grails.tld") } touch(file: "${basedir}/grails-app/i18n/messages.properties") replaceregexp(match: "^.*GRAILS_HOME.*\$", replace: "", flags: "gm") { fileset(dir: "${basedir}", includes: ".classpath") } replace(dir: "${basedir}", includes: ".classpath", token: "", value: "\n${eclipseClasspathLibs()}${eclipseClasspathGrailsJars()}\n") replaceregexp(match: "^\\s*", replace: "", flags: "gm") { fileset(dir: "${basedir}", includes: ".classpath") } } // Add the app name and Grails version to the metadata. updateMetadata("app.name": "$grailsAppName", "app.grails.version": "$grailsVersion") // proceed plugin-specific upgrade logic contained in 'scripts/_Upgrade.groovy' under plugin's root def plugins = GrailsPluginUtils.getPluginBaseDirectories(pluginsHome) if (plugins) { for (pluginDir in plugins) { def f = new File(pluginDir) if (f.isDirectory() && f.name != 'core') { // fix for Windows-style path with backslashes def pluginBase = "${basedir}/plugins/${f.name}".toString().replaceAll("\\\\", "/") // proceed _Upgrade.groovy plugin script if exists def upgradeScript = new File("${pluginBase}/scripts/_Upgrade.groovy") if (upgradeScript.exists()) { event("StatusUpdate", ["Executing ${f.name} plugin upgrade script"]) // instrumenting plugin scripts adding 'pluginBasedir' variable def instrumentedUpgradeScript = "def pluginBasedir = '${pluginBase}'\n" + upgradeScript.text // we are using text form of script here to prevent Gant caching includeTargets << instrumentedUpgradeScript } } } } installDefaultPluginSet() event("StatusUpdate", ["Please make sure you view the README for important information about changes to your source code."]) event("StatusFinal", ["Project upgraded"]) } target("default": "Upgrades a Grails application from a previous version of Grails") { depends(upgrade) }