Commits

shemnon committed 7fd6c22

change artifact ID to more descriptive gradle-javafx-plugin

  • Participants
  • Parent commits 599ee04

Comments (0)

Files changed (19)

gradle-javafx-plugin/build.gradle

+apply plugin: 'groovy'
+apply plugin: 'maven'
+
+group = 'com.bitbucket.shemnon.javafxplugin'
+version = '0.2.0-SNAPSHOT'
+
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+    groovy 'org.codehaus.groovy:groovy-all:2.0.5'
+    compile gradleApi()
+    compile files("${System.properties['java.home']}/../lib/ant-javafx.jar")
+    compile files("${System.properties['java.home']}/lib/jfxrt.jar")
+}
+
+uploadArchives {
+    repositories {
+        mavenDeployer {
+            repository(url:"https://api.bintray.com/maven/shemnon/javafx-gradle/gradle-javafx-plugin/",
+                id: 'bintray-shemnon-javafx-gradle-plugin'
+            ) {
+                try {
+                    authentication(
+                        userName: bintrayUserName,
+                        password: bintrayApiKey
+                    )
+                } catch (MissingPropertyException pne) {
+                    // ignore, don't authenticate
+                }
+            }
+            snapshotRepository (url: "https://repository-javafx-gradle-plugin.forge.cloudbees.com/snapshot/",
+                id: 'cloudbees-javafx-gradle-plugin'
+            ) {
+                try {
+                    authentication(
+                        userName: cloudbeesUserName,
+                        password: cloudbeesPassword
+                    )
+                } catch (MissingPropertyException pne) {
+                    // ignore, don't authenticate
+                }
+            }
+        }
+    }
+}
+
+[install.repositories.mavenInstaller, uploadArchives.repositories.mavenDeployer]*.pom*.whenConfigured {pom ->
+    pom.project {
+        dependencies {
+            dependency {
+                groupId 'net.java.openjdk'
+                artifactId 'jfxrt'
+                version '8b72'
+                scope 'system'
+                systemPath '${java.home}/lib/jfxrt.jar'
+            }
+            dependency {
+                groupId 'net.java.openjdk'
+                artifactId 'ant-javafx'
+                version '8b72'
+                scope 'system'
+                systemPath '${java.home}/../lib/ant-javafx.jar'
+            }
+        }
+    }
+}
+
+

gradle-javafx-plugin/src/main/groovy/com/bitbucket/shemnon/javafxplugin/JavaFXPlugin.groovy

