1 import org.apache.tools.ant.filters.ReplaceTokens
2 import org.gradle.internal.os.OperatingSystem
3 import org.gradle.plugins.ide.eclipse.model.Output
4 import org.gradle.plugins.ide.eclipse.model.Library
6 import groovy.transform.ExternalizeMethods
10 classpath 'org.openclover:clover:4.3.1'
18 id 'com.github.johnrengelman.shadow' version '4.0.3'
19 id 'com.install4j.gradle' version '7.0.9'
20 id 'com.dorongold.task-tree' version '1.4' // only needed to display task dependency tree with gradle task1 [task2 ...] taskTree
33 compile 'org.apache.commons:commons-compress:1.18'
37 // in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use
38 def string(Object o) {
44 jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
45 jalviewDirRelativePath = jalviewDir
47 // local build environment properties
48 def localProps = "${jalviewDirAbsolutePath}/local.properties"
49 if (file(localProps).exists()) {
51 def p = new Properties()
52 def localPropsFIS = new FileInputStream(localProps)
57 def over = getProperty(key) != null
60 println("Overriding property '${key}' with local.properties value '${val}'")
63 } catch (Exception e) {
64 System.out.println("Exception reading local.properties")
68 // this property set when running Eclipse headlessly
69 j2sHeadlessBuildProperty = string("net.sf.j2s.core.headlessbuild")
70 // this property set by Eclipse
71 eclipseApplicationProperty = string("eclipse.application")
72 // CHECK IF RUNNING FROM WITHIN ECLIPSE
73 def eclipseApplicationPropertyVal = System.properties[eclipseApplicationProperty]
74 IN_ECLIPSE = eclipseApplicationPropertyVal != null && eclipseApplicationPropertyVal.startsWith("org.eclipse.ui.")
75 // BUT WITHOUT THE HEADLESS BUILD PROPERTY SET
76 if (System.properties[j2sHeadlessBuildProperty].equals("true")) {
77 println("Setting IN_ECLIPSE to ${IN_ECLIPSE} as System.properties['${j2sHeadlessBuildProperty}'] == '${System.properties[j2sHeadlessBuildProperty]}'")
81 println("WITHIN ECLIPSE IDE")
83 println("HEADLESS BUILD")
86 System.properties.sort { it.key }.each {
87 key, val -> println("SYSTEM PROPERTY ${key}='${val}'")
89 if (false && IN_ECLIPSE) {
90 jalviewDir = jalviewDirAbsolutePath
95 bareSourceDir = string(source_dir)
96 sourceDir = string("${jalviewDir}/${bareSourceDir}")
97 resourceDir = string("${jalviewDir}/${resource_dir}")
98 bareTestSourceDir = string(test_source_dir)
99 testSourceDir = string("${jalviewDir}/${bareTestSourceDir}")
102 cloverInstrDir = file("${buildDir}/${cloverSourcesInstrDir}")
103 classesDir = string("${jalviewDir}/${classes_dir}")
104 if (clover.equals("true")) {
106 classesDir = string("${buildDir}/${cloverClassesDir}")
109 classesDir = string("${jalviewDir}/${classes_dir}")
114 getdownWebsiteDir = string("${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}")
115 getdownDir = string("")
116 reportRsyncCmd = false
118 buildProperties = build_properties_file
119 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
123 // TODO: get bamboo build artifact URL for getdown artifacts
124 getdown_channel_base = bamboo_channelbase
125 getdown_channel_name = string("${bamboo_planKey}/${JAVA_VERSION}")
126 getdown_app_base = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
127 getdown_app_dir = getdown_app_dir_alt
128 buildProperties = string("${classesDir}/${build_properties_file}")
132 getdown_channel_name = CHANNEL.toLowerCase()
133 getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
134 getdown_app_base = string("${getdown_channel_base}/${getdownDir}")
135 getdown_app_dir = getdown_app_dir_release
136 buildProperties = string("${classesDir}/${build_properties_file}")
137 reportRsyncCommand = true
141 getdown_channel_name = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
142 getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
143 getdown_app_base = string("${getdown_channel_base}/${getdownDir}")
144 getdown_app_dir = getdown_app_dir_alt
145 if (!file("${ARCHIVEDIR}/${packageDir}").exists()) {
146 print "Must provide an ARCHIVEDIR value to produce an archive distribution"
149 packageDir = string("${ARCHIVEDIR}/${packageDir}")
150 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
153 reportRsyncCommand = true
157 getdown_channel_name = string("archive/${JALVIEW_VERSION}")
158 getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
159 getdown_app_base = file(getdownWebsiteDir).toURI().toString()
160 getdown_app_dir = getdown_app_dir_alt
161 if (!file("${ARCHIVEDIR}/${packageDir}").exists()) {
162 print "Must provide an ARCHIVEDIR value to produce an archive distribution"
165 packageDir = string("${ARCHIVEDIR}/${packageDir}")
166 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
169 reportRsyncCommand = true
170 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
174 getdown_channel_name = CHANNEL.toLowerCase()
175 getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
176 getdown_app_base = string("${getdown_channel_base}/${getdownDir}")
177 getdown_app_dir = getdown_app_dir_alt
178 buildProperties = string("${classesDir}/${build_properties_file}")
179 reportRsyncCommand = true
183 getdown_channel_name = CHANNEL.toLowerCase()
184 getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
185 getdown_app_base = string("${getdown_channel_base}/${getdownDir}")
186 getdown_app_dir = getdown_app_dir_alt
187 buildProperties = string("${classesDir}/${build_properties_file}")
188 reportRsyncCommand = true
191 case ~/^SCRATCH(|-[-\w]*)$/:
192 getdown_channel_name = CHANNEL
193 getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
194 getdown_app_base = string("${getdown_channel_base}/${getdownDir}")
195 getdown_app_dir = getdown_app_dir_alt
196 buildProperties = string("${classesDir}/${build_properties_file}")
197 reportRsyncCommand = true
201 getdown_app_base = file(getdownWebsiteDir).toURI().toString()
202 getdown_app_dir = getdown_app_dir_alt
203 buildProperties = string("${classesDir}/${build_properties_file}")
204 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
207 default: // something wrong specified
208 print("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
214 getdownAppDir = string("${getdownWebsiteDir}/${getdown_app_dir}")
215 //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}"
216 getdownResourceDir = string("${getdownWebsiteDir}/${getdown_resource_dir}")
217 getdownInstallDir = string("${getdownWebsiteDir}/${getdown_install_dir}")
218 getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
219 getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
220 /* compile without modules -- using classpath libraries
221 modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
222 modules_runtimeClasspath = modules_compileClasspath
225 gitBranch = string("")
227 println("Using a ${CHANNEL} profile.")
229 additional_compiler_args = []
230 // configure classpath/args for j8/j11 compilation
231 if (JAVA_VERSION.equals("1.8")) {
232 JAVA_INTEGER_VERSION = string("8")
235 libDistDir = j8libDir
236 compile_source_compatibility = 1.8
237 compile_target_compatibility = 1.8
238 // these are getdown.txt properties defined dependent on the JAVA_VERSION
239 getdown_alt_java_min_version = getdown_alt_java8_min_version
240 getdown_alt_java_max_version = getdown_alt_java8_max_version
241 // this property is assigned below and expanded to multiple lines in the getdown task
242 getdown_alt_multi_java_location = getdown_alt_java8_txt_multi_java_location
243 // this property is for the Java library used in eclipse
244 eclipse_java_runtime_name = string("JavaSE-1.8")
245 } else if (JAVA_VERSION.equals("11")) {
246 JAVA_INTEGER_VERSION = string("11")
248 libDistDir = j11libDir
249 compile_source_compatibility = 11
250 compile_target_compatibility = 11
251 getdown_alt_java_min_version = getdown_alt_java11_min_version
252 getdown_alt_java_max_version = getdown_alt_java11_max_version
253 getdown_alt_multi_java_location = getdown_alt_java11_txt_multi_java_location
254 eclipse_java_runtime_name = string("JavaSE-11")
255 /* compile without modules -- using classpath libraries
256 additional_compiler_args += [
257 '--module-path', modules_compileClasspath.asPath,
258 '--add-modules', j11modules
261 } else if (JAVA_VERSION.equals("12") || JAVA_VERSION.equals("13")) {
262 JAVA_INTEGER_VERSION = JAVA_VERSION
264 libDistDir = j11libDir
265 compile_source_compatibility = JAVA_VERSION
266 compile_target_compatibility = JAVA_VERSION
267 getdown_alt_java_min_version = getdown_alt_java11_min_version
268 getdown_alt_java_max_version = getdown_alt_java11_max_version
269 getdown_alt_multi_java_location = getdown_alt_java11_txt_multi_java_location
270 eclipse_java_runtime_name = string("JavaSE-11")
271 /* compile without modules -- using classpath libraries
272 additional_compiler_args += [
273 '--module-path', modules_compileClasspath.asPath,
274 '--add-modules', j11modules
278 throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
283 macosJavaVMDir = string("${System.env.HOME}/buildtools/jre/openjdk-java_vm/getdown/macos-jre${JAVA_VERSION}/jre")
284 macosJavaVMTgz = string("${System.env.HOME}/buildtools/jre/openjdk-java_vm/install4j/tgz/macos-jre${JAVA_VERSION}.tar.gz")
285 windowsJavaVMDir = string("${System.env.HOME}/buildtools/jre/openjdk-java_vm/getdown/windows-jre${JAVA_VERSION}/jre")
286 windowsJavaVMTgz = string("${System.env.HOME}/buildtools/jre/openjdk-java_vm/install4j/tgz/windows-jre${JAVA_VERSION}.tar.gz")
287 install4jDir = string("${jalviewDir}/${install4jResourceDir}")
288 install4jConfFileName = string("jalview-installers-java${JAVA_VERSION}.install4j")
289 install4jConfFile = string("${install4jDir}/${install4jConfFileName}")
292 buildingHTML = string("${jalviewDir}/${docDir}/building.html")
293 helpFile = string("${classesDir}/${help_dir}/help.jhm")
294 helpParentDir = string("${jalviewDir}/${help_parent_dir}")
295 helpDir = string("${help_dir}")
296 helpSourceDir = string("${helpParentDir}/${helpDir}")
299 relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
300 jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
301 jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}")
303 jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
305 jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
307 jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
308 jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
309 jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
310 jalviewjsJalviewCoreHtmlFile = string("")
311 jalviewjsJalviewCoreName = string(jalviewjs_core_name)
312 jalviewjsCoreClasslists = []
313 jalviewjsJalviewTemplateName = string(jalviewjs_name)
314 jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
315 jalviewjsJ2sProps = null
317 eclipseWorkspace = null
318 eclipseBinary = string("")
319 eclipseVersion = string("")
329 outputDir = file(classesDir)
336 jar.destinationDir = file("${jalviewDir}/${packageDir}")
338 compileClasspath = files(sourceSets.main.java.outputDir)
339 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
341 runtimeClasspath = compileClasspath
346 srcDirs = [ cloverInstrDir ]
347 outputDir = file("${buildDir}/${cloverClassesDir}")
351 srcDirs = sourceSets.main.resources.srcDirs
353 compileClasspath = configurations.cloverRuntime + files( sourceSets.clover.java.outputDir )
354 compileClasspath += files(sourceSets.main.java.outputDir)
355 compileClasspath += sourceSets.main.compileClasspath
356 compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}", include: ["**/*.jar"])
357 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
359 runtimeClasspath = compileClasspath
364 srcDirs testSourceDir
365 outputDir = file("${jalviewDir}/${testOutputDir}")
369 srcDirs = sourceSets.main.resources.srcDirs
372 compileClasspath = files( sourceSets.test.java.outputDir )
375 compileClasspath += sourceSets.clover.compileClasspath
377 compileClasspath += files(sourceSets.main.java.outputDir)
380 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
381 compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}/testnglibs", include: ["**/*.jar"])
382 compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}/testlibs", include: ["**/*.jar"])
384 runtimeClasspath = compileClasspath
392 cloverCompile 'org.openclover:clover:4.3.1'
393 testCompile 'org.openclover:clover:4.3.1'
400 cloverRuntime.extendsFrom cloverCompile
405 name = eclipse_project_name
407 natures 'org.eclipse.jdt.core.javanature',
408 'org.eclipse.jdt.groovy.core.groovyNature',
409 'org.eclipse.buildship.core.gradleprojectnature'
411 buildCommand 'org.eclipse.jdt.core.javabuilder'
412 buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
416 //defaultOutputDir = sourceSets.main.java.outputDir
419 if (it.isCanBeResolved()) {
424 minusConfigurations += removeThese
425 plusConfigurations = [ ]
429 def removeTheseToo = []
430 HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
431 cp.entries.each { entry ->
432 if (entry.kind == 'src') {
433 if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) {
434 removeTheseToo += entry
436 alreadyAddedSrcPath.putAt(entry.path, true)
440 cp.entries.removeAll(removeTheseToo)
442 cp.entries += new Output("${eclipse_bin_dir}/main")
443 if (file(helpSourceDir).isDirectory()) {
444 cp.entries += new Library(fileReference(helpSourceDir))
446 if (file(resourceDir).isDirectory()) {
447 cp.entries += new Library(fileReference(resourceDir))
450 HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
452 sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.each {
453 //don't want to add outputDir as eclipse is using its own output dir in bin/main
454 if (it.isDirectory() || ! it.exists()) {
455 // don't add dirs to classpath
458 def itPath = it.toString()
459 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
460 // make relative path
461 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
463 if (alreadyAddedLibPath.get(itPath)) {
464 //println("Not adding duplicate entry "+itPath)
466 //println("Adding entry "+itPath)
467 cp.entries += new Library(fileReference(itPath))
468 alreadyAddedLibPath.put(itPath, true)
472 //fileTree(dir: "$jalviewDir/$utilsDir", include: ["test*/*.jar"]).each {
473 sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
474 //no longer want to add outputDir as eclipse is using its own output dir in bin/main
475 if (it.isDirectory() || ! it.exists()) {
476 // don't add dirs to classpath
477 return false // groovy "continue" in .any closure
480 def itPath = it.toString()
481 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
482 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
484 if (alreadyAddedLibPath.get(itPath)) {
487 def lib = new Library(fileReference(itPath))
488 lib.entryAttributes["test"] = "true"
490 alreadyAddedLibPath.put(itPath, true)
498 containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
503 // for the IDE, use java 11 compatibility
504 sourceCompatibility = compile_source_compatibility
505 targetCompatibility = compile_target_compatibility
506 javaRuntimeName = eclipse_java_runtime_name
508 // add in jalview project specific properties/preferences into eclipse core preferences
510 withProperties { props ->
511 def jalview_prefs = new Properties()
512 def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
513 jalview_prefs.load(ins)
515 jalview_prefs.forEach { t, v ->
516 if (props.getAt(t) == null) {
526 // Don't want these to be activated if in headless build
527 synchronizationTasks "eclipseSynchronizationTask"
528 autoBuildTasks "eclipseAutoBuildTask"
534 // only instrument source, we build test classes as normal
535 inputs.files files (sourceSets.main.allJava) // , fileTree(dir: testSourceDir, include: ["**/*.java"]))
536 outputs.dir cloverInstrDir
539 delete cloverInstrDir
540 def argsList = ["--initstring", "${buildDir}/clover/clover.db",
541 "-d", "${buildDir}/${cloverSourcesInstrDir}"]
542 argsList.addAll(inputs.files.files.collect({ file ->
545 String[] args = argsList.toArray()
546 println("About to instrument "+args.length +" files")
547 com.atlassian.clover.CloverInstr.mainImpl(args)
553 group = "Verification"
554 description = "Createst the Clover report"
555 inputs.dir "${buildDir}/clover"
556 outputs.dir "${reportsDir}/clover"
558 file("${buildDir}/clover/clover.db").exists()
561 def argsList = ["--initstring", "${buildDir}/clover/clover.db",
562 "-o", "${reportsDir}/clover"]
563 String[] args = argsList.toArray()
564 com.atlassian.clover.reporters.html.HtmlReporter.runReport(args)
566 // and generate ${reportsDir}/clover/clover.xml
567 args = ["--initstring", "${buildDir}/clover/clover.db",
568 "-o", "${reportsDir}/clover/clover.xml"].toArray()
569 com.atlassian.clover.reporters.xml.XMLReporter.runReport(args)
578 sourceCompatibility = compile_source_compatibility
579 targetCompatibility = compile_target_compatibility
580 options.compilerArgs = additional_compiler_args
581 print ("Setting target compatibility to "+targetCompatibility+"\n")
589 dependsOn compileCloverJava
590 classpath += configurations.cloverRuntime
592 classpath += sourceSets.main.runtimeClasspath
595 sourceCompatibility = compile_source_compatibility
596 targetCompatibility = compile_target_compatibility
597 options.compilerArgs = additional_compiler_args
598 print ("Setting target compatibility to "+targetCompatibility+"\n")
606 sourceCompatibility = compile_source_compatibility
607 targetCompatibility = compile_target_compatibility
608 options.compilerArgs += additional_compiler_args
609 print ("Setting target compatibility to "+targetCompatibility+"\n")
611 classpath += configurations.cloverRuntime
617 delete sourceSets.main.java.outputDir
624 delete sourceSets.test.java.outputDir
625 delete cloverInstrDir
630 // format is a string like date.format("dd MMMM yyyy")
631 def getDate(format) {
632 def date = new Date()
633 return date.format(format)
638 def hashStdOut = new ByteArrayOutputStream()
640 commandLine "git", "rev-parse", "--short", "HEAD"
641 standardOutput = hashStdOut
645 def branchStdOut = new ByteArrayOutputStream()
647 commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
648 standardOutput = branchStdOut
652 gitHash = hashStdOut.toString().trim()
653 gitBranch = branchStdOut.toString().trim()
655 outputs.upToDateWhen { false }
659 task createBuildProperties(type: WriteProperties) {
661 inputs.dir(sourceDir)
662 inputs.dir(resourceDir)
663 file(buildProperties).getParentFile().mkdirs()
664 outputFile (buildProperties)
665 // taking time specific comment out to allow better incremental builds
666 comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
667 //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
668 property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
669 property "VERSION", JALVIEW_VERSION
670 property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
671 outputs.file(outputFile)
675 task cleanBuildingHTML(type: Delete) {
682 task convertBuildingMD(type: Exec) {
683 dependsOn cleanBuildingHTML
684 def buildingMD = "${jalviewDir}/${docDir}/building.md"
685 def css = "${jalviewDir}/${docDir}/github.css"
688 pandoc_exec.split(",").each {
689 if (file(it.trim()).exists()) {
695 def hostname = "hostname".execute().text.trim()
696 if ((pandoc == null || ! file(pandoc).exists()) && hostname.equals("jv-bamboo")) {
697 pandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
701 if (pandoc != null && file(pandoc).exists()) {
702 commandLine pandoc, '-s', '-o', buildingHTML, '--metadata', 'pagetitle="Building Jalview from Source"', '--toc', '-H', css, buildingMD
704 println("Cannot find pandoc. Skipping convert building.md to HTML")
705 throw new StopExecutionException()
711 inputs.file(buildingMD)
713 outputs.file(buildingHTML)
724 task syncDocs(type: Sync) {
725 dependsOn convertBuildingMD
726 def syncDir = "${classesDir}/${docDir}"
727 from fileTree("${jalviewDir}/${docDir}")
733 task copyHelp(type: Copy) {
734 def inputDir = helpSourceDir
735 def outputDir = "${classesDir}/${helpDir}"
740 filter(ReplaceTokens,
744 'Version-Rel': JALVIEW_VERSION,
745 'Year-Rel': getDate("yyyy")
757 outputs.files(helpFile)
758 outputs.dir(outputDir)
762 task syncLib(type: Sync) {
763 def syncDir = "${classesDir}/${libDistDir}"
764 from fileTree("${jalviewDir}/${libDistDir}")
769 task syncResources(type: Sync) {
780 dependsOn syncResources
786 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
789 dependsOn compileJava
791 dependsOn cloverInstr
795 print("Running tests " + (use_clover?"WITH":"WITHOUT") + " clover [clover="+use_clover+"]\n")
799 includeGroups testngGroups
801 useDefaultListeners=true
804 workingDir = jalviewDir
805 //systemProperties 'clover.jar' System.properties.clover.jar
806 sourceCompatibility = compile_source_compatibility
807 targetCompatibility = compile_target_compatibility
808 jvmArgs += additional_compiler_args
813 task buildIndices(type: JavaExec) {
815 classpath = sourceSets.main.compileClasspath
816 main = "com.sun.java.help.search.Indexer"
817 workingDir = "${classesDir}/${helpDir}"
820 inputs.dir("${workingDir}/${argDir}")
822 outputs.dir("${classesDir}/doc")
823 outputs.dir("${classesDir}/help")
824 outputs.file("${workingDir}/JavaHelpSearch/DOCS")
825 outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
826 outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
827 outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
828 outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
829 outputs.file("${workingDir}/JavaHelpSearch/TMAP")
833 task compileLinkCheck(type: JavaCompile) {
835 classpath = files("${jalviewDir}/${utilsDir}")
836 destinationDir = file("${jalviewDir}/${utilsDir}")
837 source = fileTree(dir: "${jalviewDir}/${utilsDir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
839 inputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.java")
840 inputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.java")
841 outputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.class")
842 outputs.file("${jalviewDir}/${utilsDir}/BufferedLineReader.class")
846 task linkCheck(type: JavaExec) {
847 dependsOn prepare, compileLinkCheck
849 def helpLinksCheckerOutFile = file("${jalviewDir}/${utilsDir}/HelpLinksChecker.out")
850 classpath = files("${jalviewDir}/${utilsDir}")
851 main = "HelpLinksChecker"
852 workingDir = jalviewDir
853 def help = "${classesDir}/${helpDir}"
854 args = [ "${classesDir}/${helpDir}", "-nointernet" ]
856 def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
858 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
861 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
865 inputs.dir("${classesDir}/${helpDir}")
866 outputs.file(helpLinksCheckerOutFile)
869 // import the pubhtmlhelp target
870 ant.properties.basedir = "${jalviewDir}"
871 ant.properties.helpBuildDir = "${jalviewDirAbsolutePath}/${classes_dir}/${helpDir}"
872 ant.importBuild "${utilsDir}/publishHelp.xml"
875 task cleanPackageDir(type: Delete) {
877 delete fileTree(dir: "${jalviewDir}/${packageDir}", include: "*.jar")
883 dependsOn buildIndices
884 dependsOn createBuildProperties
887 attributes "Main-Class": mainClass,
888 "Permissions": "all-permissions",
889 "Application-Name": "Jalview Desktop",
890 "Codebase": application_codebase
893 destinationDir = file("${jalviewDir}/${packageDir}")
894 archiveName = rootProject.name+".jar"
902 inputs.dir(classesDir)
903 outputs.file("${jalviewDir}/${packageDir}/${archiveName}")
907 task copyJars(type: Copy) {
908 from fileTree(dir: classesDir, include: "**/*.jar").files
909 into "${jalviewDir}/${packageDir}"
913 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
914 task syncJars(type: Sync) {
915 from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
916 into "${jalviewDir}/${packageDir}"
918 include jar.archiveName
925 description = "Put all required libraries in dist"
926 // order of "cleanPackageDir", "copyJars", "jar" important!
927 jar.mustRunAfter cleanPackageDir
928 syncJars.mustRunAfter cleanPackageDir
929 dependsOn cleanPackageDir
932 outputs.dir("${jalviewDir}/${packageDir}")
937 dependsOn cleanPackageDir
943 group = "distribution"
947 from ("${jalviewDir}/${libDistDir}") {
951 attributes 'Implementation-Version': JALVIEW_VERSION
953 mainClassName = shadowJarMainClass
955 classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
960 task getdownWebsite() {
961 group = "distribution"
962 description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
967 def getdownWebsiteResourceFilenames = []
968 def getdownTextString = ""
969 def getdownResourceDir = getdownResourceDir
970 def getdownAppDir = getdownAppDir
971 def getdownResourceFilenames = []
974 // clean the getdown website and files dir before creating getdown folders
975 delete getdownWebsiteDir
976 delete getdownFilesDir
980 rename(build_properties_file, getdown_build_properties)
983 getdownWebsiteResourceFilenames += "${getdown_app_dir}/${getdown_build_properties}"
985 // go through properties looking for getdown_txt_...
986 def props = project.properties.sort { it.key }
987 if (getdown_alt_java_min_version.length() > 0) {
988 props.put("getdown_txt_java_min_version", getdown_alt_java_min_version)
990 if (getdown_alt_java_max_version.length() > 0) {
991 props.put("getdown_txt_java_max_version", getdown_alt_java_max_version)
993 props.put("getdown_txt_multi_java_location", getdown_alt_multi_java_location)
995 props.put("getdown_txt_appbase", getdown_app_base)
996 props.each{ prop, val ->
997 if (prop.startsWith("getdown_txt_") && val != null) {
998 if (prop.startsWith("getdown_txt_multi_")) {
999 def key = prop.substring(18)
1000 val.split(",").each{ v ->
1001 def line = "${key} = ${v}\n"
1002 getdownTextString += line
1005 // file values rationalised
1006 if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1008 if (val.indexOf('/') == 0) {
1011 } else if (val.indexOf('/') > 0) {
1012 // relative path (relative to jalviewDir)
1013 r = file( "${jalviewDir}/${val}" )
1016 val = "${getdown_resource_dir}/" + r.getName()
1017 getdownWebsiteResourceFilenames += val
1018 getdownResourceFilenames += r.getPath()
1021 if (! prop.startsWith("getdown_txt_resource")) {
1022 def line = prop.substring(12) + " = ${val}\n"
1023 getdownTextString += line
1029 getdownWebsiteResourceFilenames.each{ filename ->
1030 getdownTextString += "resource = ${filename}\n"
1032 getdownResourceFilenames.each{ filename ->
1035 into getdownResourceDir
1040 fileTree(file(packageDir)).each{ f ->
1041 if (f.isDirectory()) {
1042 def files = fileTree(dir: f, include: ["*"]).getFiles()
1044 } else if (f.exists()) {
1048 codeFiles.sort().each{f ->
1049 def name = f.getName()
1050 def line = "code = ${getdown_app_dir}/${name}\n"
1051 getdownTextString += line
1058 // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
1060 if (JAVA_VERSION.equals("11")) {
1061 def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
1062 j11libFiles.sort().each{f ->
1063 def name = f.getName()
1064 def line = "code = ${getdown_j11lib_dir}/${name}\n"
1065 getdownTextString += line
1068 into getdownJ11libDir
1074 // getdown-launcher.jar should not be in main application class path so the main application can move it when updated. Listed as a resource so it gets updated.
1075 //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
1076 getdownTextString += "resource = ${getdown_launcher_new}\n"
1077 getdownTextString += "class = ${mainClass}\n"
1079 def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
1080 getdown_txt.write(getdownTextString)
1082 def launch_jvl = file("${getdownWebsiteDir}/${getdown_launch_jvl}")
1083 launch_jvl.write("appbase="+props.get("getdown_txt_appbase"))
1086 from getdownLauncher
1087 rename(file(getdownLauncher).getName(), getdown_launcher_new)
1088 into getdownWebsiteDir
1092 from getdownLauncher
1093 if (file(getdownLauncher).getName() != getdown_launcher) {
1094 rename(file(getdownLauncher).getName(), getdown_launcher)
1096 into getdownWebsiteDir
1099 if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
1102 from getdownLauncher
1103 from "${getdownWebsiteDir}/${getdown_build_properties}"
1104 if (file(getdownLauncher).getName() != getdown_launcher) {
1105 rename(file(getdownLauncher).getName(), getdown_launcher)
1107 into getdownInstallDir
1111 from getdownInstallDir
1112 into getdownFilesInstallDir
1119 from getdownLauncher
1120 from "${getdownWebsiteDir}/${getdown_build_properties}"
1121 if (file(getdownLauncher).getName() != getdown_launcher) {
1122 rename(file(getdownLauncher).getName(), getdown_launcher)
1124 into getdownFilesDir
1128 from getdownResourceDir
1129 into "${getdownFilesDir}/${getdown_resource_dir}"
1134 inputs.dir("${jalviewDir}/${packageDir}")
1136 outputs.dir(getdownWebsiteDir)
1137 outputs.dir(getdownFilesDir)
1141 task getdownDigest(type: JavaExec) {
1142 group = "distribution"
1143 description = "Digest the getdown website folder"
1144 dependsOn getdownWebsite
1146 classpath = files("${getdownWebsiteDir}/${getdown_launcher}")
1148 main = "com.threerings.getdown.tools.Digester"
1149 args getdownWebsiteDir
1150 inputs.dir(getdownWebsiteDir)
1151 outputs.file("${getdownWebsiteDir}/digest2.txt")
1156 group = "distribution"
1157 description = "Create the minimal and full getdown app folder for installers and website and create digest file"
1158 dependsOn getdownDigest
1160 if (reportRsyncCommand) {
1161 def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
1162 def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
1163 println "LIKELY RSYNC COMMAND:"
1164 println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
1165 if (RUNRSYNC == "true") {
1167 commandLine "mkdir", "-p", toDir
1170 commandLine "rsync", "-avh", "--delete", fromDir, toDir
1180 delete getdownWebsiteDir
1181 delete getdownFilesDir
1187 def install4jHomeDir = "/opt/install4j"
1188 def hostname = "hostname".execute().text.trim()
1189 if (hostname.equals("jv-bamboo")) {
1190 install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1191 } else if (OperatingSystem.current().isMacOsX()) {
1192 install4jHomeDir = '/Applications/install4j.app/Contents/Resources/app'
1193 if (! file(install4jHomeDir).exists()) {
1194 install4jHomeDir = System.getProperty("user.home")+install4jHomeDir
1196 } else if (OperatingSystem.current().isLinux()) {
1197 install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1199 installDir = file(install4jHomeDir)
1200 mediaTypes = Arrays.asList(install4jMediaTypes.split(","))
1201 if (install4jFaster.equals("true")) {
1207 task copyInstall4jTemplate(type: Copy) {
1208 from (install4jDir) {
1209 include install4jTemplate
1210 rename (install4jTemplate, install4jConfFileName)
1211 filter(ReplaceTokens,
1215 '9999999999': JAVA_VERSION
1218 filter(ReplaceTokens,
1222 'JAVA_VERSION': JAVA_VERSION,
1223 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
1224 'VERSION': JALVIEW_VERSION,
1225 'MACOS_JAVA_VM_DIR': macosJavaVMDir,
1226 'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
1227 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
1228 'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
1229 'INSTALL4JINFOPLISTFILEASSOCIATIONS': install4jInfoPlistFileAssociations,
1230 'COPYRIGHT_MESSAGE': install4jCopyrightMessage,
1231 'MACOS_BUNDLE_ID': install4jMacOSBundleId,
1232 'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
1233 'GETDOWN_DIST_DIR': getdown_app_dir,
1234 'GETDOWN_ALT_DIR': getdown_app_dir_alt,
1235 'GETDOWN_INSTALL_DIR': getdown_install_dir
1238 if (OSX_KEYPASS == "") {
1239 filter(ReplaceTokens,
1240 beginToken: 'codeSigning macEnabled="',
1243 'true': 'codeSigning macEnabled="false"'
1246 filter(ReplaceTokens,
1247 beginToken: 'runPostProcessor="true" ',
1248 endToken: 'Processor',
1250 'post': 'runPostProcessor="false" postProcessor'
1256 outputs.files(install4jConfFile)
1259 // include file associations in installer
1260 def installerFileAssociationsXml = file("${install4jDir}/${install4jInstallerFileAssociations}").text
1264 match: '<action name="EXTENSIONS_REPLACED_BY_GRADLE".*?</action>',
1265 replace: installerFileAssociationsXml,
1266 file: install4jConfFile
1269 // include uninstaller applescript app files in dmg
1270 def installerDMGUninstallerXml = file("$install4jDir/$install4jDMGUninstallerAppFiles").text
1274 match: '<file name="UNINSTALL_OLD_JALVIEW_APP_REPLACED_IN_GRADLE" file=.*?>',
1275 replace: installerDMGUninstallerXml,
1276 file: install4jConfFile
1285 delete install4jConfFile
1290 task installers(type: com.install4j.gradle.Install4jTask) {
1291 group = "distribution"
1292 description = "Create the install4j installers"
1294 dependsOn copyInstall4jTemplate
1295 projectFile = file(install4jConfFile)
1296 variables = [majorVersion: version.substring(2, 11), build: 001, OSX_KEYSTORE: OSX_KEYSTORE, JSIGN_SH: JSIGN_SH]
1297 destination = "${jalviewDir}/${install4jBuildDir}/${JAVA_VERSION}"
1298 buildSelected = true
1301 macKeystorePassword=OSX_KEYPASS
1305 println("Using projectFile "+projectFile)
1308 inputs.dir(getdownWebsiteDir)
1309 inputs.file(install4jConfFile)
1310 inputs.dir(macosJavaVMDir)
1311 inputs.dir(windowsJavaVMDir)
1312 outputs.dir("${jalviewDir}/${install4jBuildDir}/${JAVA_VERSION}")
1316 task sourceDist (type: Tar) {
1318 def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
1319 def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
1320 // cater for buildship < 3.1 [3.0.1 is max version in eclipse 2018-09]
1322 archiveFileName = outputFileName
1323 } catch (Exception e) {
1324 archiveName = outputFileName
1327 compression Compression.GZIP
1331 def EXCLUDE_FILES=["build/*","bin/*","test-output/","test-reports","tests","clover*/*"
1336 ,"**/*.class","${j11modDir}/**/*.jar","appletlib","**/*locales"
1338 ,"utils/InstallAnywhere"]
1339 def PROCESS_FILES=[ "AUTHORS",
1347 "THIRDPARTYLIBS","TESTNG",
1349 "gradle.properties",
1360 exclude (EXCLUDE_FILES)
1361 include (PROCESS_FILES)
1362 filter(ReplaceTokens,
1366 'Version-Rel': JALVIEW_VERSION,
1367 'Year-Rel': getDate("yyyy")
1372 exclude (EXCLUDE_FILES)
1373 exclude (PROCESS_FILES)
1374 exclude ("appletlib")
1375 exclude ("**/*locales")
1376 exclude ("*locales/**")
1377 exclude ("utils/InstallAnywhere")
1379 exclude (getdown_files_dir)
1380 exclude (getdown_website_dir)
1382 // exluding these as not using jars as modules yet
1383 exclude ("${j11modDir}/**/*.jar")
1385 // from (jalviewDir) {
1386 // // explicit includes for stuff that seemed to not get included
1387 // include(fileTree("test/**/*."))
1388 // exclude(EXCLUDE_FILES)
1389 // exclude(PROCESS_FILES)
1396 dependsOn pubhtmlhelp
1398 inputs.dir("${classesDir}/${helpDir}")
1399 outputs.dir("${buildDir}/distributions/${helpDir}")
1403 task j2sSetHeadlessBuild {
1410 task jalviewjsSetEclipseWorkspace {
1411 def propKey = "jalviewjs_eclipse_workspace"
1413 if (project.hasProperty(propKey)) {
1414 propVal = project.getProperty(propKey)
1415 if (propVal.startsWith("~/")) {
1416 propVal = System.getProperty("user.home") + propVal.substring(1)
1419 def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
1420 def propsFile = file(propsFileName)
1421 def eclipseWsDir = propVal
1422 def props = new Properties()
1424 if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
1425 def ins = new FileInputStream(propsFileName)
1428 if (props.getProperty(propKey, null) != null) {
1429 eclipseWsDir = props.getProperty(propKey)
1433 def writeProps = false
1434 if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
1435 def tempDir = File.createTempDir()
1436 eclipseWsDir = tempDir.getAbsolutePath()
1439 eclipseWorkspace = file(eclipseWsDir)
1442 // do not run a headless transpile when we claim to be in Eclipse
1444 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1445 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
1447 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1451 props.setProperty(propKey, eclipseWsDir)
1452 propsFile.parentFile.mkdirs()
1453 def bytes = new ByteArrayOutputStream()
1454 props.store(bytes, null)
1455 def propertiesString = bytes.toString()
1456 propsFile.text = propertiesString
1462 println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
1465 //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
1466 outputs.file(propsFileName)
1467 outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
1471 task jalviewjsEclipsePaths {
1474 def eclipseRoot = jalviewjs_eclipse_root
1475 if (eclipseRoot.startsWith("~/")) {
1476 eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
1478 if (OperatingSystem.current().isMacOsX()) {
1479 eclipseRoot += "/Eclipse.app"
1480 eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
1481 eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
1482 } else if (OperatingSystem.current().isWindows()) { // check these paths!!
1483 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1484 eclipseRoot += "/eclipse.exe"
1486 eclipseBinary = "${eclipseRoot}/eclipse"
1487 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1488 } else { // linux or unix
1489 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1490 eclipseRoot += "/eclipse"
1492 eclipseBinary = "${eclipseRoot}/eclipse"
1493 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1496 eclipseVersion = "4.13" // default
1497 def assumedVersion = true
1498 if (file(eclipseProduct).exists()) {
1499 def fis = new FileInputStream(eclipseProduct)
1500 def props = new Properties()
1502 eclipseVersion = props.getProperty("version")
1504 assumedVersion = false
1507 def propKey = "eclipse_debug"
1508 eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
1511 // do not run a headless transpile when we claim to be in Eclipse
1513 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1514 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
1516 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1519 if (!assumedVersion) {
1520 println("ECLIPSE VERSION=${eclipseVersion}")
1527 dependsOn eclipseProject
1528 dependsOn eclipseClasspath
1529 dependsOn eclipseJdt
1533 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
1534 task jalviewjsEclipseCopyDropins(type: Copy) {
1535 dependsOn jalviewjsEclipsePaths
1537 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
1538 inputFiles += file("${jalviewDir}/${jalviewjs_j2s_plugin}")
1539 def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
1546 // this eclipse -clean doesn't actually work
1547 task jalviewjsCleanEclipse(type: Exec) {
1548 dependsOn eclipseSetup
1549 dependsOn jalviewjsEclipsePaths
1550 dependsOn jalviewjsEclipseCopyDropins
1552 executable(eclipseBinary)
1553 args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
1559 def inputString = """exit
1562 def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
1563 standardInput = inputByteStream
1566 /* not really working yet
1567 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
1571 task jalviewjsTransferUnzipSwingJs {
1572 def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
1576 from zipTree(file_zip)
1577 into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
1581 inputs.file file_zip
1582 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
1586 task jalviewjsTransferUnzipLib {
1587 def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
1590 zipFiles.each { file_zip ->
1592 from zipTree(file_zip)
1593 into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
1598 inputs.files zipFiles
1599 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
1603 task jalviewjsTransferUnzipAllLibs {
1604 dependsOn jalviewjsTransferUnzipSwingJs
1605 dependsOn jalviewjsTransferUnzipLib
1609 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
1611 description "Create the .j2s file from the j2s.* properties"
1613 jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
1614 def siteDirProperty = "j2s.site.directory"
1615 def setSiteDir = false
1616 jalviewjsJ2sProps.each { prop, val ->
1618 if (prop == siteDirProperty) {
1619 if (!(val.startsWith('/') || val.startsWith("file://") )) {
1620 val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
1626 if (!setSiteDir) { // default site location, don't override specifically set property
1627 property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
1630 outputFile = jalviewjsJ2sSettingsFileName
1633 inputs.properties(jalviewjsJ2sProps)
1634 outputs.file(jalviewjsJ2sSettingsFileName)
1639 task jalviewjsEclipseSetup {
1640 dependsOn jalviewjsEclipseCopyDropins
1641 dependsOn jalviewjsSetEclipseWorkspace
1642 dependsOn jalviewjsCreateJ2sSettings
1646 task jalviewjsSyncAllLibs (type: Sync) {
1647 dependsOn jalviewjsTransferUnzipAllLibs
1648 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
1649 inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
1650 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
1654 def outputFiles = []
1655 rename { filename ->
1656 outputFiles += "${outputDir}/${filename}"
1662 outputs.files outputFiles
1663 inputs.files inputFiles
1667 task jalviewjsSyncResources (type: Sync) {
1668 def inputFiles = fileTree(dir: resourceDir)
1669 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
1673 def outputFiles = []
1674 rename { filename ->
1675 outputFiles += "${outputDir}/${filename}"
1681 outputs.files outputFiles
1682 inputs.files inputFiles
1686 task jalviewjsSyncSiteResources (type: Sync) {
1687 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
1688 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
1692 def outputFiles = []
1693 rename { filename ->
1694 outputFiles += "${outputDir}/${filename}"
1700 outputs.files outputFiles
1701 inputs.files inputFiles
1705 task jalviewjsSyncBuildProperties (type: Sync) {
1706 dependsOn createBuildProperties
1707 def inputFiles = [file(buildProperties)]
1708 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
1712 def outputFiles = []
1713 rename { filename ->
1714 outputFiles += "${outputDir}/${filename}"
1720 outputs.files outputFiles
1721 inputs.files inputFiles
1725 task jalviewjsProjectImport(type: Exec) {
1726 dependsOn eclipseSetup
1727 dependsOn jalviewjsEclipsePaths
1728 dependsOn jalviewjsEclipseSetup
1731 // do not run a headless import when we claim to be in Eclipse
1733 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1734 throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
1736 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1740 //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
1741 def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
1742 executable(eclipseBinary)
1743 args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
1747 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
1749 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
1752 inputs.file("${jalviewDir}/.project")
1753 outputs.upToDateWhen {
1754 file(projdir).exists()
1759 task jalviewjsTranspile(type: Exec) {
1760 dependsOn jalviewjsEclipseSetup
1761 dependsOn jalviewjsProjectImport
1762 dependsOn jalviewjsEclipsePaths
1765 // do not run a headless transpile when we claim to be in Eclipse
1767 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1768 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
1770 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1774 executable(eclipseBinary)
1775 args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
1779 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
1781 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
1787 stdout = new ByteArrayOutputStream()
1788 stderr = new ByteArrayOutputStream()
1790 def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
1791 def logOutFile = file(logOutFileName)
1792 logOutFile.createNewFile()
1793 logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
1794 BINARY: ${eclipseBinary}
1795 VERSION: ${eclipseVersion}
1796 WORKSPACE: ${eclipseWorkspace}
1797 DEBUG: ${eclipseDebug}
1800 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
1801 // combine stdout and stderr
1802 def logErrFOS = logOutFOS
1804 if (jalviewjs_j2s_to_console.equals("true")) {
1805 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1806 new org.apache.tools.ant.util.TeeOutputStream(
1810 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1811 new org.apache.tools.ant.util.TeeOutputStream(
1816 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1819 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1826 if (stdout.toString().contains("Error processing ")) {
1827 // j2s did not complete transpile
1828 //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
1829 throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
1833 inputs.dir("${jalviewDir}/${sourceDir}")
1834 outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
1835 outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
1839 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
1841 def stdout = new ByteArrayOutputStream()
1842 def stderr = new ByteArrayOutputStream()
1844 def coreFile = file(jsfile)
1846 msg = "Creating core for ${name}...\nGenerating ${jsfile}"
1848 logOutFile.createNewFile()
1849 logOutFile.append(msg+"\n")
1851 def coreTop = file(prefixFile)
1852 def coreBottom = file(suffixFile)
1853 coreFile.getParentFile().mkdirs()
1854 coreFile.createNewFile()
1855 coreFile.write( coreTop.text )
1860 t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
1861 coreFile.append( t )
1863 msg = "...file '"+f.getPath()+"' does not exist, skipping"
1865 logOutFile.append(msg+"\n")
1868 coreFile.append( coreBottom.text )
1870 msg = "Generating ${zjsfile}"
1872 logOutFile.append(msg+"\n")
1873 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
1874 def logErrFOS = logOutFOS
1877 classpath = files(["${jalviewDir}/tools/closure_compiler.jar"])
1878 args = [ "--js", jsfile, "--js_output_file", zjsfile ]
1880 msg = "\nRunning '"+commandLine.join(' ')+"'\n"
1882 logOutFile.append(msg+"\n")
1884 if (logOutConsole) {
1885 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1886 new org.apache.tools.ant.util.TeeOutputStream(
1890 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1891 new org.apache.tools.ant.util.TeeOutputStream(
1896 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1899 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1906 logOutFile.append(msg+"\n")
1910 task jalviewjsBuildAllCores {
1912 description "Build the core js lib closures listed in the classlists dir"
1913 dependsOn jalviewjsTranspile
1914 dependsOn jalviewjsTransferUnzipSwingJs
1916 def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
1917 def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
1918 def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
1919 def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
1920 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
1921 def prefixFile = "${jsDir}/core/coretop2.js"
1922 def suffixFile = "${jsDir}/core/corebottom2.js"
1924 inputs.file prefixFile
1925 inputs.file suffixFile
1927 def classlistFiles = []
1928 // add the classlists found int the jalviewjs_classlists_dir
1929 fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
1931 def name = file.getName() - ".txt"
1938 // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
1939 //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
1940 classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
1942 jalviewjsCoreClasslists = []
1944 classlistFiles.each {
1947 def file = hash['file']
1948 if (! file.exists()) {
1949 println("...classlist file '"+file.getPath()+"' does not exist, skipping")
1950 return false // this is a "continue" in groovy .each closure
1952 def name = hash['name']
1954 name = file.getName() - ".txt"
1962 def list = fileTree(dir: j2sDir, includes: filelist)
1964 def jsfile = "${outputDir}/core${name}.js"
1965 def zjsfile = "${outputDir}/core${name}.z.js"
1967 jalviewjsCoreClasslists += [
1976 outputs.file(jsfile)
1977 outputs.file(zjsfile)
1980 // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
1981 def stevesoftClasslistName = "_stevesoft"
1982 def stevesoftClasslist = [
1983 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
1984 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
1985 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
1986 'name': stevesoftClasslistName
1988 jalviewjsCoreClasslists += stevesoftClasslist
1989 inputs.files(stevesoftClasslist['list'])
1990 outputs.file(stevesoftClasslist['jsfile'])
1991 outputs.file(stevesoftClasslist['zjsfile'])
1994 def allClasslistName = "_all"
1995 def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
1996 allJsFiles += fileTree(
2000 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2001 "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
2002 "**/org/jmol/export/JSExporter.js"
2005 allJsFiles += fileTree(
2009 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2010 "**/sun/misc/Unsafe.js",
2011 "**/swingjs/jquery/jquery-editable-select.js",
2012 "**/swingjs/jquery/j2sComboBox.js",
2013 "**/sun/misc/FloatingDecimal.js"
2016 def allClasslist = [
2017 'jsfile': "${outputDir}/core${allClasslistName}.js",
2018 'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
2020 'name': allClasslistName
2022 jalviewjsCoreClasslists += allClasslist
2023 inputs.files(allClasslist['list'])
2024 outputs.file(allClasslist['jsfile'])
2025 outputs.file(allClasslist['zjsfile'])
2028 def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
2029 logOutFile.getParentFile().mkdirs()
2030 logOutFile.createNewFile()
2031 logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
2033 jalviewjsCoreClasslists.each {
2034 jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
2041 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
2044 into file(outputFile).getParentFile()
2045 rename { filename ->
2046 if (filename.equals(inputFile.getName())) {
2047 return file(outputFile).getName()
2051 filter(ReplaceTokens,
2055 'MAIN': '"'+mainClass+'"',
2057 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
2058 'COREKEY': jalviewjs_core_key,
2059 'CORENAME': coreName
2066 task jalviewjsPublishCoreTemplates {
2067 dependsOn jalviewjsBuildAllCores
2068 def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
2069 def inputFile = file(inputFileName)
2070 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2072 def outputFiles = []
2073 jalviewjsCoreClasslists.each { cl ->
2074 def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
2075 cl['outputfile'] = outputFile
2076 outputFiles += outputFile
2080 jalviewjsCoreClasslists.each { cl ->
2081 jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
2084 inputs.file(inputFile)
2085 outputs.files(outputFiles)
2089 task jalviewjsSyncCore (type: Sync) {
2090 dependsOn jalviewjsBuildAllCores
2091 dependsOn jalviewjsPublishCoreTemplates
2092 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
2093 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2097 def outputFiles = []
2098 rename { filename ->
2099 outputFiles += "${outputDir}/${filename}"
2105 outputs.files outputFiles
2106 inputs.files inputFiles
2110 // this Copy version of TransferSiteJs will delete anything else in the target dir
2111 task jalviewjsCopyTransferSiteJs(type: Copy) {
2112 dependsOn jalviewjsTranspile
2113 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2114 into "${jalviewDir}/${jalviewjsSiteDir}"
2118 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
2119 task jalviewjsSyncTransferSiteJs(type: Sync) {
2120 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2122 into "${jalviewDir}/${jalviewjsSiteDir}"
2129 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
2130 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
2131 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
2132 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
2134 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
2135 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
2136 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
2137 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
2140 task jalviewjsPrepareSite {
2142 description "Prepares the website folder including unzipping files and copying resources"
2143 dependsOn jalviewjsSyncAllLibs
2144 dependsOn jalviewjsSyncResources
2145 dependsOn jalviewjsSyncSiteResources
2146 dependsOn jalviewjsSyncBuildProperties
2147 dependsOn jalviewjsSyncCore
2151 task jalviewjsBuildSite {
2153 description "Builds the whole website including transpiled code"
2154 dependsOn jalviewjsCopyTransferSiteJs
2155 dependsOn jalviewjsPrepareSite
2159 task cleanJalviewjsSite {
2161 delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2162 delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2163 delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2164 delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2165 delete "${jalviewDir}/${jalviewjsSiteDir}"
2170 task jalviewjsSiteTar(type: Tar) {
2172 description "Creates a tar.gz file for the website"
2173 dependsOn jalviewjsBuildSite
2174 def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
2176 archiveFileName = outputFilename
2177 } catch (Exception e) {
2178 archiveName = outputFilename
2181 compression Compression.GZIP
2183 from "${jalviewDir}/${jalviewjsSiteDir}"
2184 into jalviewjs_site_dir // this is inside the tar file
2186 inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
2190 task jalviewjsServer {
2192 def filename = "jalviewjsTest.html"
2193 description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
2194 def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
2197 SimpleHttpFileServerFactory factory = new SimpleHttpFileServerFactory()
2198 def port = Integer.valueOf(jalviewjs_server_port)
2203 while(port < start+1000 && !running) {
2205 def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
2206 jalviewjsServer = factory.start(doc_root, port)
2208 url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
2209 println("SERVER STARTED with document root ${doc_root}.")
2210 println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).")
2211 println("For debug: "+url+"?j2sdebug")
2212 println("For verbose: "+url+"?j2sverbose")
2213 } catch (Exception e) {
2218 <p><a href="${url}">JalviewJS Test. <${url}></a></p>
2219 <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
2220 <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
2222 jalviewjsCoreClasslists.each { cl ->
2223 def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
2225 <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></a></p>
2227 println("For core ${cl.name}: "+urlcore)
2230 file(htmlFile).text = htmlText
2233 outputs.file(htmlFile)
2234 outputs.upToDateWhen({false})
2238 task cleanJalviewjsAll {
2240 description "Delete all configuration and build artifacts to do with JalviewJS build"
2241 dependsOn cleanJalviewjsSite
2242 dependsOn jalviewjsEclipsePaths
2245 delete "${jalviewDir}/${jalviewjsBuildDir}"
2246 delete "${jalviewDir}/${eclipse_bin_dir}"
2247 if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
2248 delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
2250 delete "${jalviewDir}/${jalviewjs_j2s_settings}"
2253 outputs.upToDateWhen( { false } )
2258 task jalviewjsIDE_j2sFile {
2259 group "00 JalviewJS in Eclipse"
2260 description "Creates the .j2s file"
2261 dependsOn jalviewjsCreateJ2sSettings
2265 task jalviewjsIDE_SyncCore {
2266 group "00 JalviewJS in Eclipse"
2267 description "Build the core js lib closures listed in the classlists dir and publish core html from template"
2268 dependsOn jalviewjsSyncCore
2272 task jalviewjsIDE_PrepareSite {
2273 group "00 JalviewJS in Eclipse"
2274 description "Sync libs and resources to site dir, but not closure cores"
2275 dependsOn jalviewjsSyncAllLibs
2276 dependsOn jalviewjsSyncResources
2277 dependsOn jalviewjsSyncSiteResources
2278 dependsOn jalviewjsSyncBuildProperties
2282 task jalviewjsIDE_AssembleSite {
2283 group "00 JalviewJS in Eclipse"
2284 description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
2285 dependsOn jalviewjsPrepareSite
2289 task jalviewjsIDE_SiteClean {
2290 group "00 JalviewJS in Eclipse"
2291 description "Deletes the Eclipse transpiled site"
2292 dependsOn cleanJalviewjsSite
2296 task jalviewjsIDE_Server {
2297 group "00 JalviewJS in Eclipse"
2298 description "Starts a webserver on localhost to test the website"
2299 dependsOn jalviewjsServer
2303 // buildship runs this at import
2304 task eclipseSynchronizationTask {
2305 //dependsOn eclipseSetup
2306 dependsOn jalviewjsIDE_j2sFile
2310 // buildship runs this at build time
2311 task eclipseAutoBuildTask {
2312 dependsOn jalviewjsIDE_PrepareSite
2324 description "Build the site"
2325 dependsOn jalviewjsBuildSite