| /* |
| * 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. |
| */ |
| |
| import org.apache.log4j.LogManager |
| import org.codehaus.groovy.grails.commons.ConfigurationHolder |
| import org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper |
| import org.codehaus.groovy.grails.plugins.logging.Log4jConfig |
| import org.springframework.core.io.FileSystemResource |
| |
| /** |
| * Gant script that packages a Grails application (note: does not create WAR) |
| * |
| * @author Graeme Rocher |
| * |
| * @since 0.4 |
| */ |
| |
| includeTargets << grailsScript("_GrailsCompile") |
| includeTargets << grailsScript("_PackagePlugins") |
| |
| |
| target( createConfig: "Creates the configuration object") { |
| if(configFile.exists()) { |
| def configClass |
| try { |
| configClass = classLoader.loadClass("Config") |
| } catch (ClassNotFoundException cnfe) { |
| println "WARNING: No config found for the application." |
| } |
| if(configClass) { |
| try { |
| config = configSlurper.parse(configClass) |
| config.setConfigFile(configFile.toURI().toURL()) |
| |
| ConfigurationHolder.setConfig(config) |
| } |
| catch(Exception e) { |
| logError("Failed to compile configuration file",e) |
| exit(1) |
| } |
| } |
| } |
| def dataSourceFile = new File("${basedir}/grails-app/conf/DataSource.groovy") |
| if(dataSourceFile.exists()) { |
| try { |
| def dataSourceConfig = configSlurper.parse(classLoader.loadClass("DataSource")) |
| config.merge(dataSourceConfig) |
| ConfigurationHolder.setConfig(config) |
| } |
| catch(ClassNotFoundException e) { |
| println "WARNING: DataSource.groovy not found, assuming dataSource bean is configured by Spring..." |
| } |
| catch(Exception e) { |
| logError("Error loading DataSource.groovy",e) |
| exit(1) |
| } |
| } |
| ConfigurationHelper.initConfig(config, null, classLoader) |
| } |
| |
| target( packageApp : "Implementation of package target") { |
| depends(createStructure, packagePlugins, packageTlds) |
| |
| try { |
| profile("compile") { |
| compile() |
| } |
| } |
| catch(Exception e) { |
| logError("Compilation error",e) |
| exit(1) |
| } |
| profile("creating config") { |
| createConfig() |
| } |
| |
| configureServerContextPath() |
| |
| String i18nDir = "${resourcesDirPath}/grails-app/i18n" |
| ant.mkdir(dir:i18nDir) |
| |
| def files = ant.fileScanner { |
| fileset(dir:"${basedir}/grails-app/views", includes:"**/*.jsp") |
| } |
| |
| if(files.iterator().hasNext()) { |
| ant.mkdir(dir:"${basedir}/web-app/WEB-INF/grails-app/views") |
| ant.copy(todir:"${basedir}/web-app/WEB-INF/grails-app/views") { |
| fileset(dir:"${basedir}/grails-app/views", includes:"**/*.jsp") |
| } |
| } |
| |
| if(config.grails.enable.native2ascii) { |
| profile("converting native message bundles to ascii") { |
| ant.native2ascii(src:"${basedir}/grails-app/i18n", |
| dest:i18nDir, |
| includes:"*.properties", |
| encoding:"UTF-8") |
| } |
| } |
| else { |
| ant.copy(todir:i18nDir) { |
| fileset(dir:"${basedir}/grails-app/i18n", includes:"*.properties") |
| } |
| } |
| ant.copy(todir:classesDirPath) { |
| fileset(dir:"${basedir}", includes:metadataFile.name) |
| } |
| |
| // Copy resources from various directories to the target "resources" dir. |
| packageFiles(basedir) |
| |
| startLogging() |
| |
| loadPlugins() |
| generateWebXml() |
| event("PackagingEnd",[]) |
| } |
| |
| target(configureServerContextPath: "Configuring server context path") { |
| // Get the application context path by looking for a property named 'app.context' in the following order of precedence: |
| // System properties |
| // application.properties |
| // config |
| // default to grailsAppName if not specified |
| |
| serverContextPath = System.getProperty("app.context") |
| serverContextPath = serverContextPath ?: metadata.'app.context' |
| serverContextPath = serverContextPath ?: config.grails.app.context |
| serverContextPath = serverContextPath ?: grailsAppName |
| |
| if(!serverContextPath.startsWith('/')) { |
| serverContextPath = "/${serverContextPath}" |
| } |
| } |
| |
| |
| target(startLogging:"Bootstraps logging") { |
| LogManager.resetConfiguration() |
| if(config.log4j instanceof Closure) { |
| profile("configuring log4j") { |
| new Log4jConfig().configure(config.log4j) |
| } |
| } |
| else { |
| // setup default logging |
| new Log4jConfig().configure() |
| } |
| } |
| |
| target( generateWebXml : "Generates the web.xml file") { |
| depends(classpath) |
| |
| if(buildConfig.grails.config.base.webXml) { |
| def customWebXml = resolveResources(buildConfig.grails.config.base.webXml) |
| if(customWebXml) |
| webXml = customWebXml[0] |
| else { |
| event("StatusError", [ "Custom web.xml defined in config [${buildConfig.grails.config.base.webXml}] could not be found." ]) |
| exit(1) |
| } |
| } |
| else { |
| webXml = new FileSystemResource("${basedir}/src/templates/war/web.xml") |
| def tmpWebXml = "${projectWorkDir}/web.xml.tmp" |
| if(!webXml.exists()) { |
| copyGrailsResource(tmpWebXml, grailsResource("src/war/WEB-INF/web${servletVersion}.template.xml")) |
| } |
| else { |
| ant.copy(file:webXml.file, tofile:tmpWebXml, overwrite:true) |
| } |
| webXml = new FileSystemResource(tmpWebXml) |
| ant.replace(file:tmpWebXml, token:"@grails.project.key@", value:"${grailsAppName}-${grailsEnv}-${grailsAppVersion}") |
| } |
| def sw = new StringWriter() |
| |
| try { |
| profile("generating web.xml from $webXml") { |
| event("WebXmlStart", [webXml.filename]) |
| pluginManager.doWebDescriptor(webXml, sw) |
| webXmlFile.withWriter { |
| it << sw.toString() |
| } |
| event("WebXmlEnd", [webXml.filename]) |
| } |
| } |
| catch(Exception e) { |
| logError("Error generating web.xml file",e) |
| exit(1) |
| } |
| |
| } |
| |
| target(packageTemplates: "Packages templates into the app") { |
| ant.mkdir(dir:scaffoldDir) |
| if(new File("${basedir}/src/templates/scaffolding").exists()) { |
| ant.copy(todir:scaffoldDir, overwrite:true) { |
| fileset(dir:"${basedir}/src/templates/scaffolding", includes:"**") |
| } |
| } |
| else { |
| copyGrailsResources(scaffoldDir, "src/grails/templates/scaffolding/*") |
| } |
| } |
| |
| target(packageTlds:"packages tld definitions for the correct servlet version") { |
| // We don't know until runtime what servlet version to use, so |
| // install the relevant TLDs now. |
| copyGrailsResources("${basedir}/web-app/WEB-INF/tld", "src/war/WEB-INF/tld/${servletVersion}/*") |
| } |
| |
| // Checks whether the project's sources have changed since the last |
| // compilation, and then performs a recompilation if this is the case. |
| // Returns the updated 'lastModified' value. |
| recompileCheck = { lastModified, callback -> |
| try { |
| def ant = new AntBuilder() |
| def classpathId = "grails.compile.classpath" |
| ant.taskdef (name: 'groovyc', classname : 'org.codehaus.groovy.grails.compiler.GrailsCompiler') |
| ant.path(id:classpathId,compileClasspath) |
| |
| ant.groovyc(destdir:classesDirPath, |
| classpathref:classpathId, |
| encoding:"UTF-8", |
| projectName:baseName) { |
| src(path:"${basedir}/src/groovy") |
| src(path:"${basedir}/grails-app/domain") |
| src(path:"${basedir}/grails-app/utils") |
| src(path:"${basedir}/src/java") |
| javac(classpathref:classpathId, debug:"yes") |
| |
| } |
| ant = null |
| } |
| catch(Exception e) { |
| compilationError = true |
| logError("Error automatically restarting container",e) |
| } |
| |
| def tmp = classesDir.lastModified() |
| if(lastModified < tmp) { |
| |
| // run another compile JIT |
| try { |
| callback() |
| } |
| catch(Exception e) { |
| logError("Error automatically restarting container",e) |
| } |
| |
| finally { |
| lastModified = classesDir.lastModified() |
| } |
| } |
| |
| return lastModified |
| } |