+/*
+ * Copyright (c) 2012, Danno Ferrin
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions are met:
+ *       * Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ *       * Redistributions in binary form must reproduce the above copyright
+ *         notice, this list of conditions and the following disclaimer in the
+ *         documentation and/or other materials provided with the distribution.
+ *       * Neither the name of Danno Ferrin nor the
+ *         names of contributors may be used to endorse or promote products
+ *         derived from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *   DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ *   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.bitbucket.shemnon.javafxplugin
+
+import org.gradle.api.Project
+import org.gradle.api.Plugin
+import com.bitbucket.shemnon.javafxplugin.tasks.JavaFXDeployTask
+import com.bitbucket.shemnon.javafxplugin.tasks.JavaFXJarTask
+import org.gradle.api.plugins.JavaPluginConvention
+import org.gradle.api.file.FileCollection
+import org.gradle.api.tasks.SourceSet
+import org.gradle.api.tasks.JavaExec
+import org.gradle.api.artifacts.ConfigurationContainer
+import org.gradle.api.artifacts.Configuration
+import org.gradle.api.plugins.JavaPlugin
+import com.bitbucket.shemnon.javafxplugin.tasks.JavaFXCSSToBinTask
+import com.bitbucket.shemnon.javafxplugin.tasks.JavaFXSignJarTask
+import com.bitbucket.shemnon.javafxplugin.tasks.GenKeyTask
+import org.gradle.api.DefaultTask
+import org.gradle.api.artifacts.ResolvedArtifact
+
+
+class JavaFXPlugin implements Plugin<Project> {
+
+    public static final String PROVIDED_COMPILE_CONFIGURATION_NAME = "providedCompile";
+    public static final String PROVIDED_RUNTIME_CONFIGURATION_NAME = "providedRuntime";
+
+    @Override
+    void apply(Project project) {
+        project.getPlugins().apply(JavaPlugin)
+        project.extensions.create('javafx', JavaFXPluginExtension)
+
+        configureConfigurations(project.configurations)
+
+        def jfxrtJarFile = project.files(findJFXJar())
+        project.javafx {
+            jfxrtJar = jfxrtJarFile
+            antJavaFXJar = project.files(findAntJavaFXJar())
+            mainClass = "${project.group}${(project.group&&project.name)?'.':''}${project.name}${(project.group||project.name)?'.':''}Main"
+            appName = project.name //FIXME capatalize
+            packaging = 'all'
+            debugKey {
+                alias = 'javafxdebugkey'
+                keyPass = 'JavaFX'
+                keyStore = new File(project.projectDir, 'debug.keyStore')
+                storePass = 'JavaFX'
+            }
+            signingMode = 'debug'
+        }
+
+
+        project.dependencies {
+            providedCompile jfxrtJarFile
+        }
+        project.sourceSets {
+            'package' {
+                resources {
+                    srcDir 'src/main'
+                }
+            }
+        }
+
+        configureJavaFXCSSToBinTask(project)
+        configureJavaFXJarTask(project)
+        configureGenerateDebugKeyTask(project)
+        configureJavaFXSignJarTask(project)
+        configureJFXDeployTask(project)
+        configureScenicViewTask(project)
+        configureRunTask(project)
+        configureDebugTask(project)
+    }
+
+
+    private configureJavaFXCSSToBinTask(Project project) {
+        def task = project.task("cssToBin", type: JavaFXCSSToBinTask,
+                description: "Converts CSS to Binary CSS.",
+                group: 'Build')
+
+        task.conventionMapping.distsDir = {convention, aware -> convention.getPlugin(JavaPluginConvention).sourceSets.main.output.resourcesDir}
+
+        task.conventionMapping.inputFiles = {convention, aware ->
+            convention.getPlugin(JavaPluginConvention).sourceSets.main.resources
+        }
+
+        project.tasks.getByName("classes").dependsOn(task)
+        task.dependsOn(project.tasks.getByName("processResources"))
+    }
+
+    private configureJavaFXJarTask(Project project) {
+        def task = project.task("jfxJar", type: JavaFXJarTask,
+                description: "Jars up the classes and adds JavaFX specific packaging.",
+                group: 'Build')
+
+        task.conventionMapping.mainClass = {convention, aware -> project.javafx.mainClass }
+
+        task.conventionMapping.outputDirectory = {convention, aware ->
+            "$project.libsDir" as File}
+        task.conventionMapping.outputFile = {convention, aware ->
+            "${project.archivesBaseName}.jar" as File}
+
+        task.conventionMapping.inputFiles = {convention, aware -> convention.getPlugin(JavaPluginConvention).sourceSets.main.output}
+        task.conventionMapping.classpath = {convention, aware ->
+            FileCollection compileClasspath = project.convention.getPlugin(JavaPluginConvention).sourceSets[SourceSet.MAIN_SOURCE_SET_NAME].compileClasspath;
+            Configuration providedCompile = project.configurations[PROVIDED_COMPILE_CONFIGURATION_NAME];
+            FileCollection output = compileClasspath - providedCompile;
+        }
+    }
+
+    private configureGenerateDebugKeyTask(Project project) {
+        def task = project.task("generateDebugKey", type: GenKeyTask,
+                description: "Generates the JAvaFX Debug Key.",
+                group: 'Build')
+
+        task.conventionMapping.alias     = {convention, aware -> project.javafx.debugKey.alias }
+        task.conventionMapping.keyPass   = {convention, aware -> project.javafx.debugKey.keyPass }
+        task.conventionMapping.keyStore  = {convention, aware -> project.javafx.debugKey.keyStore }
+        task.conventionMapping.storePass = {convention, aware -> project.javafx.debugKey.storePass }
+        task.conventionMapping.storeType = {convention, aware -> project.javafx.debugKey.storeType }
+        task.conventionMapping.dname     = {convention, aware -> 'CN=JavaFX Gradle Plugin Default Debug Key, O=JavaFX Debug' }
+        task.conventionMapping.validity  = {convention, aware -> ((365.25) * 25 as int) /* 25 years */ }
+    }
+
+    private configureJavaFXSignJarTask(Project project) {
+        def task = project.task("jfxSignJar", type: JavaFXSignJarTask,
+                description: "Signs the JavaFX jars the JavaFX way.",
+                group: 'Build')
+
+        ['alias', 'keyPass', 'storePass', 'storeType'].each { prop ->
+            task.conventionMapping[prop]  = {convention, aware ->
+                def jfxc = project.javafx;
+                def props = project.properties
+                def mode = props['javafx.signingMode']  ?: jfxc.signingMode
+                return props?."javafx.${mode}Key.$prop" ?: jfxc?."${mode}Key"?."$prop"
+            }
+        }
+        task.conventionMapping.keyStore  = {convention, aware ->
+            def jfxc = project.javafx;
+            def props = project.properties
+            def mode = props['javafx.signingMode']  ?: jfxc.signingMode
+            String keyFile = props?."javafx.${mode}Key.keyStore"
+            return keyFile == null ? jfxc?."${mode}Key"?.keyStore : new File(keyFile)
+        }
+
+        task.conventionMapping.outdir = {convention, aware -> "$project.libsDir/../signed" as File}
+
+        task.conventionMapping.inputFiles = {convention, aware ->
+            FileCollection runtimeClasspath = project.convention.getPlugin(JavaPluginConvention).sourceSets[SourceSet.MAIN_SOURCE_SET_NAME].runtimeClasspath;
+            Configuration providedRuntime = project.configurations[PROVIDED_RUNTIME_CONFIGURATION_NAME];
+            runtimeClasspath  + project.files("$project.libsDir/${project.archivesBaseName}.jar" as File)- providedRuntime
+        }
+
+        task.dependsOn(project.tasks.getByName("jfxJar"))
+        task.dependsOn(project.tasks.getByName("generateDebugKey"))
+    }
+
+    private configureJFXDeployTask(Project project) {
+        def task = project.task("jfxDeploy", type: JavaFXDeployTask,
+                description: "Processes the JavaFX jars and generates webstart and native packages.",
+                group: 'Build')
+
+        task.conventionMapping.packaging = {convention, aware -> project.javafx.packaging }
+
+        task.conventionMapping.antJavaFXJar = {convention, aware ->
+            project.javafx.antJavaFXJar }
+
+        task.conventionMapping.appID = {convention, aware -> project.javafx.appID }
+        task.conventionMapping.appName = {convention, aware -> project.javafx.appName }
+        task.conventionMapping.mainClass = {convention, aware -> project.javafx.mainClass }
+
+
+        task.conventionMapping.inputFiles = {convention, aware ->
+            project.fileTree("$project.libsDir/../signed").include("*.jar")
+        }
+
+        task.conventionMapping.distsDir = {convention, aware -> project.distsDir }
+
+        task.conventionMapping.jvmArgs = {convention, aware -> project.javafx.jvmArgs }
+        task.conventionMapping.systemProperties = {convention, aware -> project.javafx.systemProperties }
+        task.conventionMapping.arguments = {convention, aware -> project.javafx.arguments}
+
+        task.dependsOn(project.tasks.getByName("jfxSignJar"))
+        project.tasks.getByName("assemble").dependsOn(task)
+        project.tasks.getByName("jar").enabled = false
+    }
+    
+    private void configureRunTask(Project project) {
+        JavaExec task = project.task("run", type: JavaExec,
+            description: 'Runs the application.',
+            group: 'Execution')
+
+        task.classpath = project.sourceSets.main.runtimeClasspath
+        task.conventionMapping.main = {convention, aware -> project.javafx.mainClass }
+        task.doFirst {
+            task.jvmArgs project.javafx.jvmArgs
+            task.systemProperties project.javafx.systemProperties
+            if (!task.args) task.args = project.javafx.arguments
+        }
+    }
+
+    private void configureDebugTask(Project project) {
+        JavaExec task = project.task("debug", type:JavaExec,
+            description: 'Runs the applicaiton and sets up debugging on port 5005.',
+            group: 'Execution')
+
+        task.classpath = project.sourceSets.main.runtimeClasspath
+        task.conventionMapping.main = {convention, aware -> project.javafx.mainClass }
+        task.doFirst {
+            task.jvmArgs project.javafx.jvmArgs
+            task.systemProperties project.javafx.systemProperties
+            if (!task.args) task.args = project.javafx.arguments
+        }
+        task.debug = true
+    }
+
+    private void configureScenicViewTask(Project project) {
+        def task = project.task("scenicview", type: DefaultTask,
+                description: 'Adds the ScenicView agent to all Execution Tasks.',
+                group: 'Tools')
+
+        task.doLast {
+            project.configurations {
+                scenicview
+            }
+            project.repositories {
+                ivy  { url 'https://repository-javafx-gradle-plugin.forge.cloudbees.com/release' }
+            }
+            project.dependencies {
+                scenicview 'com.fxexperience.scenicview:scenicview:1.3.0'
+            }
+
+            project.tasks.findAll {it.group == 'Execution' && it instanceof JavaExec}.each {JavaExec execTask ->
+                project.configurations.getByName('scenicview').resolvedConfiguration.resolvedArtifacts.each { ResolvedArtifact ra ->
+                    execTask.jvmArgs = ["-javaagent:$ra.file.canonicalPath"] + execTask.jvmArgs
+                }
+            }
+        }
+    }
+
+    public void configureConfigurations(ConfigurationContainer configurationContainer) {
+        Configuration provideCompileConfiguration = configurationContainer.add(PROVIDED_COMPILE_CONFIGURATION_NAME).setVisible(false).
+                setDescription("Additional compile classpath for libraries that should not be part of the WAR archive.");
+        Configuration provideRuntimeConfiguration = configurationContainer.add(PROVIDED_RUNTIME_CONFIGURATION_NAME).setVisible(false).
+                extendsFrom(provideCompileConfiguration).
+                setDescription("Additional runtime classpath for libraries that should not be part of the WAR archive.");
+        configurationContainer.getByName(JavaPlugin.COMPILE_CONFIGURATION_NAME).extendsFrom(provideCompileConfiguration);
+        configurationContainer.getByName(JavaPlugin.RUNTIME_CONFIGURATION_NAME).extendsFrom(provideRuntimeConfiguration);
+    }
+
+    public File findJFXJar() {
+        def javafxHome = System.env['JFXRT_HOME']
+        File jfxrtHome
+        if (javafxHome) {
+            jfxrtHome = "${javafxHome}" as File
+        } else {
+            final javaHome = System.env['JAVA_HOME']
+            if (javaHome)
+                jfxrtHome = "${javaHome}/jre/lib"  as File
+            else
+                jfxrtHome = "${System.properties['java.home']}/lib" as File
+        }
+
+        File jfxrtJar = new File((File) jfxrtHome, "jfxrt.jar")
+        if (!jfxrtJar.exists()) {
+            println ("""    Please set the environment variable JFXRT_HOME
+    to the directory that contains jfxrt.jar, or set JAVA_HOME.""")
+
+        }
+        println "JavaFX runtime jar: ${jfxrtJar}"
+        return jfxrtJar
+    }
+
+    public File findAntJavaFXJar() {
+        def javafxHome = System.env['JFXRT_HOME']
+        File jfxrtHome
+        if (javafxHome) {
+            jfxrtHome = "${javafxHome}" as File
+        } else {
+            final javaHome = System.env['JAVA_HOME']
+            if (javaHome)
+                jfxrtHome = "${javaHome}/lib"  as File
+            else
+                jfxrtHome = "${System.properties['java.home']}/../lib" as File
+        }
+
+        File antjfxjar = new File((File)jfxrtHome, "ant-javafx.jar")
+        if (!antjfxjar.exists()) {
+            println("""    Please set the environment variable JFXRT_HOME
+    to the directory that contains jfxrt.jar, or set JAVA_HOME.""")
+
+        }
+        println "JavaFX ant jar: ${antjfxjar}"
+        return antjfxjar
+    }
+}

