import javax.swing.*
import java.awt.Dimension
defaultTasks 'showGui'
apply plugin: 'war'
apply plugin: 'groovy'
apply plugin: 'idea'
apply plugin: 'eclipse'
repositories {
mavenCentral()
// since JQuery is frequently used by add-ons, include their repo here as a convenience
mavenRepo (name: "JQuery", url: "http://code.jquery.com") {
pattern = "[module]-[revision](.[classifier]).[ext]"
}
mavenRepo (name: "JQuery UI", url: "http://code.jquery.com/ui") {
pattern = "[revision]/[module](.[classifier]).[ext]"
}
}
final jsDir = 'js'
configurations {
js // used to specify javascript dependencies. These are all put in 'jsDir' when the .war is built.
}
project.convention.plugins.addoninfo = new AddOnInfo()
final addonInfoFile = new File(buildDir, 'tmp/war/info.xml')
task generateAddOnInfo {
afterEvaluate {
inputs.properties project.convention.plugins.addoninfo.properties
outputs.file addonInfoFile
}
doLast {
def addoninfo = project.convention.plugins.addoninfo
def props = addoninfo.properties
if (props.any { key, value -> value != null }) {
def text = '\r\n'
props.each { key, value ->
if (value) {
def keyText = addoninfo.propNameToXmlElementName(key)
text += " <$keyText>$value$keyText>\r\n"
}
}
text += ''
addonInfoFile.parentFile.mkdirs()
addonInfoFile.text = text
}
else
addonInfoFile.delete()
}
}
war {
dependsOn generateAddOnInfo
inputs.files addonInfoFile, 'LICENSE.txt'
if (extension == 'war')
extension = 'addon'
// lower-case'ify the war name to simplify usage in a web browser (which is case-sensitive)
doFirst {
archiveName = war.baseName.toLowerCase() + '.' + extension
}
into('webapp') // put most stuff into the 'webapp' subdir
// move the stuff that the War task puts into 'WEB-INF' to 'webapp/WEB-INF'
copyAction.rootSpec.childSpecs.each {
if (it.destDir == 'WEB-INF')
it.into('webapp/'+it.destDir)
}
// include addon-info.xml in binary
copyAction.rootSpec.into('') {
from(addonInfoFile)
}
// include license in binary
from('LICENSE.txt') {
into 'WEB-INF'
}
// include javascript libraries
from(configurations.js) {
into jsDir
}
}
// not intended to be used directly. This is the default task for the script. This allows
// the user to "double-click" on 'gradlew' and have the GUI launch.
task showGui(description: 'Starts a graphical user interface for the build') << {
org.gradle.gradleplugin.userinterface.swing.standalone.BlockingApplication.launchAndBlock();
}
// Helper method to get the installation root directory of the server. This method will either
// return whatever is in the 'serverRootDir' property (if it's set) ...
File getServerDir() {
if (!project.ext.has("serverRootDir"))
project.ext.set("serverRootDir", null);
if (project.ext.serverRootDir == null) {
Properties props = new Properties()
File optionsFile = new File('build.options')
if (optionsFile.exists()) {
optionsFile.withReader { props.load(it) }
project.ext.serverRootDir = props.getProperty('serverRootDir')
}
if (project.ext.serverRootDir == null) {
File dir = pickServerDir()
if (dir == null)
throw new Exception("""serverRootDir property (path to webctrl install directory) not set.
Please set the serverRootDir property on the command line (-PserverRootDir=
) or in the userHome/.gradle/gradle.properties file.""")
project.ext.serverRootDir = dir.absolutePath.replaceAll('\\\\', '/')
props.setProperty('serverRootDir', project.ext.serverRootDir)
optionsFile.withWriter { props.store(it, null) }
}
}
return new File(project.ext.serverRootDir)
}
project.ext.set("getServerDir", {getServerDir()});
// Helper methods to get the directory in which to deploy webapps (add-ons).
File getDeployLoc() { new File(getServerDir(), 'addons/'+war.baseName.toLowerCase()) }
// task that deletes the .war (and exploded dir) from the webserver
task cleanDeploy(description: 'Deletes the war from the webserver', overwrite: true, type:Delete)
cleanDeploy.doFirst { delete deploy.destDir }
// task that builds and deploys the .war to the webserver
task deploy(description: 'Deploys the war to the webserver', type: Sync, dependsOn:war) {
ext.destDir = getDeployLoc()
doFirst {
println "Deploying $war.baseName to ${ext.destDir.canonicalPath}"
}
from { zipTree(war.archivePath) }
into { ext.destDir }
fileMode = 0644
}
task signAddon(description: 'Signs the add-on archive', dependsOn: war) << {
ant.signjar(jar: war.archivePath, alias:addon_sign_alias, storepass:addon_sign_password, keystore:addon_sign_keystore)
}
// have war tell you where the archive was put!
war.doLast {
println "War created as ${war.archivePath}"
}
task wrapper(type: Wrapper) {
gradleVersion = '1.0-milestone-9'
jarFile = file('wrapper/gradle-wrapper.jar')
archiveBase = Wrapper.PathBase.GRADLE_USER_HOME
}
File pickServerDir() {
def serverDir = null;
def builder = new groovy.swing.SwingBuilder()
builder.registerBeanFactory('folderChooser', com.jidesoft.swing.FolderChooser)
builder.build {
frame(id: 'mainframe', title:'Pick Server Root Dir', defaultCloseOperation:JFrame.EXIT_ON_CLOSE, size:[440,440], locationRelativeTo: null, show: true) {
panel(border: emptyBorder(10)) {
boxLayout axis: BoxLayout.Y_AXIS
panel {
boxLayout axis: BoxLayout.X_AXIS
label text: 'In order to deploy the add-on to the server (and to run some tests), the build needs to know where the root directory of the server is located.'
}
rigidArea size: new Dimension(0, 10)
panel {
boxLayout axis: BoxLayout.Y_AXIS
panel {
boxLayout axis: BoxLayout.X_AXIS
label text: 'Server root dir:'
hglue()
}
rigidArea size: new Dimension(0, 5)
panel {
boxLayout axis: BoxLayout.X_AXIS
folderChooser id: 'driverDirChooser', currentDirectory: new File('.'), navigationFieldVisible: false, controlButtonsAreShown: false, availableButtons: 0, recentListVisible: false
hglue()
}
}
rigidArea size: new Dimension(0, 10)
panel {
boxLayout axis: BoxLayout.X_AXIS
hglue()
button text: 'Accept', actionPerformed: {
serverDir = builder.driverDirChooser.selectedFolder
dispose()
}
hglue()
button text: 'Cancel', actionPerformed: {
dispose()
}
hglue()
}
}
}
}
// block until the gui is closed
while (builder.mainframe.isVisible()) {
Thread.sleep(100)
}
if (serverDir == null)
throw new GradleException("ERROR: Build cannot continue because the root directory of the server was not specified")
return serverDir
}
idea {
project {
//if you want to set specific jdk and language level
rootProject.afterEvaluate {
jdkName = "${rootProject.sourceCompatibility}"
languageLevel = "${rootProject.sourceCompatibility}"
}
ipr.withXml {
def node = it.asNode()
def vcsConfig = node.component.find { it.'@name' == 'VcsDirectoryMappings' }
vcsConfig.mapping[0].'@vcs' = 'Git'
def mgrNode = node.component.find { it.'@name' == 'ArtifactManager' }
if (!mgrNode)
mgrNode = node.appendNode('component', [name: 'ArtifactManager'])
def webNode = mgrNode?.artifact.find { it.'@name' == 'Add-On Web exploded' }
if (webNode)
mgrNode.remove(webNode)
mgrNode.append(new XmlParser().parseText("""
${pathFactory.relativePath('PROJECT_DIR', getDeployLoc()).relPath}
"""))
def libNode = mgrNode.artifact.root.element.find { it.'@name' == 'WEB-INF' }.element.find { it.'@name' == 'lib' }
def userHome = new File(System.getProperty("user.home"))
modules[0].resolveDependencies().each { dep ->
if (dep instanceof org.gradle.plugins.ide.idea.model.ModuleLibrary)
{
if (dep.scope == 'COMPILE' || dep.scope == 'RUNTIME')
dep.classes.each {
libNode.appendNode('element', [id: 'file-copy', path: pathFactory.relativePath(userHome, '$USER_HOME$', it.file).relPath])
}
}
}
def jsLibs = modules[0].project.configurations.js.resolve()
if (!jsLibs.isEmpty())
{
def jsNode = mgrNode.artifact.root.element.find { it.'@name' == jsDir }
if (!jsNode)
jsNode = mgrNode.artifact.root[0].appendNode('element', [id: 'directory', name: jsDir])
jsLibs.each {
jsNode.appendNode('element', [id: 'file-copy', path: pathFactory.relativePath(userHome, '$USER_HOME$', it).relPath])
}
}
}
}
module {
scopes.PROVIDED.plus += configurations.providedCompile
scopes.PROVIDED.plus += configurations.providedRuntime
scopes.COMPILE.minus += configurations.providedCompile
scopes.RUNTIME.minus += configurations.providedRuntime
inheritOutputDirs = false
outputDir = file("$buildDir/classes/main")
testOutputDir = file("$buildDir/classes/test")
iml.withXml {
def node = it.asNode()
def mgrNode = node.component.find { it.'@name' == 'FacetManager' }
if (!mgrNode)
mgrNode = node.appendNode('component', [name: 'FacetManager'])
def webNode = mgrNode?.facet.find { it.'@name' == 'Add-On Web' }
if (webNode)
mgrNode.remove(webNode)
mgrNode.append(new XmlParser().parseText('''
'''))
}
}
}
buildscript {
repositories { mavenRepo url: 'http://download.java.net/maven/2/' }
dependencies { classpath group: 'com.jidesoft', name: 'jide-oss', version: '2.9.0' }
}
// Support for info.xml
class AddOnInfo {
def String name
def String description
def String version
def String vendor
def String systemMenuProvider
void info(Closure c) {
c.setDelegate(this)
c.setResolveStrategy Closure.DELEGATE_ONLY
c()
}
String propNameToXmlElementName(String propName)
{
// this converts a camelCase string to dash-separated all lower case string (i.e. camel-case)
propName.replaceAll('[A-Z]', { '-'+it.toLowerCase() })
}
Map getProperties() {
[ name:name, description:description, version:version, vendor:vendor, systemMenuProvider:systemMenuProvider ]
}
}