Last active
July 20, 2017 11:54
-
-
Save DrPlantabyte/3d1fc5341d6fc976c8fa88eba7580d06 to your computer and use it in GitHub Desktop.
This is my default build.gradle file, which has a createProject task that makes all of the folders so you don't have to guess the convention and even intializes it with a blank JavaFX app
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// buildscript blocks MUST go before plugins | |
buildscript { | |
dependencies { | |
classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: '8.8.2' | |
} | |
repositories { | |
mavenLocal() | |
mavenCentral() | |
} | |
} | |
// java plugins | |
plugins { | |
id 'org.unbroken-dome.test-sets' version '1.3.2' | |
} | |
apply plugin: 'java' | |
apply plugin: 'application' | |
apply plugin: 'javafx-gradle-plugin' | |
def jvmVersion = '1.8' | |
targetCompatibility = jvmVersion | |
sourceCompatibility = jvmVersion | |
///// Project settings ///// | |
// - change before running the createProject task | |
mainClassName = 'cch.appname.App' | |
archivesBaseName = 'App Name' | |
def resourceName = 'app' // simple name used for resources such as icons and executable names | |
def versionFileName = 'version.properties' | |
def authorVendor = 'CCHall' | |
//////////////////////////// | |
// customizing build folder | |
def sourceDir = 'src' | |
def resourceDir = 'resources' | |
def testDir = 'unit-test' | |
def integrationTestDir = 'integration-test' | |
def testResources = "${testDir}-${resourceDir}" | |
def integrationTestResources = "${integrationTestDir}-${resourceDir}" | |
def importDir = 'lib' | |
def buildDirName = 'build' | |
def nativeInstallerResources = 'deploy-resources' | |
buildDir = buildDirName // buildDir is a file, not a string, unlike the other properties | |
libsDirName = 'jar' | |
distsDirName = 'distributions' | |
docsDirName = 'code-doc' | |
testResultsDirName = 'test-results' | |
testReportDirName = 'tests' | |
def runDir = 'run' | |
// add integration testing with the testsets plugin | |
testSets { | |
integrationTest { dirName = integrationTestDir } | |
} | |
project.integrationTest { | |
outputs.upToDateWhen { false } | |
} | |
tasks.withType(Test) { | |
// fixes issue where integration results overwrite unit test results | |
reports.html.destination = file("${reporting.baseDir}/${name}") | |
} | |
integrationTest.mustRunAfter test | |
//check.dependsOn integrationTest // optional: make build require successful integration test | |
// source folders | |
sourceSets { | |
main { | |
java { | |
srcDirs = [sourceDir] | |
} | |
resources { | |
srcDirs = [resourceDir] | |
} | |
} | |
test { | |
java { | |
srcDirs = [testDir] | |
} | |
resources { | |
srcDirs = [testResources] | |
} | |
} | |
integrationTest { | |
java { | |
srcDirs = [integrationTestDir] | |
} | |
resources { | |
srcDirs = [integrationTestResources] | |
} | |
} | |
} | |
// In this section you declare where to find the dependencies of your project | |
repositories { | |
flatDir { | |
dirs importDir // add libraries folder to build path | |
} | |
jcenter() // repo for 'standard' java tools like JUnit | |
// mavenCentral() // repo with lots of goodies and LGPL/MIT/Apache open source libraries | |
} | |
dependencies { | |
testCompile "junit:junit:+" // latest JUnit verion (whatever that might be) | |
//compile name: 'xxx' // import xxx.jar from the libraries folder | |
//compile "zzz.xyz:libname:version" // import artifactId "libname" in groupId "zzz.xyz" from Maven repository | |
//integrationTestCompile "zzz.xyz:libname:version" // add specific dependency for integration tests | |
} | |
// version file stuff | |
def majorVersionKey = 'version.major' | |
def minorVersionKey = 'version.minor' | |
def buildVersionKey = 'version.build' | |
def namespaceDirPath = folderName(classPathToFilePath(mainClassName)) | |
def namespace = namespaceDirPath.toString().replace('/','.').replace('\\','.') | |
def versionFilepath = "${resourceDir}/${namespaceDirPath}/${versionFileName}" | |
// customized behavior | |
compileJava.doFirst( { | |
incrementPropertyNumber("${projectDir}/${versionFilepath}", buildVersionKey) | |
version = readVersionNumber("${projectDir}/${versionFilepath}",majorVersionKey,minorVersionKey,buildVersionKey) | |
}) | |
jfxNative.doFirst{ | |
jfx.nativeReleaseVersion = readVersionNumber("${projectDir}/${versionFilepath}",majorVersionKey,minorVersionKey,buildVersionKey) | |
} | |
run.doFirst{ | |
workingDir = new File("${projectDir}/${runDir}") | |
if( ! workingDir.exists()){ | |
workingDir.mkdirs() | |
} | |
} | |
clean.doLast{ | |
workingDir = new File("${projectDir}/${runDir}") | |
if( workingDir.exists() ) { | |
ant.delete(includeEmptyDirs: 'true') { | |
fileset(dir: file("${projectDir}/${runDir}"), includes: '*/**') | |
fileset(dir: file("${projectDir}/${runDir}"), includes: '*') | |
} | |
} | |
} | |
///// JavaFX native installer configuration ///// | |
// See https://github.com/FibreFoX/javafx-gradle-plugin for JavaFX plugin configuration options | |
jfx { | |
// minimal requirements for jfxJar-task | |
mainClass = mainClassName | |
vendor = authorVendor | |
// Extended options | |
verbose = true | |
jfxAppOutputDir = "${buildDirName}/jfx/app".toString() | |
jfxMainAppJarName = "${archivesBaseName}.jar".toString() | |
deployDir = nativeInstallerResources // defaults to src/main/deploy | |
useEnvironmentRelativeExecutables = true | |
libFolderName = "lib" | |
// gradle jfxJar | |
css2bin = false | |
preLoader = null // String | |
updateExistingJar = false | |
allPermissions = false | |
manifestAttributes = null // Map<String, String> | |
addPackagerJar = true | |
copyAdditionalAppResourcesToJar = false | |
skipCopyingDependencies = false | |
useLibFolderContentForManifestClasspath = false | |
fixedManifestClasspath = null | |
// gradle jfxNative | |
identifier = null // String - setting this for windows-bundlers makes it possible to generate upgradeable installers (using same GUID) | |
nativeOutputDir = "${buildDirName}/jfx/native-deploy".toString() | |
bundler = "ALL" // set this to some specific, if your don't want all bundlers running, examples "windows.app", "jnlp", ... | |
jvmProperties = null // Map<String, String> | |
jvmArgs = null // List<String> | |
userJvmArgs = null // Map<String, String> | |
launcherArguments = null // List<String> | |
//nativeReleaseVersion = "$project.version".toString() | |
needShortcut = false | |
needMenu = false | |
//bundleArguments = [ | |
// optional parameters to pass to the bundler (usually OS-specific) | |
// see https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/self-contained-packaging.html#A1308687 | |
//] | |
appName = resourceName // this is used for files below "${nativeOutputDir}", e.g. "src/main/deploy/windows/project.ico" | |
additionalBundlerResources = null // path to some additional resources for the bundlers when creating application-bundle | |
additionalAppResources = null // path to some additional resources when creating application-bundle | |
//secondaryLaunchers = [ [appName:"run-${resourceName}".toString()] ] // alternative app names, there can be many (and you can give them different icons) | |
fileAssociations = null // List<Map<String, Object>> | |
noBlobSigning = false // when using bundler "jnlp", you can choose to NOT use blob signing | |
customBundlers = null // List<String> | |
failOnError = false | |
onlyCustomBundlers = false | |
skipJNLP = false | |
skipNativeVersionNumberSanitizing = false // anything than numbers or dots are removed | |
additionalJarsignerParameters = null // List<String> | |
skipMainClassScanning = false // set to true might increase build-speed | |
skipNativeLauncherWorkaround124 = false | |
skipNativeLauncherWorkaround167 = false | |
skipNativeLauncherWorkaround205 = false | |
skipJNLPRessourcePathWorkaround182 = false | |
skipSigningJarFilesJNLP185 = false | |
skipSizeRecalculationForJNLP185 = false | |
skipMacBundlerWorkaround = false | |
// gradle jfxRun | |
runJavaParameter = null // String | |
runAppParameter = null // String | |
// per default the outcome of the gradle "jarTask" will be used, set this to specify otherwise (like proguard-output) | |
alternativePathToJarFile = null // String | |
// to disable patching of ant-javafx.jar, set this to false | |
usePatchedJFXAntLib = true | |
// making it able to support absolute paths, defaults to "false" for maintaining old behaviour | |
checkForAbsolutePaths = false | |
// gradle jfxGenerateKeyStore | |
keyStore = "${nativeOutputDir}/keystore.jks".toString() | |
keyStoreAlias = "${resourceName}".toString() | |
keyStorePassword = "spirogyra".toString() | |
keyPassword = null // will default to keyStorePassword | |
keyStoreType = "jks" | |
overwriteKeyStore = false | |
certDomain = null // required | |
certOrgUnit = null // defaults to "none" | |
certOrg = null // required | |
certState = null // required | |
certCountry = null // required | |
} | |
///// utility functions and tasks ///// | |
// Task to create project directory structure. | |
task createProject { | |
doLast { | |
def projectName = project.name | |
def mainClassFilePath = classPathToFilePath(mainClassName) | |
def mainClassFile = "${sourceDir}/${mainClassFilePath}.java" | |
def mainClassITFile = "${integrationTestDir}/${mainClassFilePath}IT.java" | |
println "Creating directory structure for ${projectName}" | |
makeFolder("${projectDir}/${sourceDir}") | |
makeFolder("${projectDir}/${resourceDir}") | |
makeFolder("${projectDir}/${testDir}") | |
makeFolder("${projectDir}/${testResources}") | |
makeFolder("${projectDir}/${integrationTestDir}") | |
makeFolder("${projectDir}/${integrationTestResources}") | |
makeFolder("${projectDir}/${importDir}") | |
makeFolder("${projectDir}/${nativeInstallerResources}/package") | |
makeFolder("${projectDir}/${nativeInstallerResources}/package/windows") | |
makeFolder("${projectDir}/${nativeInstallerResources}/package/macosx") | |
makeFolder("${projectDir}/${nativeInstallerResources}/package/linux") | |
makeFolder(buildDir) // is a file, not a string | |
makeFolder("${projectDir}/${runDir}") | |
makeFolder( folderName("${projectDir}/${mainClassFile}") ) | |
makeFolder( folderName("${projectDir}/${mainClassITFile}") ) | |
makeFolder( folderName("${projectDir}/${versionFilepath}") ) | |
println "Version properties file for ${projectName}: ${versionFilepath}" | |
def copyrightYear = java.time.ZonedDateTime.now().getYear() | |
writeToFile(versionFilepath, ["${majorVersionKey}=0", "${minorVersionKey}=0", "${buildVersionKey}=0", "authors=No names given", "title=${archivesBaseName}", "copyright=Copyright ${copyrightYear}", "license.redistribution=All rights reserved. You may not redistribute this software or any of its components or derivatives without written permission from the authors of this software."]) | |
if ( ! file("${projectDir}/${mainClassFile}").exists() ){ | |
println "Creating basic java files" | |
def mainViewFile = "${resourceDir}/${namespaceDirPath}/MainView.fxml" | |
def mainViewController = "${sourceDir}/${namespaceDirPath}/MainViewController.java" | |
def className = fileName(mainClassFile).toString().replace('.java','') | |
def languageFileBaseName = 'Language' | |
def languageBaseFile = "${resourceDir}/${namespaceDirPath}/${languageFileBaseName}" | |
writeToFile("${projectDir}/${mainClassFile}", ["package ${namespace};", "import java.io.IOException;", "import java.nio.file.Paths;", "import java.util.Locale;", "import java.util.Properties;", "import java.util.ResourceBundle;", "import java.util.concurrent.atomic.AtomicReference;", "import java.util.logging.Level;", "import java.util.logging.Logger;", "import javafx.application.Application;", "import javafx.fxml.FXMLLoader;", "import javafx.scene.Parent;", "import javafx.scene.Scene;", "import javafx.stage.Stage;", "public class ${className} extends Application{", " private static ${className} instance = null;", " private Stage rootStage = null;", " private final Properties properties = new Properties();", " @Override", " public void start(Stage primaryStage) throws Exception {", " rootStage = primaryStage;", " ", " rootStage.setTitle(properties.getProperty(\"title\", \"<TITLE NOT FOUND>\"));", " //rootStage.getIcons().add( new javafx.scene.image.Image( ${className}.class.getResourceAsStream( \"icon.png\" )));", " AtomicReference<Object> rootController = new AtomicReference<>();", " AtomicReference<Parent> rootPane = new AtomicReference<>();", " loadFXML(\"MainView.fxml\",rootController, rootPane);", " switchToScreen(rootPane.get());", " }", " private void loadFXML(String fxmlPath, AtomicReference<Object> controller, AtomicReference<Parent> rootPane) throws IOException{", " Locale locality = Locale.getDefault();", " ResourceBundle localization = ResourceBundle.getBundle(\"${namespace}.Language\", locality);", " FXMLLoader loader = new FXMLLoader(getClass().getResource(fxmlPath),localization);", " rootPane.set( loader.load());", " controller.set(loader.getController());", " }", " private void switchToScreen(Parent rootFXMLElement) {", " rootStage.setScene(new Scene(rootFXMLElement));", " rootStage.sizeToScene();", " rootStage.show();", " }", " public static ${className} getInstance(){", " if(instance == null){", " throw new IllegalStateException(\"Cannot get instance: application not yet initialized\");", " }", " return instance;", " }", " public Stage getMainStage() {", " return rootStage;", " }", " @Override public void init() throws Exception {", " instance = this;", " properties.load(getClass().getResource(\"version.properties\").openStream());", " }", " @Override", " public void stop(){", " quit();", " }", " void quit(){", " javafx.application.Platform.exit();", " System.exit(0);", " }", " public static void main(String[] args) {", " Application.launch(args);", " }", "}"]) | |
writeToFile("${projectDir}/${mainViewController}", ["package ${namespace};", "import java.net.URL;", "import java.util.ResourceBundle;", "import javafx.fxml.Initializable;", "public class MainViewController implements Initializable {", " private boolean rightToLeftLanguage = false;", " @Override", " public void initialize(URL url, ResourceBundle rb) {", " if(rb.containsKey(\"language.rtl\")) rightToLeftLanguage = Boolean.parseBoolean(rb.getString(\"language.rtl\"));", " }", "}"]) | |
writeToFile("${projectDir}/${mainViewFile}", ["<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "<?import javafx.geometry.*?>", "<?import java.lang.*?>", "<?import java.util.*?>", "<?import javafx.scene.*?>", "<?import javafx.scene.control.*?>", "<?import javafx.scene.layout.*?>", "<AnchorPane id=\"AnchorPane\" prefHeight=\"400.0\" prefWidth=\"600.0\" xmlns=\"http://javafx.com/javafx/8.0.40\" xmlns:fx=\"http://javafx.com/fxml/1\" fx:controller=\"${namespace}.MainViewController\">", " <children>", " <BorderPane prefHeight=\"200.0\" prefWidth=\"200.0\" AnchorPane.bottomAnchor=\"0.0\" AnchorPane.leftAnchor=\"0.0\" AnchorPane.rightAnchor=\"0.0\" AnchorPane.topAnchor=\"0.0\">", " <center>", " <SplitPane dividerPositions=\"0.667\" BorderPane.alignment=\"CENTER\">", " <items>", " <BorderPane />", " <VBox spacing=\"8.0\">", " <padding>", " <Insets bottom=\"8.0\" left=\"8.0\" right=\"8.0\" top=\"8.0\" />", " </padding>", " <children>", " <Label text=\"%gui.mainview.label2\" />", " <Separator prefWidth=\"200.0\" />", " <FlowPane hgap=\"8.0\" vgap=\"8.0\">", " <children>", " <Label text=\"%gui.mainview.label1\" />", " <Button mnemonicParsing=\"false\" text=\"%gui.mainview.button1\" />", " </children>", " </FlowPane>", " </children>", " </VBox>", " </items>", " </SplitPane>", " </center>", " </BorderPane>", " </children>", "</AnchorPane>"]) | |
writeToFile("${projectDir}/${mainClassITFile}", ["package ${namespace};", 'import javafx.application.Application;', 'import org.junit.Test;', 'import static org.junit.Assert.*;', "public class ${className}IT {", " public ${className}IT() { }", ' @Test', " public void test${className}() {", ' System.out.println(String.format("Running integration test for %s",', " ${mainClassName}.class));", " Application.launch(${mainClassName}.class);", ' }', '}']) | |
println "Creating language localization files (English, Spanish, and Simplified Chinese)" | |
writeToFile("${projectDir}/${languageBaseFile}.properties", ["language.name=English", "language.rtl=false", "gui.mainview.label1=Label 1", "gui.mainview.label2=Label 2", "gui.mainview.button1=Button 1"]) | |
writeToFile("${projectDir}/${languageBaseFile}_en_US.properties", ["language.name=English", "language.rtl=false", "gui.mainview.label1=Label 1", "gui.mainview.label2=Label 2", "gui.mainview.button1=Button 1"]) | |
writeToFile("${projectDir}/${languageBaseFile}_es.properties", ["language.name=Espa\\u00f1ol", "language.rtl=false", "gui.mainview.label1=etiqueta 1", "gui.mainview.label2=etiqueta 2", "gui.mainview.button1=bot\\u00f3n 1"]) | |
writeToFile("${projectDir}/${languageBaseFile}_zh_CN.properties", ["language.name=\\u7b80\\u4f53\\u4e2d\\u6587", "language.rtl=false", "gui.mainview.label1=\\u6807\\u7b7e1", "gui.mainview.label2=\\u6807\\u7b7e2", "gui.mainview.button1=\\u6309\\u94ae1"]) | |
} | |
println "Creating DVCS ignore files" | |
if ( ! file('.hgignore').exists() ){ | |
println "Creating .hgignore file" | |
writeToFile('.hgignore',['# mercurial ignore file', '# using glob syntax (use "syntax: regexp" for REGEX expressions)', 'syntax: glob', '# non-committed project folders and files', "${runDir}/**", "${buildDirName}/**", 'out/**', '.*gradle/**', '# ignore netbeans cache', 'private/**', '# ignore IntelliJ cache files', '.idea/**', '# ignore eclipse files', '.settings/**', '.classpath', '.project', '# ignore lock files', '# Open/Libre Office', '.~lock.*', '# MS Office', '~$*', '~*.tmp', '# gedit and notepad++', '*~']) | |
} else { | |
println ".hgignore file already exists" | |
} | |
if ( ! file('.gitignore').exists() ){ | |
println "Creating .gitignore file" | |
writeToFile('.gitignore',['# git ignore file', '# using glob syntax', '# (Note: unlike hg, git does not support REGEX parsing in ignore files)', '# non-committed project folders and files', "${runDir}/*", "${buildDirName}/*", 'out/*', '.*gradle/*', '# ignore netbeans cache', 'private/*', '# ignore IntelliJ cache files', '.idea/*', '# ignore eclipse files', '.settings/*', '.classpath', '.project', '# ignore lock files', '# Open/Libre Office', '.~lock.*', '# MS Office', '~$*', '~*.tmp', '# gedit and notepad++', '*~']) | |
} else { | |
println ".gitignore file already exists" | |
} | |
println "\tFor Windows icons, add the following files:" | |
println "${projectDir}/${nativeInstallerResources}/package/windows/${resourceName}.ico" | |
println "${projectDir}/${nativeInstallerResources}/package/windows/${resourceName}-setup-icon.bmp" | |
println "\tFor Mac OS X icons, add the following files:" | |
println "${projectDir}/${nativeInstallerResources}/package/macosx/${resourceName}.icns" | |
println "\tFor Linux icons, add the following files:" | |
println "${projectDir}/${nativeInstallerResources}/package/linux/${resourceName}.png (image size must be 512x512 pixels)" | |
println "Project creation complete." | |
} | |
} | |
// functions | |
public String readVersionNumber( def filepath, def majorVersionKey, def minorVersionKey, def buildVersionKey ){ | |
Properties props = new Properties() | |
File propsFile = new File(filepath) | |
props.load(propsFile.newDataInputStream()) | |
def majorV = props.getProperty(majorVersionKey) | |
def minorV = props.getProperty(minorVersionKey) | |
def buildV = props.getProperty(buildVersionKey) | |
return "${majorV}.${minorV}.${buildV}".toString() | |
} | |
public void incrementPropertyNumber( def filepath, def buildVersionKey ){ | |
Properties props = new Properties() | |
File propsFile = new File(filepath) | |
props.load(propsFile.newDataInputStream()) | |
Integer nextbuildnum = ( ((props.getProperty(buildVersionKey)) as BigDecimal) + 1 ) | |
props.setProperty(buildVersionKey, nextbuildnum.toString()) | |
props.store(propsFile.newWriter(), null) | |
} | |
public void makeFolder( def folderpath) { | |
println "Creating directory: ${folderpath}" | |
java.nio.file.Files.createDirectories(java.nio.file.Paths.get(folderpath.toString())) | |
} | |
public void writeToFile( def filepath, def contentList) { | |
println "Writing to file: ${filepath}" | |
File f = new File(filepath) | |
contentList.each { | |
f << ("${it}\n") | |
} | |
} | |
public String fileName( def filepath) { | |
return java.nio.file.Paths.get(filepath.toString()).getFileName().toString() | |
} | |
public String folderName( def filepath) { | |
return java.nio.file.Paths.get(filepath.toString()).getParent().toString().replace('\\','/') | |
} | |
public String relativeTo( def filepath, def rootfilepath) { | |
return java.nio.file.Paths.get(rootfilepath.toString()).relativize(java.nio.file.Paths.get(filepath.toString())).toString().replace('\\','/') | |
} | |
public String classPathToFilePath( def classPathString ) { | |
return classPathString.toString().replace('.','/') | |
} | |
///// end of utility functions ///// |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Added JavaFX native deployment plugin and configuration