gradle-javafx-plugin/src/main/groovy/com/bitbucket/shemnon/javafxplugin/JavaFXPluginExtension.groovy

+/*
+ * Copyright (c) 2012, Danno Ferrin
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions are met:
+ *       * Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ *       * Redistributions in binary form must reproduce the above copyright
+ *         notice, this list of conditions and the following disclaimer in the
+ *         documentation and/or other materials provided with the distribution.
+ *       * Neither the name of Danno Ferrin nor the
+ *         names of contributors may be used to endorse or promote products
+ *         derived from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *   DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ *   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.bitbucket.shemnon.javafxplugin
+
+import org.gradle.util.ConfigureUtil
+import org.gradle.api.file.FileCollection
+import org.gradle.api.plugins.BasePluginConvention
+import org.gradle.api.Project
+
+class JavaFXPluginExtension { //extends BasePluginConvention {
+
+    // preliminaries
+    FileCollection jfxrtJar
+    FileCollection antJavaFXJar
+
+    // build steps
+    SigningKeyInfo debugKey
+    SigningKeyInfo releaseKey
+
+    String signingMode
+
+    // app info
+    String appID
+    String appName
+    String mainClass
+
+    String packaging
+
+    List<String> jvmArgs = []
+    Map<String, String> systemProperties = [:]
+    List<String> arguments = []
+
+    public debugKey(Closure closure) {
+        debugKey = new SigningKeyInfo(closure)
+    }
+
+    public releaseKey(Closure closure) {
+        releaseKey = new SigningKeyInfo(closure)
+    }
+
+
+}
+
+class SigningKeyInfo {
+    String alias
+    String keyPass
+    File keyStore
+    String storePass
+    String storeType
+
+
+    public SigningKeyInfo(Closure configure) {
+        ConfigureUtil.configure(configure, this)
+    }
+
+    //TODO logic methods
+    //   - determine if a key exists
+    //   - load stuff like validity and dname from existing key
+    //   - prompt for password if set to null on a read
+}

gradle-javafx-plugin/src/main/groovy/com/bitbucket/shemnon/javafxplugin/tasks/GenKeyTask.groovy

+/*
+ * Copyright (c) 2011-2012, Danno Ferrin
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions are met:
+ *       * Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ *       * Redistributions in binary form must reproduce the above copyright
+ *         notice, this list of conditions and the following disclaimer in the
+ *         documentation and/or other materials provided with the distribution.
+ *       * Neither the name of Danno Ferrin nor the
+ *         names of contributors may be used to endorse or promote products
+ *         derived from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *   DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ *   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.bitbucket.shemnon.javafxplugin.tasks;
+
+import org.gradle.api.internal.ConventionTask
+import org.gradle.api.tasks.OutputFile
+import org.gradle.api.tasks.TaskAction
+import org.gradle.process.ExecResult
+import org.gradle.process.internal.DefaultExecAction
+import org.gradle.process.internal.ExecAction
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dannoferrin
+ * Date: 3/8/11
+ * Time: 9:07 PM
+ */
+class GenKeyTask extends ConventionTask {
+
+    @TaskAction
+    processResources() {
+        if (getKeyStore().exists()) return
+
+        ExecAction aaptExec = new DefaultExecAction()
+        aaptExec.workingDir = project.projectDir
+        aaptExec.executable = "${System.properties['java.home']}/bin/keytool"
+
+        def args = []
+        args << '-genkeypair'
+        ['alias', 'dname', 'validity', 'keyPass', 'keyStore', 'storePass', 'storeType'].each {
+            if (this[it]) {
+                args << "-${it.toLowerCase()}" << this[it] as String
+            }
+        }
+
+        // [-v]
+        // [-protected]
+        // [-keyalg <keyalg>]
+        // [-keysize <keysize>]
+        // [-sigalg <sigalg>]
+        // [-providername <name>]
+        // [-providerclass <provider_class_name> [-providerarg <arg>]] ...
+        // [-providerpath <pathlist>]
+
+
+        aaptExec.args = args
+
+        ExecResult exec = aaptExec.execute()
+        exec.assertNormalExitValue()
+    }
+
+    @OutputFile
+    File keyStore
+
+    String alias
+    String dname
+    Integer validity // conventions don't play nice with primitives
+    String keyPass
+    String storePass
+    String storeType
+}

gradle-javafx-plugin/src/main/groovy/com/bitbucket/shemnon/javafxplugin/tasks/JavaFXCSSToBinTask.groovy

