Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

More refactoring of package/compile scripts into classes

  • Loading branch information...
commit 53845f18402a42ee91aa3817def9bd929054afe5 1 parent a3ecafe
@graemerocher graemerocher authored
View
249 grails-core/src/main/groovy/org/codehaus/groovy/grails/compiler/GrailsProjectCompiler.groovy
@@ -16,12 +16,15 @@
package org.codehaus.groovy.grails.compiler
+import grails.util.BuildSettings
+import grails.util.GrailsNameUtils
+import grails.util.PluginBuildSettings
import org.codehaus.groovy.control.CompilationUnit
import org.codehaus.groovy.control.CompilerConfiguration
+import org.codehaus.groovy.grails.plugins.GrailsPluginInfo
import org.springframework.core.io.Resource
- /**
- *
+/**
* Encapsulates the compilation logic required for a Grails application
*
* @author Graeme Rocher
@@ -46,12 +49,32 @@ class GrailsProjectCompiler {
String srcdir
String encoding = "UTF-8"
Resource[] pluginSourceDirectories
+ File targetClassesDir
+ File targetPluginClassesDir
+
+ def commonClasspath
+ def compileClasspath
+ def testClasspath
+ def runtimeClasspath
+
+ BuildSettings buildSettings
+ PluginBuildSettings pluginSettings
+ /**
+ * Constructs a new GrailsProjectCompiler instance for the given PluginBuildSettings and optional classloader
+ *
+ * @param pluginBuildSettings The PluginBuildSettings
+ * @param rootLoader The ClassLoader
- GrailsProjectCompiler(String basedir, String srcdir, Resource[] pluginSrcDirectories, CompilerConfiguration config, ClassLoader rootLoader = Thread.currentThread().getContextClassLoader()) {
- this.basedir = basedir
- this.srcdir = srcdir
- this.pluginSourceDirectories = pluginSrcDirectories
+ */
+ GrailsProjectCompiler(PluginBuildSettings pluginBuildSettings, ClassLoader rootLoader = Thread.currentThread().getContextClassLoader()) {
+ pluginSettings = pluginBuildSettings
+ buildSettings = pluginBuildSettings.buildSettings
+ this.targetClassesDir = buildSettings.classesDir
+ this.targetPluginClassesDir = buildSettings.pluginClassesDir
+ this.basedir = buildSettings.baseDir.absolutePath
+ this.srcdir = buildSettings.sourceDir.absolutePath
+ this.pluginSourceDirectories = pluginBuildSettings.pluginSourceFiles
this.classLoader = rootLoader
this.pluginDescriptor = new File(basedir).listFiles().find { it.name.endsWith("GrailsPlugin.groovy") }
this.config = config
@@ -68,10 +91,18 @@ class GrailsProjectCompiler {
srcDirectories << "${dir}"
}
}
+
+ initializeAntClasspaths()
}
+
+
AntBuilder getAnt() {
- if(this.ant == null) ant = new AntBuilder()
+ if(this.ant == null) {
+ ant = new AntBuilder()
+ ant.taskdef (name: 'groovyc', classname : 'org.codehaus.groovy.grails.compiler.Grailsc')
+ ant.path(id: "grails.compile.classpath", compileClasspath)
+ }
return ant
}
@@ -80,11 +111,103 @@ class GrailsProjectCompiler {
}
/**
+ * Configures the Grails classpath, should be called prior to any call to {@link #compile(Object) }
+ */
+ void configureClasspath() {
+
+ ant.path(id: "grails.compile.classpath", compileClasspath)
+ ant.path(id: "grails.test.classpath", testClasspath)
+ ant.path(id: "grails.runtime.classpath", runtimeClasspath)
+
+ def grailsDir = new File("${basedir}/grails-app").listFiles()
+ StringBuffer cpath = new StringBuffer("")
+
+ def jarFiles = getJarFiles()
+
+ for (dir in grailsDir) {
+ cpath << dir.absolutePath << File.pathSeparator
+ // Adding the grails-app folders to the root loader causes re-load issues as
+ // root loader returns old class before the grails GCL attempts to recompile it
+ // rootLoader?.addURL(dir.URL)
+ }
+ cpath << targetClassesDir.absolutePath<< File.pathSeparator
+ cpath << targetPluginClassesDir.absolutePath << File.pathSeparator
+
+ cpath << "${basedir}/web-app/WEB-INF" << File.pathSeparator
+ for (File jar in jarFiles) {
+ cpath << jar.absolutePath << File.pathSeparator
+ }
+
+ // We need to set up this configuration so that we can compile the
+ // plugin descriptors, which lurk in the root of the plugin's project directory.
+ config = new CompilerConfiguration()
+ config.setClasspath(cpath.toString())
+ config.sourceEncoding = "UTF-8"
+
+ // The resources directory must be created before it is added to
+ // the root loader, otherwise it is quietly ignored. In other words,
+ // if the directory is created after its path has been added to the
+ // root loader, it will not be included in the classpath.
+ def resourcesDir = new File(buildSettings.resourcesDir.path)
+ if (!resourcesDir.exists()) {
+ resourcesDir.mkdirs()
+ }
+ classLoader?.addURL(resourcesDir.toURI().toURL())
+ }
+
+ /**
+ * Obtains all JAR files for the project that aren't declared via BuildConfig
+ *
+ * @return A list of JAR files
+ */
+ List<File> getJarFiles() {
+ final libDirPath = "${basedir}/lib"
+ def jarFiles = listJarFiles(libDirPath)
+ def pluginJars = pluginSettings.pluginJarFiles
+
+ for (pluginJar in pluginJars) {
+ boolean matches = jarFiles.any {it.name == pluginJar.file.name}
+ if (!matches) jarFiles.add(pluginJar.file)
+ }
+
+ def userJars = listJarFiles("${buildSettings.userHome}/.grails/lib")
+ for (userJar in userJars) {
+ jarFiles.add(userJar)
+ }
+
+ jarFiles.addAll(getExtraDependencies())
+
+ jarFiles
+ }
+
+ private List<File> listJarFiles(String libDirPath) {
+ return new File(libDirPath).listFiles({ File f -> f.name.endsWith(".jar")} as FileFilter)?.toList() ?: []
+ }
+
+ /**
+ * Extra dependencies defined by the 'grails.compiler.dependencies' config option in BuildConfig
+ *
+ * @return
+ */
+ List<File> getExtraDependencies() {
+ def jarFiles =[]
+ final buildConfig = buildSettings.config
+ if (buildConfig?.grails?.compiler?.dependencies) {
+ def extraDeps = ant.fileScanner(buildConfig.grails.compiler.dependencies)
+ for (jar in extraDeps) {
+ jarFiles << jar
+ }
+ }
+ jarFiles
+ }
+
+
+ /**
* Compiles project sources to the given target directory
*
* @param targetDir The target directory to compile to
*/
- void compile(targetDir) {
+ void compile(targetDir = targetClassesDir ) {
def compilerPaths = { String classpathId ->
for(srcPath in srcDirectories) {
@@ -115,7 +238,7 @@ class GrailsProjectCompiler {
*
* @param targetDir The target directory to compile to
*/
- void compilePlugins(targetDir) {
+ void compilePlugins(targetDir = targetPluginClassesDir) {
def classesDirPath = targetDir
ant.mkdir(dir:classesDirPath)
@@ -151,6 +274,49 @@ class GrailsProjectCompiler {
}
/**
+ * Compiles GSP pages for the given application name to the (optional) target directory
+ *
+ * @param grailsAppName The app name
+ * @param classesDir The optional classes dir, defaults to one provided by PluginBuildSettings in constructor
+ */
+ void compileGroovyPages(String grailsAppName, classesDir = targetClassesDir) {
+ ant.taskdef (name: 'gspc', classname : 'org.codehaus.groovy.grails.web.pages.GroovyPageCompilerTask')
+ // compile gsps in grails-app/views directory
+ File gspTmpDir = new File(buildSettings.projectWorkDir, "gspcompile")
+ ant.gspc(destdir:classesDir,
+ srcdir:"${basedir}/grails-app/views",
+ packagename:GrailsNameUtils.getPropertyNameForLowerCaseHyphenSeparatedName(grailsAppName),
+ serverpath:"/WEB-INF/grails-app/views/",
+ classpathref:"grails.compile.classpath",
+ tmpdir:gspTmpDir)
+
+ // compile gsps in web-app directory
+ ant.gspc(destdir:classesDir,
+ srcdir:"${basedir}/web-app",
+ packagename:"${GrailsNameUtils.getPropertyNameForLowerCaseHyphenSeparatedName(grailsAppName)}_webapp",
+ serverpath:"/",
+ classpathref:"grails.compile.classpath",
+ tmpdir:gspTmpDir)
+
+ // compile views in plugins
+ def pluginInfos = pluginSettings.supportedPluginInfos
+ if (pluginInfos) {
+ for (GrailsPluginInfo info in pluginInfos) {
+ File pluginViews = new File(info.pluginDir.file, "grails-app/views")
+ if (pluginViews.exists()) {
+ def viewPrefix="/WEB-INF/plugins/${info.name}-${info.version}/grails-app/views/"
+ ant.gspc(destdir:classesDir,
+ srcdir:pluginViews,
+ packagename:GrailsNameUtils.getPropertyNameForLowerCaseHyphenSeparatedName(info.name),
+ serverpath:viewPrefix,
+ classpathref:"grails.compile.classpath",
+ tmpdir:gspTmpDir)
+ }
+ }
+ }
+ }
+
+ /**
* Compiles a given plugin descriptor file - *GrailsPlugin.groovy.
*/
protected compilePluginDescriptor(File descriptor, File classesDir) {
@@ -200,4 +366,69 @@ class GrailsProjectCompiler {
watcher.start()
return watcher
}
+
+ private initializeAntClasspaths() {
+
+ commonClasspath = {
+ def grailsDir = new File("${basedir}/grails-app").listFiles()
+ for (File file in grailsDir) {
+ pathelement(location: "${file.absolutePath}")
+ }
+
+ def pluginLibDirs = pluginSettings.pluginLibDirectories.findAll { it.exists() }
+ for (pluginLib in pluginLibDirs) {
+ fileset(dir: pluginLib.file.absolutePath)
+ }
+ }
+
+ compileClasspath = {
+ commonClasspath.delegate = delegate
+ commonClasspath.call()
+
+ def dependencies = buildSettings.compileDependencies
+ if (dependencies) {
+ for (File f in dependencies) {
+ if (f) {
+ pathelement(location: f.absolutePath)
+ }
+ }
+ }
+ pathelement(location: "${targetPluginClassesDir.absolutePath}")
+ }
+
+ testClasspath = {
+ commonClasspath.delegate = delegate
+ commonClasspath.call()
+
+ def dependencies = buildSettings.testDependencies
+ if (dependencies) {
+
+ for (File f in dependencies) {
+ if (f) {
+ pathelement(location: f.absolutePath)
+ }
+ }
+ }
+
+ pathelement(location: "${targetClassesDir.absolutePath}")
+ pathelement(location: "${targetPluginClassesDir.absolutePath}")
+ }
+
+ runtimeClasspath = {
+ commonClasspath.delegate = delegate
+ commonClasspath.call()
+
+ def dependencies = buildSettings.runtimeDependencies
+ if (dependencies) {
+ for (File f in dependencies) {
+ if (f) {
+ pathelement(location: f.absolutePath)
+ }
+ }
+ }
+
+ pathelement(location: "${targetPluginClassesDir.absolutePath}")
+ pathelement(location: "${targetClassesDir.absolutePath}")
+ }
+ }
}
View
89 grails-core/src/main/groovy/org/codehaus/groovy/grails/compiler/GrailsProjectPackager.groovy
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2011 SpringSource
+ *
+ * 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.
+ */
+
+package org.codehaus.groovy.grails.compiler
+
+import grails.util.BuildSettings
+
+/**
+ * Encapsulates the logic to package a project ready for execution
+ *
+ * TODO: This class is a work-in-progress port from the code in the script _GrailsPackage.groovy
+ *
+ * @since 1.4
+ * @author Graeme Rocher
+ */
+class GrailsProjectPackager {
+
+
+ GrailsProjectCompiler projectCompiler
+ BuildSettings buildSettings
+ AntBuilder ant
+
+ GrailsProjectPackager(GrailsProjectCompiler compiler) {
+ this.projectCompiler = compiler
+ buildSettings = compiler.buildSettings
+ ant = compiler.ant
+ }
+
+ /**
+ * Packages any config files such as Hibernate config, XML files etc.
+ * to the projects resources directory
+ *
+ * @param from Where to package from
+ */
+ void packageConfigFiles(String from) {
+ def ant = new AntBuilder()
+ def targetPath = buildSettings.resourcesDir.path
+ def dir = new File(from, "grails-app/conf")
+ if (dir.exists()) {
+ ant.copy(todir:targetPath, failonerror:false) {
+ fileset(dir:dir.path) {
+ exclude(name:"**/*.groovy")
+ exclude(name:"**/log4j*")
+ exclude(name:"hibernate/**/*")
+ exclude(name:"spring/**/*")
+ }
+ }
+ }
+
+ dir = new File(dir, "hibernate")
+ if (dir.exists()) {
+ ant.copy(todir:targetPath, failonerror:false) {
+ fileset(dir:dir.path, includes:"**/*")
+ }
+ }
+
+ dir = new File(from, "src/groovy")
+ if (dir.exists()) {
+ ant.copy(todir:targetPath, failonerror:false) {
+ fileset(dir:dir.path) {
+ exclude(name:"**/*.groovy")
+ exclude(name:"**/*.java")
+ }
+ }
+ }
+
+ dir = new File(from, "src/java")
+ if (dir.exists()) {
+ ant.copy(todir:targetPath, failonerror:false) {
+ fileset(dir:dir.path) {
+ exclude(name:"**/*.java")
+ }
+ }
+ }
+ }
+}
View
194 scripts/_GrailsClasspath.groovy
@@ -34,197 +34,27 @@ includeTargets << grailsScript("_GrailsSettings")
classpathSet = false
includePluginJarsOnClasspath = true
+projectCompiler = new org.codehaus.groovy.grails.compiler.GrailsProjectCompiler(pluginSettings, rootLoader)
+projectCompiler.ant = ant
target(name:'classpath', description: "Sets the Grails classpath", prehook:null, posthook:null) {
setClasspath()
}
-/**
- * Obtains all of the plug-in Lib directories
- * @deprecated Use "pluginSettings.pluginLibDirectories"
- */
-getPluginLibDirs = {
- pluginSettings.pluginLibDirectories
-}
-
-/**
- * Obtains an array of all plug-in JAR files as Spring Resource objects
- * @deprecated Use "pluginSettings.pluginJarFiles".
- */
-getPluginJarFiles = {
- pluginSettings.pluginJarFiles
-}
-
-getJarFiles = {->
- def jarFiles = resolveResources("file:${basedir}/lib/*.jar").toList()
- if (includePluginJarsOnClasspath) {
-
- def pluginJars = pluginSettings.pluginJarFiles
-
- for (pluginJar in pluginJars) {
- boolean matches = jarFiles.any {it.file.name == pluginJar.file.name}
- if (!matches) jarFiles.add(pluginJar)
- }
- }
-
- def userJars = resolveResources("file:${userHome}/.grails/lib/*.jar")
- for (userJar in userJars) {
- jarFiles.add(userJar)
- }
-
- jarFiles.addAll(getExtraDependencies())
-
- jarFiles
-}
-
-getExtraDependencies = {
- def jarFiles =[]
- if (buildConfig?.grails?.compiler?.dependencies) {
- def extraDeps = ant.fileScanner(buildConfig.grails.compiler.dependencies)
- for (jar in extraDeps) {
- jarFiles << new FileSystemResource(jar)
- }
- }
- jarFiles
-}
-
-populateRootLoader = {rootLoader, jarFiles ->
- for (jar in getExtraDependencies()) {
- rootLoader?.addURL(jar.URL)
- }
- rootLoader?.addURL(new File("${basedir}/web-app/WEB-INF").toURI().toURL())
-}
-
-// Only used by "grailsClasspath" closure.
-//defaultCompilerDependencies = { antBuilder ->
-// if (antBuilder) {
-// delegate = antBuilder
-// resolveStrategy = Closure.DELEGATE_FIRST
-// }
-//
-// grailsSettings.compileDependencies?.each { file ->
-// file(file: file.absolutePath)
-// }
-//
-// if (new File("${basedir}/lib").exists()) {
-// fileset(dir: "${basedir}/lib")
-// }
-//}
-
-commonClasspath = {
- def grailsDir = resolveResources("file:${basedir}/grails-app/*")
- for (d in grailsDir) {
- pathelement(location: "${d.file.absolutePath}")
- }
-
- def pluginLibDirs = pluginSettings.pluginLibDirectories.findAll { it.exists() }
- for (pluginLib in pluginLibDirs) {
- fileset(dir: pluginLib.file.absolutePath)
- }
-}
-
-compileClasspath = {
- commonClasspath.delegate = delegate
- commonClasspath.call()
-
- def dependencies = grailsSettings.compileDependencies
- if (dependencies) {
- for (File f in dependencies) {
- if (f) {
- pathelement(location: f.absolutePath)
- }
- }
- }
- pathelement(location: "${pluginClassesDir.absolutePath}")
-}
-
-testClasspath = {
- commonClasspath.delegate = delegate
- commonClasspath.call()
-
- def dependencies = grailsSettings.testDependencies
- if (dependencies) {
-
- for (File f in dependencies) {
- if (f) {
- pathelement(location: f.absolutePath)
- }
- }
- }
-
- pathelement(location: "${classesDir.absolutePath}")
- pathelement(location: "${pluginClassesDir.absolutePath}")
-}
-
-runtimeClasspath = {
- commonClasspath.delegate = delegate
- commonClasspath.call()
-
- def dependencies = grailsSettings.runtimeDependencies
- if (dependencies) {
- for (File f in dependencies) {
- if (f) {
- pathelement(location: f.absolutePath)
- }
- }
- }
-
- pathelement(location: "${pluginClassesDir.absolutePath}")
- pathelement(location: "${classesDir.absolutePath}")
-}
-
-/**
- * Converts an Ant path into a list of URLs.
- */
-classpathToUrls = { String classpathId ->
- def propName = "converted.classpath"
- ant.pathconvert(refid: classpathId, dirsep: "/", pathsep: ":", property: propName)
-
- return ant.project.properties.get(propName).split(":").collect { new File(it).toURI().toURL() }
-}
+// The following variables are here for compatibility with older versions of Grails
+getPluginLibDirs = pluginSettings.&pluginLibDirectories
+getPluginJarFiles = pluginSettings.&pluginJarFiles
+getJarFiles = projectCompiler.&getJarFiles
+getExtraDependencies = projectCompiler.&getExtraDependencies
+commonClasspath = projectCompiler.commonClasspath
+compileClasspath = projectCompiler.compileClasspath
+testClasspath = projectCompiler.testClasspath
+runtimeClasspath = projectCompiler.runtimeClasspath
void setClasspath() {
// Make sure the following code is only executed once.
if (classpathSet) return
- ant.path(id: "grails.compile.classpath", compileClasspath)
- ant.path(id: "grails.test.classpath", testClasspath)
- ant.path(id: "grails.runtime.classpath", runtimeClasspath)
-
- def grailsDir = resolveResources("file:${basedir}/grails-app/*")
- StringBuffer cpath = new StringBuffer("")
-
- def jarFiles = getJarFiles()
-
- for (dir in grailsDir) {
- cpath << dir.file.absolutePath << File.pathSeparator
- // Adding the grails-app folders to the root loader causes re-load issues as
- // root loader returns old class before the grails GCL attempts to recompile it
- // rootLoader?.addURL(dir.URL)
- }
- cpath << classesDirPath << File.pathSeparator
- cpath << pluginClassesDirPath << File.pathSeparator
-
- cpath << "${basedir}/web-app/WEB-INF" << File.pathSeparator
- for (jar in jarFiles) {
- cpath << jar.file.absolutePath << File.pathSeparator
- }
-
- // We need to set up this configuration so that we can compile the
- // plugin descriptors, which lurk in the root of the plugin's project directory.
- compConfig = new CompilerConfiguration()
- compConfig.setClasspath(cpath.toString())
- compConfig.sourceEncoding = "UTF-8"
-
- // The resources directory must be created before it is added to
- // the root loader, otherwise it is quietly ignored. In other words,
- // if the directory is created after its path has been added to the
- // root loader, it will not be included in the classpath.
- def resourcesDir = new File(resourcesDirPath)
- if (!resourcesDir.exists()) {
- resourcesDir.mkdirs()
- }
- rootLoader?.addURL(resourcesDir.toURI().toURL())
-
+ projectCompiler.configureClasspath()
classpathSet = true
}
View
47 scripts/_GrailsCompile.groovy
@@ -33,17 +33,8 @@ includeTargets << grailsScript("_GrailsArgParsing")
ant.taskdef (name: 'groovyc', classname : 'org.codehaus.groovy.grails.compiler.Grailsc')
ant.path(id: "grails.compile.classpath", compileClasspath)
-projectCompiler = null
-
target(setCompilerSettings: "Updates the compile build settings based on args") {
depends(parseArguments)
-
- projectCompiler = new GrailsProjectCompiler(basedir,
- grailsSettings.sourceDir.absolutePath,
- pluginSettings.pluginSourceFiles,
- compConfig,
- classLoader)
- projectCompiler.ant = ant
if (argsMap.containsKey('verboseCompile')) {
grailsSettings.verboseCompile = argsMap.verboseCompile as boolean
projectCompiler.verbose = grailsSettings.verboseCompile
@@ -82,42 +73,6 @@ target(compilepackage : "Compile & Compile GSP files") {
depends(compile, compilegsp)
}
-
-
target(compilegsp : "Compile GSP files") {
- ant.taskdef (name: 'gspc', classname : 'org.codehaus.groovy.grails.web.pages.GroovyPageCompilerTask')
- // compile gsps in grails-app/views directory
- File gspTmpDir = new File(grailsSettings.projectWorkDir, "gspcompile")
- ant.gspc(destdir:classesDir,
- srcdir:"${basedir}/grails-app/views",
- packagename:GrailsNameUtils.getPropertyNameForLowerCaseHyphenSeparatedName(grailsAppName),
- serverpath:"/WEB-INF/grails-app/views/",
- classpathref:"grails.compile.classpath",
- tmpdir:gspTmpDir)
-
- // compile gsps in web-app directory
- ant.gspc(destdir:classesDir,
- srcdir:"${basedir}/web-app",
- packagename:"${GrailsNameUtils.getPropertyNameForLowerCaseHyphenSeparatedName(grailsAppName)}_webapp",
- serverpath:"/",
- classpathref:"grails.compile.classpath",
- tmpdir:gspTmpDir)
-
- // compile views in plugins
- loadPlugins()
- def pluginInfos = pluginSettings.supportedPluginInfos
- if (pluginInfos) {
- for (GrailsPluginInfo info in pluginInfos) {
- File pluginViews = new File(info.pluginDir.file, "grails-app/views")
- if (pluginViews.exists()) {
- def viewPrefix="/WEB-INF/plugins/${info.name}-${info.version}/grails-app/views/"
- ant.gspc(destdir:classesDir,
- srcdir:pluginViews,
- packagename:GrailsNameUtils.getPropertyNameForLowerCaseHyphenSeparatedName(info.name),
- serverpath:viewPrefix,
- classpathref:"grails.compile.classpath",
- tmpdir:gspTmpDir)
- }
- }
- }
+ projectCompiler.compileGroovyPages(grailsAppName, grailsSettings.classesDir)
}
Please sign in to comment.
Something went wrong with that request. Please try again.