+/*
+ * Copyright (c) 2012, Danno Ferrin
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions are met:
+ *       * Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ *       * Redistributions in binary form must reproduce the above copyright
+ *         notice, this list of conditions and the following disclaimer in the
+ *         documentation and/or other materials provided with the distribution.
+ *       * Neither the name of Danno Ferrin nor the
+ *         names of contributors may be used to endorse or promote products
+ *         derived from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *   DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ *   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.bitbucket.shemnon.javafxplugin.tasks
+
+import com.sun.javafx.tools.packager.CreateBSSParams
+import com.sun.javafx.tools.packager.PackagerLib
+import org.gradle.api.file.FileVisitDetails
+import org.gradle.api.file.FileVisitor
+import org.gradle.api.file.SourceDirectorySet
+import org.gradle.api.internal.ConventionTask
+import org.gradle.api.internal.file.collections.DirectoryFileTree
+import org.gradle.api.tasks.InputFiles
+import org.gradle.api.tasks.OutputDirectory
+import org.gradle.api.tasks.TaskAction
+
+class JavaFXCSSToBinTask extends ConventionTask {
+
+    @TaskAction
+    processResources() {
+
+        CreateBSSParams bssParams = new CreateBSSParams();
+        getInputFiles().srcDirTrees.each { DirectoryFileTree dirTree ->
+            dirTree.visit new FileVisitor() {
+                @Override
+                void visitDir(FileVisitDetails fileVisitDetails) {
+                    // do nothing
+                }
+
+                @Override
+                void visitFile(FileVisitDetails fileVisitDetails) {
+                    File f = fileVisitDetails.getFile();
+                    if (f.getName().endsWith(".css")) {
+                        bssParams.addResource(dirTree.getDir(), f);
+                    }
+                }
+            }
+        }
+        bssParams.setOutdir(getDistsDir())
+
+        PackagerLib packager = new PackagerLib();
+        packager.generateBSS(bssParams)
+    }
+
+    @InputFiles
+    SourceDirectorySet inputFiles
+
+    @OutputDirectory
+    File distsDir
+}

gradle-javafx-plugin/src/main/groovy/com/bitbucket/shemnon/javafxplugin/tasks/JavaFXDeployTask.groovy

+/*
+ * Copyright (c) 2012, Danno Ferrin
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions are met:
+ *       * Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ *       * Redistributions in binary form must reproduce the above copyright
+ *         notice, this list of conditions and the following disclaimer in the
+ *         documentation and/or other materials provided with the distribution.
+ *       * Neither the name of Danno Ferrin nor the
+ *         names of contributors may be used to endorse or promote products
+ *         derived from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *   DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ *   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.bitbucket.shemnon.javafxplugin.tasks
+
+import com.sun.javafx.tools.packager.DeployParams
+import com.sun.javafx.tools.packager.DeployParams.RunMode;
+import com.sun.javafx.tools.packager.PackagerLib
+import com.sun.javafx.tools.packager.bundlers.Bundler;
+import org.gradle.api.tasks.InputFiles
+import org.gradle.api.tasks.TaskAction
+import org.gradle.api.tasks.OutputDirectory
+import org.gradle.api.internal.ConventionTask
+import org.gradle.api.file.FileCollection
+import org.gradle.util.ConfigureUtil
+
+class JavaFXDeployTask extends ConventionTask {
+
+    @TaskAction
+    processResources() {
+        DeployParams deployParams = new DeployParams();
+
+        deployParams.version = getProject().getVersion() // FIXME make a convention property
+
+        // these deploy params are currently not set
+        //java.lang.String preloader;
+        //java.util.List<com.sun.javafx.tools.packager.Param> params;
+        //java.util.List<com.sun.javafx.tools.packager.HtmlParam> htmlParams;
+        //java.util.List<java.lang.String> arguments;
+        //boolean embedCertificates;
+        //boolean isExtension;
+        //boolean isSwingApp;
+        //boolean includeDT;
+        //java.lang.String placeholder;
+        //java.lang.String appId;
+        //java.util.List<com.sun.javafx.tools.ant.Callback> callbacks;
+        //java.util.List<com.sun.javafx.tools.packager.DeployParams.Template> templates;
+        //java.lang.String jrePlatform;
+        //java.lang.String fxPlatform;
+        //java.util.List<java.lang.String> jvmargs;
+        //java.util.Map<java.lang.String,java.lang.String> properties;
+        //java.lang.String fallbackApp;
+        //java.util.List<com.sun.javafx.tools.packager.DeployParams.Icon> icons;
+
+
+        deployParams.width = getWidth()
+        deployParams.height = getHeight()
+        deployParams.setEmbeddedDimensions(getWidth() as String, getHeight() as String) // FIXME make a convention property
+        deployParams.setOutdir(getDistsDir())
+        deployParams.embedJNLP = getEmbedJNLP()
+        deployParams.outfile = getAppName() //FIXME duplicate with app name
+        switch (getPackaging().toLowerCase()) {
+            case "false":
+            case "none":
+                deployParams.bundleType = Bundler.BundleType.NONE
+                deployParams.targetFormat = null
+                break;
+            case "all":
+            case "true":
+                deployParams.bundleType = Bundler.BundleType.ALL
+                deployParams.targetFormat = null
+                break;
+            case "image":
+                deployParams.bundleType = Bundler.BundleType.IMAGE
+                deployParams.targetFormat = null
+                break;
+            case "installer":
+                deployParams.bundleType = Bundler.BundleType.INSTALLER
+                deployParams.targetFormat = null
+                break;
+            default:
+                // assume the packageing is for a specific type
+                deployParams.bundleType = Bundler.BundleType.INSTALLER
+                deployParams.targetFormat = getPackaging()
+
+        }
+        
+        deployParams.verbose = getVerbose()
+
+        deployParams.id = getAppID()
+        deployParams.appName = getAppName() // FIXME duplicate with title
+        deployParams.applicationClass = getMainClass()
+
+        getInputFiles() each { File f ->
+            deployParams.addResource(f.parentFile, f);
+        }
+
+        deployParams.title = getAppName()
+        deployParams.category = getCategory()
+        deployParams.copyright = getCopyright()
+        deployParams.description = getDescription()
+        deployParams.licenseType = getLicenseType()
+        deployParams.vendor = getVendor()
+
+        deployParams.systemWide = getInstallSystemWide()
+        deployParams.needMenu = getMenu()
+        deployParams.needShortcut = getShortcut()
+
+        deployParams.allPermissions = true //FIXME hardcoded
+
+        deployParams.updateMode = getUpdateMode()
+        deployParams.offlineAllowed = getOfflineAllowed()
+        for (IconInfo ii : icons) {
+            deployParams.addIcon(ii.href, ii.kind, ii.width, ii.height, ii.depth, ii.mode);
+        }
+        if (getCodebase() != null) {
+            try {
+                deployParams.codebase = getCodebase()
+            } catch (MissingPropertyException moe) {
+                getLogger().error("JavaFXDeployTask.codebase is only available in JavaFX 8 or later, codebase setting is ignored")
+            }
+        }
+
+        jvmArgs.each { deployParams.addJvmArg(it) }
+        systemProperties.each {k, v -> deployParams.addJvmProperty(k, v)}
+        deployParams.arguments = arguments
+
+        PackagerLib packager = new PackagerLib();
+        packager.generateDeploymentPackages(deployParams)
+    }
+
+    def icon(Closure closure) {
+         icons.add(new IconInfo(closure))
+    }
+
+    String packaging
+
+    FileCollection antJavaFXJar
+
+    String appID
+    String appName
+
+    boolean verbose = false
+
+    String mainClass
+    int width = 1024
+    int height = 768
+    boolean embedJNLP = false
+    String updateMode = "background"
+    boolean offlineAllowed = true
+    String codebase
+
+    List<String> jvmArgs = []
+    Map<String, String> systemProperties = [:]
+    List<String> arguments = []
+
+    // deplpy/info attributes
+    String category
+    String copyright
+    String description
+    String licenseType
+    String vendor
+    List<IconInfo> icons = []
+
+    // deploy/preferences attributes
+    Boolean installSystemWide
+    boolean menu
+    boolean shortcut
+
+    @InputFiles
+    FileCollection inputFiles
+
+
+    @OutputDirectory
+    File distsDir
+}
+
+class IconInfo {
+    String href
+    String kind = 'default'
+    int width = DeployParams.Icon.UNDEFINED
+    int height = DeployParams.Icon.UNDEFINED
+    int depth = DeployParams.Icon.UNDEFINED
+    RunMode mode = RunMode.ALL
+
+
+    public IconInfo(Closure configure) {
+        ConfigureUtil.configure(configure, this)
+    }
+}

gradle-javafx-plugin/src/main/groovy/com/bitbucket/shemnon/javafxplugin/tasks/JavaFXJarTask.groovy

+/*
+ * Copyright (c) 2012, Danno Ferrin
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions are met:
+ *       * Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ *       * Redistributions in binary form must reproduce the above copyright
+ *         notice, this list of conditions and the following disclaimer in the
+ *         documentation and/or other materials provided with the distribution.
+ *       * Neither the name of Danno Ferrin nor the
+ *         names of contributors may be used to endorse or promote products
+ *         derived from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *   DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ *   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.bitbucket.shemnon.javafxplugin.tasks
+
+import com.sun.javafx.tools.packager.CreateJarParams
+import com.sun.javafx.tools.packager.PackagerLib;
+import org.gradle.api.internal.ConventionTask
+import org.gradle.api.tasks.InputFiles
+import org.gradle.api.tasks.OutputDirectory
+import org.gradle.api.tasks.OutputFile
+import org.gradle.api.tasks.TaskAction
+import org.gradle.api.tasks.SourceSetOutput
+import org.gradle.api.file.FileCollection
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dannoferrin
+ * Date: 3/5/11
+ * Time: 7:18 AM
+ */
+public class JavaFXJarTask extends ConventionTask {
+
+    @TaskAction
+    processResources() {
+        CreateJarParams createJarParams = new CreateJarParams();
+
+        // hardcodes, fix later
+        createJarParams.embedLauncher = true
+        createJarParams.css2bin = false
+
+        createJarParams.addResource(getInputFiles().getClassesDir(), getInputFiles().getClassesDir())
+        createJarParams.addResource(getInputFiles().getResourcesDir(), getInputFiles().getResourcesDir())
+        //TODO process dirs
+
+        createJarParams.applicationClass = getMainClass()
+        createJarParams.outfile = getOutputFile()
+        createJarParams.outdir = getOutputDirectory()
+
+        createJarParams.classpath = getClasspath().files.collect {it.name}.join ' '
+
+        // not provided, fix later
+        //createJarParams.arguments
+        //createJarParams.manifestAttrs
+        //createJarParams.fxVersion
+        //createJarParams.fallback
+        //createJarParams.preloader
+
+        PackagerLib packager = new PackagerLib();
+        packager.packageAsJar(createJarParams)
+
+    }
+
+    String mainClass
+
+    @OutputFile
+    File outputFile
+
+    @OutputDirectory
+    File outputDirectory
+
+    @InputFiles
+    FileCollection classpath
+
+    @InputFiles
+    SourceSetOutput inputFiles
+}

gradle-javafx-plugin/src/main/groovy/com/bitbucket/shemnon/javafxplugin/tasks/JavaFXSignJarTask.groovy

+/*
+ * Copyright (c) 2012, Danno Ferrin
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions are met:
+ *       * Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ *       * Redistributions in binary form must reproduce the above copyright
+ *         notice, this list of conditions and the following disclaimer in the
+ *         documentation and/or other materials provided with the distribution.
+ *       * Neither the name of Danno Ferrin nor the
+ *         names of contributors may be used to endorse or promote products
+ *         derived from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *   DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ *   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.bitbucket.shemnon.javafxplugin.tasks
+
+import com.sun.javafx.tools.packager.PackagerLib
+import com.sun.javafx.tools.packager.SignJarParams;
+import org.gradle.api.file.FileCollection
+import org.gradle.api.internal.ConventionTask
+import org.gradle.api.tasks.InputFiles
+import org.gradle.api.tasks.TaskAction
+import org.gradle.api.tasks.OutputDirectory
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dannoferrin
+ * Date: 3/5/11
+ * Time: 7:18 AM
+ */
+public class JavaFXSignJarTask extends ConventionTask {
+
+    @TaskAction
+    processResources() {
+
+        SignJarParams signJarParams = new SignJarParams();
+
+        getInputFiles() filter { File f -> f.file && f.name.endsWith(".jar") } each { File f ->
+            signJarParams.addResource(f.parentFile, f);
+        }
+
+        ['alias', 'keyPass', 'keyStore', 'storePass', 'storeType', 'verbose', 'outdir', 'verbose'].each {
+            if (this[it]) {
+                signJarParams[it] = this[it]
+            }
+        }
+
+        PackagerLib packager = new PackagerLib();
+        packager.signJar(signJarParams)
+    }
+
+    String alias
+    String keyPass
+    File keyStore
+    String storePass
+    String storeType
+    String verbose = "true" // FIXME hard coded
+
+    @OutputDirectory
+    File outdir
+
+    @InputFiles
+    FileCollection inputFiles
+
+}

gradle-javafx-plugin/src/main/resources/META-INF/gradle-plugins/javafx.properties

+implementation-class=com.bitbucket.shemnon.javafxplugin.JavaFXPlugin

plugin/build.gradle

-apply plugin: 'groovy'
-apply plugin: 'maven'
-
-group = 'com.bitbucket.shemnon.javafxplugin'
-version = '0.2.0-SNAPSHOT'
-
-repositories {
-    mavenCentral()
-}
-
-dependencies {
-    groovy 'org.codehaus.groovy:groovy-all:2.0.5'
-    compile gradleApi()
-    compile files("${System.properties['java.home']}/../lib/ant-javafx.jar")
-    compile files("${System.properties['java.home']}/lib/jfxrt.jar")
-}
-
-uploadArchives {
-    repositories {
-        mavenDeployer {
-            repository(url:"https://api.bintray.com/maven/shemnon/javafx-gradle/plugin/",
-                id: 'bintray-shemnon-javafx-gradle-plugin'
-            ) {
-                try {
-                    authentication(
-                        userName: bintrayUserName,
-                        password: bintrayApiKey
-                    )
-                } catch (MissingPropertyException pne) {
-                    // ignore, don't authenticate
-                }
-            }
-            snapshotRepository (url: "https://repository-javafx-gradle-plugin.forge.cloudbees.com/snapshot/",
-                id: 'cloudbees-javafx-gradle-plugin'
-            ) {
-                try {
-                    authentication(
-                        userName: cloudbeesUserName,
-                        password: cloudbeesPassword
-                    )
-                } catch (MissingPropertyException pne) {
-                    // ignore, don't authenticate
-                }
-            }
-        }
-    }
-}
-
-[install.repositories.mavenInstaller, uploadArchives.repositories.mavenDeployer]*.pom*.whenConfigured {pom ->
-    pom.project {
-        dependencies {
-            dependency {
-                groupId 'net.java.openjdk'
-                artifactId 'jfxrt'
-                version '8b72'
-                scope 'system'
-                systemPath '${java.home}/lib/jfxrt.jar'
-            }
-            dependency {
-                groupId 'net.java.openjdk'
-                artifactId 'ant-javafx'
-                version '8b72'
-                scope 'system'
-                systemPath '${java.home}/../lib/ant-javafx.jar'
-            }
-        }
-    }
-}
-
-

plugin/src/main/groovy/com/bitbucket/shemnon/javafxplugin/JavaFXPlugin.groovy

-/*
- * Copyright (c) 2012, Danno Ferrin
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions are met:
- *       * Redistributions of source code must retain the above copyright
- *         notice, this list of conditions and the following disclaimer.
- *       * Redistributions in binary form must reproduce the above copyright
- *         notice, this list of conditions and the following disclaimer in the
- *         documentation and/or other materials provided with the distribution.
- *       * Neither the name of Danno Ferrin nor the
- *         names of contributors may be used to endorse or promote products
- *         derived from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *   DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- *   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package com.bitbucket.shemnon.javafxplugin
-
-import org.gradle.api.Project
-import org.gradle.api.Plugin
-import com.bitbucket.shemnon.javafxplugin.tasks.JavaFXDeployTask
-import com.bitbucket.shemnon.javafxplugin.tasks.JavaFXJarTask
-import org.gradle.api.plugins.JavaPluginConvention
-import org.gradle.api.file.FileCollection
-import org.gradle.api.tasks.SourceSet
-import org.gradle.api.tasks.JavaExec
-import org.gradle.api.artifacts.ConfigurationContainer
-import org.gradle.api.artifacts.Configuration
-import org.gradle.api.plugins.JavaPlugin
-import com.bitbucket.shemnon.javafxplugin.tasks.JavaFXCSSToBinTask
-import com.bitbucket.shemnon.javafxplugin.tasks.JavaFXSignJarTask
-import com.bitbucket.shemnon.javafxplugin.tasks.GenKeyTask
-import org.gradle.api.DefaultTask
-import org.gradle.api.artifacts.ResolvedArtifact
-
-
-class JavaFXPlugin implements Plugin<Project> {
-
-    public static final String PROVIDED_COMPILE_CONFIGURATION_NAME = "providedCompile";
-    public static final String PROVIDED_RUNTIME_CONFIGURATION_NAME = "providedRuntime";
-
-    @Override
-    void apply(Project project) {
-        project.getPlugins().apply(JavaPlugin)
-        project.extensions.create('javafx', JavaFXPluginExtension)
-
-        configureConfigurations(project.configurations)
-
-        def jfxrtJarFile = project.files(findJFXJar())
-        project.javafx {
-            jfxrtJar = jfxrtJarFile
-            antJavaFXJar = project.files(findAntJavaFXJar())
-            mainClass = "${project.group}${(project.group&&project.name)?'.':''}${project.name}${(project.group||project.name)?'.':''}Main"
-            appName = project.name //FIXME capatalize
-            packaging = 'all'
-            debugKey {
-                alias = 'javafxdebugkey'
-                keyPass = 'JavaFX'
-                keyStore = new File(project.projectDir, 'debug.keyStore')
-                storePass = 'JavaFX'
-            }
-            signingMode = 'debug'
-        }
-
-
-        project.dependencies {
-            providedCompile jfxrtJarFile
-        }
-        project.sourceSets {
-            'package' {
-                resources {
-                    srcDir 'src/main'
-                }
-            }
-        }
-
-        configureJavaFXCSSToBinTask(project)
-        configureJavaFXJarTask(project)
-        configureGenerateDebugKeyTask(project)
-        configureJavaFXSignJarTask(project)
-        configureJFXDeployTask(project)
-        configureScenicViewTask(project)
-        configureRunTask(project)
-        configureDebugTask(project)
-    }
-
-
-    private configureJavaFXCSSToBinTask(Project project) {
-        def task = project.task("cssToBin", type: JavaFXCSSToBinTask,
-                description: "Converts CSS to Binary CSS.",
-                group: 'Build')
-
-        task.conventionMapping.distsDir = {convention, aware -> convention.getPlugin(JavaPluginConvention).sourceSets.main.output.resourcesDir}
-
-        task.conventionMapping.inputFiles = {convention, aware ->
-            convention.getPlugin(JavaPluginConvention).sourceSets.main.resources
-        }
-
-        project.tasks.getByName("classes").dependsOn(task)
-        task.dependsOn(project.tasks.getByName("processResources"))
-    }
-
-    private configureJavaFXJarTask(Project project) {
-        def task = project.task("jfxJar", type: JavaFXJarTask,
-                description: "Jars up the classes and adds JavaFX specific packaging.",
-                group: 'Build')
-
-        task.conventionMapping.mainClass = {convention, aware -> project.javafx.mainClass }
-
-        task.conventionMapping.outputDirectory = {convention, aware ->
-            "$project.libsDir" as File}
-        task.conventionMapping.outputFile = {convention, aware ->
-            "${project.archivesBaseName}.jar" as File}
-
-        task.conventionMapping.inputFiles = {convention, aware -> convention.getPlugin(JavaPluginConvention).sourceSets.main.output}
-        task.conventionMapping.classpath = {convention, aware ->
-            FileCollection compileClasspath = project.convention.getPlugin(JavaPluginConvention).sourceSets[SourceSet.MAIN_SOURCE_SET_NAME].compileClasspath;
-            Configuration providedCompile = project.configurations[PROVIDED_COMPILE_CONFIGURATION_NAME];
-            FileCollection output = compileClasspath - providedCompile;
-        }
-    }
-
-    private configureGenerateDebugKeyTask(Project project) {
-        def task = project.task("generateDebugKey", type: GenKeyTask,
-                description: "Generates the JAvaFX Debug Key.",
-                group: 'Build')
-
-        task.conventionMapping.alias     = {convention, aware -> project.javafx.debugKey.alias }
-        task.conventionMapping.keyPass   = {convention, aware -> project.javafx.debugKey.keyPass }
-        task.conventionMapping.keyStore  = {convention, aware -> project.javafx.debugKey.keyStore }
-        task.conventionMapping.storePass = {convention, aware -> project.javafx.debugKey.storePass }
-        task.conventionMapping.storeType = {convention, aware -> project.javafx.debugKey.storeType }
-        task.conventionMapping.dname     = {convention, aware -> 'CN=JavaFX Gradle Plugin Default Debug Key, O=JavaFX Debug' }
-        task.conventionMapping.validity  = {convention, aware -> ((365.25) * 25 as int) /* 25 years */ }
-    }
-
-    private configureJavaFXSignJarTask(Project project) {
-        def task = project.task("jfxSignJar", type: JavaFXSignJarTask,
-                description: "Signs the JavaFX jars the JavaFX way.",
-                group: 'Build')
-
-        ['alias', 'keyPass', 'storePass', 'storeType'].each { prop ->
-            task.conventionMapping[prop]  = {convention, aware ->
-                def jfxc = project.javafx;
-                def props = project.properties
-                def mode = props['javafx.signingMode']  ?: jfxc.signingMode
-                return props?."javafx.${mode}Key.$prop" ?: jfxc?."${mode}Key"?."$prop"
-            }
-        }
-        task.conventionMapping.keyStore  = {convention, aware ->
-            def jfxc = project.javafx;
-            def props = project.properties
-            def mode = props['javafx.signingMode']  ?: jfxc.signingMode
-            String keyFile = props?."javafx.${mode}Key.keyStore"
-            return keyFile == null ? jfxc?."${mode}Key"?.keyStore : new File(keyFile)
-        }
-
-        task.conventionMapping.outdir = {convention, aware -> "$project.libsDir/../signed" as File}
-
-        task.conventionMapping.inputFiles = {convention, aware ->
-            FileCollection runtimeClasspath = project.convention.getPlugin(JavaPluginConvention).sourceSets[SourceSet.MAIN_SOURCE_SET_NAME].runtimeClasspath;
-            Configuration providedRuntime = project.configurations[PROVIDED_RUNTIME_CONFIGURATION_NAME];
-            runtimeClasspath  + project.files("$project.libsDir/${project.archivesBaseName}.jar" as File)- providedRuntime
-        }
-
-        task.dependsOn(project.tasks.getByName("jfxJar"))
-        task.dependsOn(project.tasks.getByName("generateDebugKey"))
-    }
-
-    private configureJFXDeployTask(Project project) {
-        def task = project.task("jfxDeploy", type: JavaFXDeployTask,
-                description: "Processes the JavaFX jars and generates webstart and native packages.",
-                group: 'Build')
-
-        task.conventionMapping.packaging = {convention, aware -> project.javafx.packaging }
-
-        task.conventionMapping.antJavaFXJar = {convention, aware ->
-            project.javafx.antJavaFXJar }
-
-        task.conventionMapping.appID = {convention, aware -> project.javafx.appID }
-        task.conventionMapping.appName = {convention, aware -> project.javafx.appName }
-        task.conventionMapping.mainClass = {convention, aware -> project.javafx.mainClass }
-
-
-        task.conventionMapping.inputFiles = {convention, aware ->
-            project.fileTree("$project.libsDir/../signed").include("*.jar")
-        }
-
-        task.conventionMapping.distsDir = {convention, aware -> project.distsDir }
-
-        task.conventionMapping.jvmArgs = {convention, aware -> project.javafx.jvmArgs }
-        task.conventionMapping.systemProperties = {convention, aware -> project.javafx.systemProperties }
-        task.conventionMapping.arguments = {convention, aware -> project.javafx.arguments}
-
-        task.dependsOn(project.tasks.getByName("jfxSignJar"))
-        project.tasks.getByName("assemble").dependsOn(task)
-        project.tasks.getByName("jar").enabled = false
-    }
-    
-    private void configureRunTask(Project project) {
-        JavaExec task = project.task("run", type: JavaExec,
-            description: 'Runs the application.',
-            group: 'Execution')
-
-        task.classpath = project.sourceSets.main.runtimeClasspath
-        task.conventionMapping.main = {convention, aware -> project.javafx.mainClass }
-        task.doFirst {
-            task.jvmArgs project.javafx.jvmArgs
-            task.systemProperties project.javafx.systemProperties
-            if (!task.args) task.args = project.javafx.arguments
-        }
-    }
-
-    private void configureDebugTask(Project project) {
-        JavaExec task = project.task("debug", type:JavaExec,
-            description: 'Runs the applicaiton and sets up debugging on port 5005.',
-            group: 'Execution')
-
-        task.classpath = project.sourceSets.main.runtimeClasspath
-        task.conventionMapping.main = {convention, aware -> project.javafx.mainClass }
-        task.doFirst {
-            task.jvmArgs project.javafx.jvmArgs
-            task.systemProperties project.javafx.systemProperties
-            if (!task.args) task.args = project.javafx.arguments
-        }
-        task.debug = true
-    }
-
-    private void configureScenicViewTask(Project project) {
-        def task = project.task("scenicview", type: DefaultTask,
-                description: 'Adds the ScenicView agent to all Execution Tasks.',
-                group: 'Tools')
-
-        task.doLast {
-            project.configurations {
-                scenicview
-            }
-            project.repositories {
-                ivy  { url 'https://repository-javafx-gradle-plugin.forge.cloudbees.com/release' }
-            }
-            project.dependencies {
-                scenicview 'com.fxexperience.scenicview:scenicview:1.3.0'
-            }
-
-            project.tasks.findAll {it.group == 'Execution' && it instanceof JavaExec}.each {JavaExec execTask ->
-                project.configurations.getByName('scenicview').resolvedConfiguration.resolvedArtifacts.each { ResolvedArtifact ra ->
-                    execTask.jvmArgs = ["-javaagent:$ra.file.canonicalPath"] + execTask.jvmArgs
-                }
-            }
-        }
-    }
-
-    public void configureConfigurations(ConfigurationContainer configurationContainer) {
-        Configuration provideCompileConfiguration = configurationContainer.add(PROVIDED_COMPILE_CONFIGURATION_NAME).setVisible(false).
-                setDescription("Additional compile classpath for libraries that should not be part of the WAR archive.");
-        Configuration provideRuntimeConfiguration = configurationContainer.add(PROVIDED_RUNTIME_CONFIGURATION_NAME).setVisible(false).
-                extendsFrom(provideCompileConfiguration).
-                setDescription("Additional runtime classpath for libraries that should not be part of the WAR archive.");
-        configurationContainer.getByName(JavaPlugin.COMPILE_CONFIGURATION_NAME).extendsFrom(provideCompileConfiguration);
-        configurationContainer.getByName(JavaPlugin.RUNTIME_CONFIGURATION_NAME).extendsFrom(provideRuntimeConfiguration);
-    }
-
-    public File findJFXJar() {
-        def javafxHome = System.env['JFXRT_HOME']
-        File jfxrtHome
-        if (javafxHome) {
-            jfxrtHome = "${javafxHome}" as File
-        } else {
-            final javaHome = System.env['JAVA_HOME']
-            if (javaHome)
-                jfxrtHome = "${javaHome}/jre/lib"  as File
-            else
-                jfxrtHome = "${System.properties['java.home']}/lib" as File
-        }
-
-        File jfxrtJar = new File((File) jfxrtHome, "jfxrt.jar")
-        if (!jfxrtJar.exists()) {
-            println ("""    Please set the environment variable JFXRT_HOME
-    to the directory that contains jfxrt.jar, or set JAVA_HOME.""")
-
-        }
-        println "JavaFX runtime jar: ${jfxrtJar}"
-        return jfxrtJar
-    }
-
-    public File findAntJavaFXJar() {
-        def javafxHome = System.env['JFXRT_HOME']
-        File jfxrtHome
-        if (javafxHome) {
-            jfxrtHome = "${javafxHome}" as File
-        } else {
-            final javaHome = System.env['JAVA_HOME']
-            if (javaHome)
-                jfxrtHome = "${javaHome}/lib"  as File
-            else
-                jfxrtHome = "${System.properties['java.home']}/../lib" as File
-        }
-
-        File antjfxjar = new File((File)jfxrtHome, "ant-javafx.jar")
-        if (!antjfxjar.exists()) {
-            println("""    Please set the environment variable JFXRT_HOME
-    to the directory that contains jfxrt.jar, or set JAVA_HOME.""")
-
-        }
-        println "JavaFX ant jar: ${antjfxjar}"
-        return antjfxjar
-    }
-}

plugin/src/main/groovy/com/bitbucket/shemnon/javafxplugin/JavaFXPluginExtension.groovy

-/*
- * Copyright (c) 2012, Danno Ferrin
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions are met:
- *       * Redistributions of source code must retain the above copyright
- *         notice, this list of conditions and the following disclaimer.
- *       * Redistributions in binary form must reproduce the above copyright
- *         notice, this list of conditions and the following disclaimer in the
- *         documentation and/or other materials provided with the distribution.
- *       * Neither the name of Danno Ferrin nor the
- *         names of contributors may be used to endorse or promote products
- *         derived from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *   DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- *   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package com.bitbucket.shemnon.javafxplugin
-
-import org.gradle.util.ConfigureUtil
-import org.gradle.api.file.FileCollection
-import org.gradle.api.plugins.BasePluginConvention
-import org.gradle.api.Project
-
-class JavaFXPluginExtension { //extends BasePluginConvention {
-
-    // preliminaries
-    FileCollection jfxrtJar
-    FileCollection antJavaFXJar
-
-    // build steps
-    SigningKeyInfo debugKey
-    SigningKeyInfo releaseKey
-
-    String signingMode
-
-    // app info
-    String appID
-    String appName
-    String mainClass
-
-    String packaging
-
-    List<String> jvmArgs = []
-    Map<String, String> systemProperties = [:]
-    List<String> arguments = []
-
-    public debugKey(Closure closure) {
-        debugKey = new SigningKeyInfo(closure)
-    }
-
-    public releaseKey(Closure closure) {
-        releaseKey = new SigningKeyInfo(closure)
-    }
-
-
-}
-
-class SigningKeyInfo {
-    String alias
-    String keyPass
-    File keyStore
-    String storePass
-    String storeType
-
-
-    public SigningKeyInfo(Closure configure) {
-        ConfigureUtil.configure(configure, this)
-    }
-
-    //TODO logic methods
-    //   - determine if a key exists
-    //   - load stuff like validity and dname from existing key
-    //   - prompt for password if set to null on a read
-}

plugin/src/main/groovy/com/bitbucket/shemnon/javafxplugin/tasks/GenKeyTask.groovy

-/*
- * Copyright (c) 2011-2012, Danno Ferrin
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions are met:
- *       * Redistributions of source code must retain the above copyright
- *         notice, this list of conditions and the following disclaimer.
- *       * Redistributions in binary form must reproduce the above copyright
- *         notice, this list of conditions and the following disclaimer in the
- *         documentation and/or other materials provided with the distribution.
- *       * Neither the name of Danno Ferrin nor the
- *         names of contributors may be used to endorse or promote products
- *         derived from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *   DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- *   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package com.bitbucket.shemnon.javafxplugin.tasks;
-
-import org.gradle.api.internal.ConventionTask
-import org.gradle.api.tasks.OutputFile
-import org.gradle.api.tasks.TaskAction
-import org.gradle.process.ExecResult
-import org.gradle.process.internal.DefaultExecAction
-import org.gradle.process.internal.ExecAction
-
-/**
- * Created by IntelliJ IDEA.
- * User: dannoferrin
- * Date: 3/8/11
- * Time: 9:07 PM
- */
-class GenKeyTask extends ConventionTask {
-
-    @TaskAction
-    processResources() {
-        if (getKeyStore().exists()) return
-
-        ExecAction aaptExec = new DefaultExecAction()
-        aaptExec.workingDir = project.projectDir
-        aaptExec.executable = "${System.properties['java.home']}/bin/keytool"
-
-        def args = []
-        args << '-genkeypair'
-        ['alias', 'dname', 'validity', 'keyPass', 'keyStore', 'storePass', 'storeType'].each {
-            if (this[it]) {
-                args << "-${it.toLowerCase()}" << this[it] as String
-            }
-        }
-
-        // [-v]
-        // [-protected]
-        // [-keyalg <keyalg>]
-        // [-keysize <keysize>]
-        // [-sigalg <sigalg>]
-        // [-providername <name>]
-        // [-providerclass <provider_class_name> [-providerarg <arg>]] ...
-        // [-providerpath <pathlist>]
-
-
-        aaptExec.args = args
-
-        ExecResult exec = aaptExec.execute()
-        exec.assertNormalExitValue()
-    }
-
-    @OutputFile
-    File keyStore
-
-    String alias
-    String dname
-    Integer validity // conventions don't play nice with primitives
-    String keyPass
-    String storePass
-    String storeType
-}

plugin/src/main/groovy/com/bitbucket/shemnon/javafxplugin/tasks/JavaFXCSSToBinTask.groovy

-/*
- * Copyright (c) 2012, Danno Ferrin
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions are met:
- *       * Redistributions of source code must retain the above copyright
- *         notice, this list of conditions and the following disclaimer.
- *       * Redistributions in binary form must reproduce the above copyright
- *         notice, this list of conditions and the following disclaimer in the
- *         documentation and/or other materials provided with the distribution.
- *       * Neither the name of Danno Ferrin nor the
- *         names of contributors may be used to endorse or promote products
- *         derived from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- *   DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- *   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package com.bitbucket.shemnon.javafxplugin.tasks
-
-import com.sun.javafx.tools.packager.CreateBSSParams
-import com.sun.javafx.tools.packager.PackagerLib
-import org.gradle.api.file.FileVisitDetails
-import org.gradle.api.file.FileVisitor
-import org.gradle.api.file.SourceDirectorySet
-import org.gradle.api.internal.ConventionTask
-import org.gradle.api.internal.file.collections.DirectoryFileTree
-import org.gradle.api.tasks.InputFiles
-import org.gradle.api.tasks.OutputDirectory
-import org.gradle.api.tasks.TaskAction
-
-class JavaFXCSSToBinTask extends ConventionTask {
-
-    @TaskAction
-    processResources() {
-
-        CreateBSSParams bssParams = new CreateBSSParams();
-        getInputFiles().srcDirTrees.each { DirectoryFileTree dirTree ->
-            dirTree.visit new FileVisitor() {