1 /* Convention for properties. Read from gradle.properties, use lower_case_underlines for property names.
2 * For properties set within build.gradle, use camelCaseNoSpace.
4 import org.apache.tools.ant.filters.ReplaceTokens
5 import org.gradle.internal.os.OperatingSystem
6 import org.gradle.plugins.ide.internal.generator.PropertiesPersistableConfigurationObject
7 import org.gradle.api.internal.PropertiesTransformer
8 import org.gradle.util.ConfigureUtil
9 import org.gradle.plugins.ide.eclipse.model.Output
10 import org.gradle.plugins.ide.eclipse.model.Library
11 import java.security.MessageDigest
12 import groovy.transform.ExternalizeMethods
13 import groovy.util.XmlParser
14 import groovy.xml.XmlUtil
29 id "com.diffplug.gradle.spotless" version "3.28.0"
30 id 'com.github.johnrengelman.shadow' version '4.0.3'
31 id 'com.install4j.gradle' version '8.0.4'
32 id 'com.dorongold.task-tree' version '1.5' // only needed to display task dependency tree with gradle task1 [task2 ...] taskTree
33 id 'com.palantir.git-version' version '0.12.3'
43 // in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use
44 def string(Object o) {
45 return o == null ? "" : o.toString()
50 jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
51 jalviewDirRelativePath = jalviewDir
53 // local build environment properties
54 // can be "projectDir/local.properties"
55 def localProps = "${projectDir}/local.properties"
57 if (file(localProps).exists()) {
58 propsFile = localProps
60 // or "../projectDir_local.properties"
61 def dirLocalProps = projectDir.getParent() + "/" + projectDir.getName() + "_local.properties"
62 if (file(dirLocalProps).exists()) {
63 propsFile = dirLocalProps
65 if (propsFile != null) {
67 def p = new Properties()
68 def localPropsFIS = new FileInputStream(propsFile)
73 def oldval = findProperty(key)
76 println("Overriding property '${key}' ('${oldval}') with ${file(propsFile).getName()} value '${val}'")
78 println("Setting unknown property '${key}' with ${file(propsFile).getName()}s value '${val}'")
81 } catch (Exception e) {
82 System.out.println("Exception reading local.properties")
87 // Import releaseProps from the RELEASE file
88 // or a file specified via JALVIEW_RELEASE_FILE if defined
89 // Expect jalview.version and target release branch in jalview.release
90 def releaseProps = new Properties();
91 def releasePropFile = findProperty("JALVIEW_RELEASE_FILE");
92 def defaultReleasePropFile = "${jalviewDirAbsolutePath}/RELEASE";
94 (new File(releasePropFile!=null ? releasePropFile : defaultReleasePropFile)).withInputStream {
97 } catch (Exception fileLoadError) {
98 throw new Error("Couldn't load release properties file "+(releasePropFile==null ? defaultReleasePropFile : "from custom location: releasePropFile"),fileLoadError);
101 // Set JALVIEW_VERSION if it is not already set
102 if (findProperty(JALVIEW_VERSION)==null || "".equals(JALVIEW_VERSION)) {
103 JALVIEW_VERSION = releaseProps.get("jalview.version")
106 // this property set when running Eclipse headlessly
107 j2sHeadlessBuildProperty = string("net.sf.j2s.core.headlessbuild")
108 // this property set by Eclipse
109 eclipseApplicationProperty = string("eclipse.application")
110 // CHECK IF RUNNING FROM WITHIN ECLIPSE
111 def eclipseApplicationPropertyVal = System.properties[eclipseApplicationProperty]
112 IN_ECLIPSE = eclipseApplicationPropertyVal != null && eclipseApplicationPropertyVal.startsWith("org.eclipse.ui.")
113 // BUT WITHOUT THE HEADLESS BUILD PROPERTY SET
114 if (System.properties[j2sHeadlessBuildProperty].equals("true")) {
115 println("Setting IN_ECLIPSE to ${IN_ECLIPSE} as System.properties['${j2sHeadlessBuildProperty}'] == '${System.properties[j2sHeadlessBuildProperty]}'")
119 println("WITHIN ECLIPSE IDE")
121 println("HEADLESS BUILD")
124 J2S_ENABLED = (project.hasProperty('j2s.compiler.status') && project['j2s.compiler.status'] != null && project['j2s.compiler.status'] == "enable")
126 println("J2S ENABLED")
129 System.properties.sort { it.key }.each {
130 key, val -> println("SYSTEM PROPERTY ${key}='${val}'")
133 if (false && IN_ECLIPSE) {
134 jalviewDir = jalviewDirAbsolutePath
139 bareSourceDir = string(source_dir)
140 sourceDir = string("${jalviewDir}/${bareSourceDir}")
141 resourceDir = string("${jalviewDir}/${resource_dir}")
142 bareTestSourceDir = string(test_source_dir)
143 testDir = string("${jalviewDir}/${bareTestSourceDir}")
145 classesDir = string("${jalviewDir}/${classes_dir}")
148 useClover = clover.equals("true")
149 cloverBuildDir = "${buildDir}/clover"
150 cloverInstrDir = file("${cloverBuildDir}/clover-instr")
151 cloverClassesDir = file("${cloverBuildDir}/clover-classes")
152 cloverReportDir = file("${buildDir}/reports/clover")
153 cloverTestInstrDir = file("${cloverBuildDir}/clover-test-instr")
154 cloverTestClassesDir = file("${cloverBuildDir}/clover-test-classes")
155 //cloverTestClassesDir = cloverClassesDir
156 cloverDb = string("${cloverBuildDir}/clover.db")
158 resourceClassesDir = useClover ? cloverClassesDir : classesDir
160 testSourceDir = useClover ? cloverTestInstrDir : testDir
161 testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}"
163 getdownWebsiteDir = string("${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}")
166 // the following values might be overridden by the CHANNEL switch
167 getdownChannelName = CHANNEL.toLowerCase()
168 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
169 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
170 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
171 getdownAppDistDir = getdown_app_dir_alt
172 buildProperties = string("${resourceDir}/${build_properties_file}")
173 reportRsyncCommand = false
174 jvlChannelName = CHANNEL.toLowerCase()
175 install4jSuffix = CHANNEL.substring(0, 1).toUpperCase() + CHANNEL.substring(1).toLowerCase(); // BUILD -> Build
176 install4jDSStore = "DS_Store-NON-RELEASE"
177 install4jDMGBackgroundImage = "jalview_dmg_background-NON-RELEASE.png"
178 install4jInstallerName = "${jalview_name} Non-Release Installer"
179 install4jExecutableName = jalview_name.replaceAll("[^\\w]+", "_").toLowerCase()
180 install4jExtraScheme = "jalviewx"
184 // TODO: get bamboo build artifact URL for getdown artifacts
185 getdown_channel_base = bamboo_channelbase
186 getdownChannelName = string("${bamboo_planKey}/${JAVA_VERSION}")
187 getdownAppBase = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
188 jvlChannelName += "_${getdownChannelName}"
189 // automatically add the test group Not-bamboo for exclusion
190 if ("".equals(testng_excluded_groups)) {
191 testng_excluded_groups = "Not-bamboo"
193 install4jExtraScheme = "jalviewb"
197 getdownAppDistDir = getdown_app_dir_release
198 reportRsyncCommand = true
200 install4jDSStore = "DS_Store"
201 install4jDMGBackgroundImage = "jalview_dmg_background.png"
202 install4jInstallerName = "${jalview_name} Installer"
206 getdownChannelName = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
207 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
208 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
209 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
210 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
212 package_dir = string("${ARCHIVEDIR}/${package_dir}")
213 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
216 reportRsyncCommand = true
217 install4jExtraScheme = "jalviewa"
221 getdownChannelName = string("archive/${JALVIEW_VERSION}")
222 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
223 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
224 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
225 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
227 package_dir = string("${ARCHIVEDIR}/${package_dir}")
228 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
231 reportRsyncCommand = true
232 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
233 install4jSuffix = "Archive"
234 install4jExtraScheme = "jalviewa"
238 reportRsyncCommand = true
240 // DEVELOP-RELEASE is usually associated with a Jalview release series so set the version
241 JALVIEW_VERSION=JALVIEW_VERSION+"-develop"
243 install4jSuffix = "Develop"
244 install4jDSStore = "DS_Store-DEVELOP"
245 install4jDMGBackgroundImage = "jalview_dmg_background-DEVELOP.png"
246 install4jExtraScheme = "jalviewd"
247 install4jInstallerName = "${jalview_name} Develop Installer"
251 reportRsyncCommand = true
252 // Don't ignore transpile errors for release build
253 if (jalviewjs_ignore_transpile_errors.equals("true")) {
254 jalviewjs_ignore_transpile_errors = "false"
255 println("Setting jalviewjs_ignore_transpile_errors to 'false'")
257 JALVIEW_VERSION = JALVIEW_VERSION+"-test"
258 install4jSuffix = "Test"
259 install4jDSStore = "DS_Store-TEST-RELEASE"
260 install4jDMGBackgroundImage = "jalview_dmg_background-TEST.png"
261 install4jExtraScheme = "jalviewt"
262 install4jInstallerName = "${jalview_name} Test Installer"
265 case ~/^SCRATCH(|-[-\w]*)$/:
266 getdownChannelName = CHANNEL
267 JALVIEW_VERSION = JALVIEW_VERSION+"-"+CHANNEL
269 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
270 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
271 reportRsyncCommand = true
272 install4jSuffix = "Scratch"
276 if (!file("${LOCALDIR}").exists()) {
277 throw new GradleException("Must provide a LOCALDIR value to produce a local distribution")
279 getdownAppBase = file(file("${LOCALDIR}").getAbsolutePath()).toURI().toString()
280 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
282 JALVIEW_VERSION = "TEST"
283 install4jSuffix = "Test-Local"
284 install4jDSStore = "DS_Store-TEST-RELEASE"
285 install4jDMGBackgroundImage = "jalview_dmg_background-TEST.png"
286 install4jExtraScheme = "jalviewt"
287 install4jInstallerName = "${jalview_name} Test Installer"
291 JALVIEW_VERSION = "TEST"
292 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
293 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
294 install4jExtraScheme = "jalviewl"
297 default: // something wrong specified
298 throw new GradleException("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
302 // override getdownAppBase if requested
303 if (findProperty("getdown_appbase_override") != null) {
304 getdownAppBase = string(getProperty("getdown_appbase_override"))
305 println("Overriding getdown appbase with '${getdownAppBase}'")
307 // sanitise file name for jalview launcher file for this channel
308 jvlChannelName = jvlChannelName.replaceAll("[^\\w\\-]+", "_")
309 // install4j application and folder names
310 if (install4jSuffix == "") {
311 install4jApplicationName = "${jalview_name}"
312 install4jBundleId = "${install4j_bundle_id}"
313 install4jWinApplicationId = install4j_release_win_application_id
315 install4jApplicationName = "${jalview_name} ${install4jSuffix}"
316 install4jBundleId = "${install4j_bundle_id}-" + install4jSuffix.toLowerCase()
317 // add int hash of install4jSuffix to the last part of the application_id
318 def id = install4j_release_win_application_id
319 def idsplitreverse = id.split("-").reverse()
320 idsplitreverse[0] = idsplitreverse[0].toInteger() + install4jSuffix.hashCode()
321 install4jWinApplicationId = idsplitreverse.reverse().join("-")
323 // sanitise folder and id names
324 // install4jApplicationFolder = e.g. "Jalview Build"
325 install4jApplicationFolder = install4jApplicationName
326 .replaceAll("[\"'~:/\\\\\\s]", "_") // replace all awkward filename chars " ' ~ : / \
327 .replaceAll("_+", "_") // collapse __
328 install4jInternalId = install4jApplicationName
330 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
331 .replaceAll("_+", "") // collapse __
332 //.replaceAll("_*-_*", "-") // collapse _-_
333 install4jUnixApplicationFolder = install4jApplicationName
335 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
336 .replaceAll("_+", "_") // collapse __
337 .replaceAll("_*-_*", "-") // collapse _-_
340 getdownAppDir = string("${getdownWebsiteDir}/${getdownAppDistDir}")
341 //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}"
342 getdownResourceDir = string("${getdownWebsiteDir}/${getdown_resource_dir}")
343 getdownInstallDir = string("${getdownWebsiteDir}/${getdown_install_dir}")
344 getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
345 getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
346 /* compile without modules -- using classpath libraries
347 modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
348 modules_runtimeClasspath = modules_compileClasspath
350 def details = versionDetails()
351 gitHash = details.gitHash
352 gitBranch = details.branchName
354 println("Using a ${CHANNEL} profile.")
356 additional_compiler_args = []
357 // configure classpath/args for j8/j11 compilation
358 if (JAVA_VERSION.equals("1.8")) {
359 JAVA_INTEGER_VERSION = string("8")
362 libDistDir = j8libDir
363 compile_source_compatibility = 1.8
364 compile_target_compatibility = 1.8
365 // these are getdown.txt properties defined dependent on the JAVA_VERSION
366 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java8_min_version"))
367 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java8_max_version"))
368 // this property is assigned below and expanded to multiple lines in the getdown task
369 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java8_txt_multi_java_location"))
370 // this property is for the Java library used in eclipse
371 eclipseJavaRuntimeName = string("JavaSE-1.8")
372 } else if (JAVA_VERSION.equals("11")) {
373 JAVA_INTEGER_VERSION = string("11")
375 libDistDir = j11libDir
376 compile_source_compatibility = 11
377 compile_target_compatibility = 11
378 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
379 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
380 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
381 eclipseJavaRuntimeName = string("JavaSE-11")
382 /* compile without modules -- using classpath libraries
383 additional_compiler_args += [
384 '--module-path', modules_compileClasspath.asPath,
385 '--add-modules', j11modules
388 } else if (JAVA_VERSION.equals("12") || JAVA_VERSION.equals("13")) {
389 JAVA_INTEGER_VERSION = JAVA_VERSION
391 libDistDir = j11libDir
392 compile_source_compatibility = JAVA_VERSION
393 compile_target_compatibility = JAVA_VERSION
394 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
395 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
396 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
397 eclipseJavaRuntimeName = string("JavaSE-11")
398 /* compile without modules -- using classpath libraries
399 additional_compiler_args += [
400 '--module-path', modules_compileClasspath.asPath,
401 '--add-modules', j11modules
405 throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
410 JAVA_MIN_VERSION = JAVA_VERSION
411 JAVA_MAX_VERSION = JAVA_VERSION
412 def jreInstallsDir = string(jre_installs_dir)
413 if (jreInstallsDir.startsWith("~/")) {
414 jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1)
416 macosJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-mac-x64/jre")
417 macosJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-mac-x64.tar.gz")
418 windowsJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-windows-x64/jre")
419 windowsJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-windows-x64.tar.gz")
420 linuxJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-linux-x64/jre")
421 linuxJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-linux-x64.tar.gz")
422 install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
423 install4jConfFileName = string("jalview-install4j-conf.install4j")
424 install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
425 install4jHomeDir = install4j_home_dir
426 if (install4jHomeDir.startsWith("~/")) {
427 install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1)
432 buildingHTML = string("${jalviewDir}/${doc_dir}/building.html")
433 helpFile = string("${resourceClassesDir}/${help_dir}/help.jhm")
434 helpParentDir = string("${jalviewDir}/${help_parent_dir}")
435 helpSourceDir = string("${helpParentDir}/${help_dir}")
438 relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
439 jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
440 jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}")
442 jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
444 jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
446 jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
447 jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
448 jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
449 jalviewjsJalviewCoreHtmlFile = string("")
450 jalviewjsJalviewCoreName = string(jalviewjs_core_name)
451 jalviewjsCoreClasslists = []
452 jalviewjsJalviewTemplateName = string(jalviewjs_name)
453 jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
454 jalviewjsJ2sProps = null
455 jalviewjsJ2sPlugin = jalviewjs_j2s_plugin
457 eclipseWorkspace = null
458 eclipseBinary = string("")
459 eclipseVersion = string("")
469 outputDir = file(classesDir)
474 srcDirs += helpParentDir
477 jar.destinationDir = file("${jalviewDir}/${package_dir}")
479 compileClasspath = files(sourceSets.main.java.outputDir)
480 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
482 runtimeClasspath = compileClasspath
487 srcDirs cloverInstrDir
488 outputDir = cloverClassesDir
492 srcDirs = sourceSets.main.resources.srcDirs
495 compileClasspath = files( sourceSets.clover.java.outputDir )
496 //compileClasspath += files( testClassesDir )
497 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
498 compileClasspath += fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
499 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
501 runtimeClasspath = compileClasspath
506 srcDirs testSourceDir
507 outputDir = file(testClassesDir)
511 srcDirs = useClover ? sourceSets.clover.resources.srcDirs : sourceSets.main.resources.srcDirs
514 compileClasspath = files( sourceSets.test.java.outputDir )
515 compileClasspath += useClover ? sourceSets.clover.compileClasspath : sourceSets.main.compileClasspath
516 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
518 runtimeClasspath = compileClasspath
524 // eclipse project and settings files creation, also used by buildship
527 name = eclipse_project_name
529 natures 'org.eclipse.jdt.core.javanature',
530 'org.eclipse.jdt.groovy.core.groovyNature',
531 'org.eclipse.buildship.core.gradleprojectnature'
533 buildCommand 'org.eclipse.jdt.core.javabuilder'
534 buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
538 //defaultOutputDir = sourceSets.main.java.outputDir
541 if (it.isCanBeResolved()) {
546 minusConfigurations += removeThese
547 plusConfigurations = [ ]
551 def removeTheseToo = []
552 HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
553 cp.entries.each { entry ->
554 // This conditional removes all src classpathentries that a) have already been added or b) aren't "src" or "test".
555 // e.g. this removes the resources dir being copied into bin/main, bin/test AND bin/clover
556 // we add the resources and help/help dirs in as libs afterwards (see below)
557 if (entry.kind == 'src') {
558 if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) {
559 removeTheseToo += entry
561 alreadyAddedSrcPath.putAt(entry.path, true)
566 cp.entries.removeAll(removeTheseToo)
568 //cp.entries += new Output("${eclipse_bin_dir}/main")
569 if (file(helpParentDir).isDirectory()) {
570 cp.entries += new Library(fileReference(helpParentDir))
572 if (file(resourceDir).isDirectory()) {
573 cp.entries += new Library(fileReference(resourceDir))
576 HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
578 sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
579 //don't want to add outputDir as eclipse is using its own output dir in bin/main
580 if (it.isDirectory() || ! it.exists()) {
581 // don't add dirs to classpath, especially if they don't exist
582 return false // groovy "continue" in .any closure
584 def itPath = it.toString()
585 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
586 // make relative path
587 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
589 if (alreadyAddedLibPath.get(itPath)) {
590 //println("Not adding duplicate entry "+itPath)
592 //println("Adding entry "+itPath)
593 cp.entries += new Library(fileReference(itPath))
594 alreadyAddedLibPath.put(itPath, true)
598 sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
599 //no longer want to add outputDir as eclipse is using its own output dir in bin/main
600 if (it.isDirectory() || ! it.exists()) {
601 // don't add dirs to classpath
602 return false // groovy "continue" in .any closure
605 def itPath = it.toString()
606 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
607 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
609 if (alreadyAddedLibPath.get(itPath)) {
612 def lib = new Library(fileReference(itPath))
613 lib.entryAttributes["test"] = "true"
615 alreadyAddedLibPath.put(itPath, true)
623 containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
628 // for the IDE, use java 11 compatibility
629 sourceCompatibility = compile_source_compatibility
630 targetCompatibility = compile_target_compatibility
631 javaRuntimeName = eclipseJavaRuntimeName
633 // add in jalview project specific properties/preferences into eclipse core preferences
635 withProperties { props ->
636 def jalview_prefs = new Properties()
637 def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
638 jalview_prefs.load(ins)
640 jalview_prefs.forEach { t, v ->
641 if (props.getAt(t) == null) {
645 // codestyle file -- overrides previous formatter prefs
646 def csFile = file("${jalviewDirAbsolutePath}/${eclipse_codestyle_file}")
647 if (csFile.exists()) {
648 XmlParser parser = new XmlParser()
649 def profiles = parser.parse(csFile)
650 def profile = profiles.'profile'.find { p -> (p.'@kind' == "CodeFormatterProfile" && p.'@name' == "Jalview") }
651 if (profile != null) {
652 profile.'setting'.each { s ->
654 def value = s.'@value'
655 if (id != null && value != null) {
656 props.putAt(id, value)
667 // Don't want these to be activated if in headless build
668 synchronizationTasks "eclipseSynchronizationTask"
669 //autoBuildTasks "eclipseAutoBuildTask"
675 /* hack to change eclipse prefs in .settings files other than org.eclipse.jdt.core.prefs */
676 // Class to allow updating arbitrary properties files
677 class PropertiesFile extends PropertiesPersistableConfigurationObject {
678 public PropertiesFile(PropertiesTransformer t) { super(t); }
679 @Override protected void load(Properties properties) { }
680 @Override protected void store(Properties properties) { }
681 @Override protected String getDefaultResourceName() { return ""; }
682 // This is necessary, because PropertiesPersistableConfigurationObject fails
683 // if no default properties file exists.
684 @Override public void loadDefaults() { load(new StringBufferInputStream("")); }
687 // Task to update arbitrary properties files (set outputFile)
688 class PropertiesFileTask extends PropertiesGeneratorTask<PropertiesFile> {
689 private final PropertiesFileContentMerger file;
690 public PropertiesFileTask() { file = new PropertiesFileContentMerger(getTransformer()); }
691 protected PropertiesFile create() { return new PropertiesFile(getTransformer()); }
692 protected void configure(PropertiesFile props) {
693 file.getBeforeMerged().execute(props); file.getWhenMerged().execute(props);
695 public void file(Closure closure) { ConfigureUtil.configure(closure, file); }
698 task eclipseUIPreferences(type: PropertiesFileTask) {
699 description = "Generate Eclipse additional settings"
700 def filename = "org.eclipse.jdt.ui.prefs"
701 outputFile = "$projectDir/.settings/${filename}" as File
704 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
709 task eclipseGroovyCorePreferences(type: PropertiesFileTask) {
710 description = "Generate Eclipse additional settings"
711 def filename = "org.eclipse.jdt.groovy.core.prefs"
712 outputFile = "$projectDir/.settings/${filename}" as File
715 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
720 task eclipseAllPreferences {
722 dependsOn eclipseUIPreferences
723 dependsOn eclipseGroovyCorePreferences
726 eclipseUIPreferences.mustRunAfter eclipseJdt
727 eclipseGroovyCorePreferences.mustRunAfter eclipseJdt
729 /* end of eclipse preferences hack */
737 delete cloverBuildDir
738 delete cloverReportDir
743 task cloverInstrJava(type: JavaExec) {
744 group = "Verification"
745 description = "Create clover instrumented source java files"
747 dependsOn cleanClover
749 inputs.files(sourceSets.main.allJava)
750 outputs.dir(cloverInstrDir)
752 //classpath = fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
753 classpath = sourceSets.clover.compileClasspath
754 main = "com.atlassian.clover.CloverInstr"
762 cloverInstrDir.getPath(),
764 def srcFiles = sourceSets.main.allJava.files
767 { file -> file.absolutePath }
770 args argsList.toArray()
773 delete cloverInstrDir
774 println("Clover: About to instrument "+srcFiles.size() +" files")
779 task cloverInstrTests(type: JavaExec) {
780 group = "Verification"
781 description = "Create clover instrumented source test files"
783 dependsOn cleanClover
785 inputs.files(testDir)
786 outputs.dir(cloverTestInstrDir)
788 classpath = sourceSets.clover.compileClasspath
789 main = "com.atlassian.clover.CloverInstr"
799 cloverTestInstrDir.getPath(),
801 args argsList.toArray()
804 delete cloverTestInstrDir
805 println("Clover: About to instrument test files")
811 group = "Verification"
812 description = "Create clover instrumented all source files"
814 dependsOn cloverInstrJava
815 dependsOn cloverInstrTests
819 cloverClasses.dependsOn cloverInstr
822 task cloverConsoleReport(type: JavaExec) {
823 group = "Verification"
824 description = "Creates clover console report"
827 file(cloverDb).exists()
830 inputs.dir cloverClassesDir
832 classpath = sourceSets.clover.runtimeClasspath
833 main = "com.atlassian.clover.reporters.console.ConsoleReporter"
835 if (cloverreport_mem.length() > 0) {
836 maxHeapSize = cloverreport_mem
838 if (cloverreport_jvmargs.length() > 0) {
839 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
849 args argsList.toArray()
853 task cloverHtmlReport(type: JavaExec) {
854 group = "Verification"
855 description = "Creates clover HTML report"
858 file(cloverDb).exists()
861 def cloverHtmlDir = cloverReportDir
862 inputs.dir cloverClassesDir
863 outputs.dir cloverHtmlDir
865 classpath = sourceSets.clover.runtimeClasspath
866 main = "com.atlassian.clover.reporters.html.HtmlReporter"
868 if (cloverreport_mem.length() > 0) {
869 maxHeapSize = cloverreport_mem
871 if (cloverreport_jvmargs.length() > 0) {
872 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
883 if (cloverreport_html_options.length() > 0) {
884 argsList += cloverreport_html_options.split(" ")
887 args argsList.toArray()
891 task cloverXmlReport(type: JavaExec) {
892 group = "Verification"
893 description = "Creates clover XML report"
896 file(cloverDb).exists()
899 def cloverXmlFile = "${cloverReportDir}/clover.xml"
900 inputs.dir cloverClassesDir
901 outputs.file cloverXmlFile
903 classpath = sourceSets.clover.runtimeClasspath
904 main = "com.atlassian.clover.reporters.xml.XMLReporter"
906 if (cloverreport_mem.length() > 0) {
907 maxHeapSize = cloverreport_mem
909 if (cloverreport_jvmargs.length() > 0) {
910 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
921 if (cloverreport_xml_options.length() > 0) {
922 argsList += cloverreport_xml_options.split(" ")
925 args argsList.toArray()
930 group = "Verification"
931 description = "Creates clover reports"
933 dependsOn cloverXmlReport
934 dependsOn cloverHtmlReport
941 sourceCompatibility = compile_source_compatibility
942 targetCompatibility = compile_target_compatibility
943 options.compilerArgs += additional_compiler_args
944 print ("Setting target compatibility to "+targetCompatibility+"\n")
946 //classpath += configurations.cloverRuntime
952 // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ?
953 sourceCompatibility = compile_source_compatibility
954 targetCompatibility = compile_target_compatibility
955 options.compilerArgs = additional_compiler_args
956 options.encoding = "UTF-8"
958 print ("Setting target compatibility to "+compile_target_compatibility+"\n")
965 sourceCompatibility = compile_source_compatibility
966 targetCompatibility = compile_target_compatibility
967 options.compilerArgs = additional_compiler_args
969 print ("Setting target compatibility to "+targetCompatibility+"\n")
976 delete sourceSets.main.java.outputDir
982 dependsOn cleanClover
984 delete sourceSets.test.java.outputDir
989 // format is a string like date.format("dd MMMM yyyy")
990 def getDate(format) {
991 def date = new Date()
992 return date.format(format)
996 task createBuildProperties(type: WriteProperties) {
998 description = "Create the ${buildProperties} file"
1000 inputs.dir(sourceDir)
1001 inputs.dir(resourceDir)
1002 file(buildProperties).getParentFile().mkdirs()
1003 outputFile (buildProperties)
1004 // taking time specific comment out to allow better incremental builds
1005 comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
1006 //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
1007 property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
1008 property "VERSION", JALVIEW_VERSION
1009 property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
1010 outputs.file(outputFile)
1016 delete buildProperties
1021 task cleanBuildingHTML(type: Delete) {
1028 task convertBuildingMD(type: Exec) {
1029 dependsOn cleanBuildingHTML
1030 def buildingMD = "${jalviewDir}/${doc_dir}/building.md"
1031 def css = "${jalviewDir}/${doc_dir}/github.css"
1034 pandoc_exec.split(",").each {
1035 if (file(it.trim()).exists()) {
1041 def buildtoolsPandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
1042 if ((pandoc == null || ! file(pandoc).exists()) && file(buildtoolsPandoc).exists()) {
1043 pandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
1047 if (pandoc != null && file(pandoc).exists()) {
1048 commandLine pandoc, '-s', '-o', buildingHTML, '--metadata', 'pagetitle="Building Jalview from Source"', '--toc', '-H', css, buildingMD
1050 println("Cannot find pandoc. Skipping convert building.md to HTML")
1051 throw new StopExecutionException("Cannot find pandoc. Skipping convert building.md to HTML")
1055 ignoreExitValue true
1057 inputs.file(buildingMD)
1059 outputs.file(buildingHTML)
1063 task syncDocs(type: Sync) {
1064 //dependsOn convertBuildingMD
1065 def syncDir = "${classesDir}/${doc_dir}"
1066 from fileTree("${jalviewDir}/${doc_dir}")
1072 task copyHelp(type: Copy) {
1073 def inputDir = helpSourceDir
1074 def outputDir = "${resourceClassesDir}/${help_dir}"
1079 filter(ReplaceTokens,
1083 'Version-Rel': JALVIEW_VERSION,
1084 'Year-Rel': getDate("yyyy")
1095 inputs.dir(inputDir)
1096 outputs.files(helpFile)
1097 outputs.dir(outputDir)
1101 task syncLib(type: Sync) {
1102 def syncDir = "${resourceClassesDir}/${libDistDir}"
1103 from fileTree("${jalviewDir}/${libDistDir}")
1108 task syncResources(type: Sync) {
1109 dependsOn createBuildProperties
1112 into "${resourceClassesDir}"
1120 dependsOn syncResources
1126 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
1129 //dependsOn compileJava ////? DELETE
1132 dependsOn cloverClasses
1134 dependsOn compileJava //?
1138 includeGroups testng_groups
1139 excludeGroups testng_excluded_groups
1141 useDefaultListeners=true
1144 maxHeapSize = "1024m"
1146 workingDir = jalviewDir
1147 //systemProperties 'clover.jar' System.properties.clover.jar
1148 sourceCompatibility = compile_source_compatibility
1149 targetCompatibility = compile_target_compatibility
1150 jvmArgs += additional_compiler_args
1154 println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
1160 task buildIndices(type: JavaExec) {
1162 classpath = sourceSets.main.compileClasspath
1163 main = "com.sun.java.help.search.Indexer"
1164 workingDir = "${classesDir}/${help_dir}"
1167 inputs.dir("${workingDir}/${argDir}")
1169 outputs.dir("${classesDir}/doc")
1170 outputs.dir("${classesDir}/help")
1171 outputs.file("${workingDir}/JavaHelpSearch/DOCS")
1172 outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
1173 outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
1174 outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
1175 outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
1176 outputs.file("${workingDir}/JavaHelpSearch/TMAP")
1180 task compileLinkCheck(type: JavaCompile) {
1182 classpath = files("${jalviewDir}/${utils_dir}")
1183 destinationDir = file("${jalviewDir}/${utils_dir}")
1184 source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
1186 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1187 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1188 outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
1189 outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
1193 task linkCheck(type: JavaExec) {
1194 dependsOn prepare, compileLinkCheck
1196 def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
1197 classpath = files("${jalviewDir}/${utils_dir}")
1198 main = "HelpLinksChecker"
1199 workingDir = jalviewDir
1200 args = [ "${classesDir}/${help_dir}", "-nointernet" ]
1202 def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
1204 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1207 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1211 inputs.dir("${classesDir}/${help_dir}")
1212 outputs.file(helpLinksCheckerOutFile)
1215 // import the pubhtmlhelp target
1216 ant.properties.basedir = "${jalviewDir}"
1217 ant.properties.helpBuildDir = "${jalviewDirAbsolutePath}/${classes_dir}/${help_dir}"
1218 ant.importBuild "${utils_dir}/publishHelp.xml"
1221 task cleanPackageDir(type: Delete) {
1223 delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
1230 dependsOn buildIndices
1231 dependsOn createBuildProperties
1234 attributes "Main-Class": main_class,
1235 "Permissions": "all-permissions",
1236 "Application-Name": "Jalview Desktop",
1237 "Codebase": application_codebase
1240 destinationDir = file("${jalviewDir}/${package_dir}")
1241 archiveName = rootProject.name+".jar"
1247 exclude "**/*.jar.*"
1249 inputs.dir(classesDir)
1250 outputs.file("${jalviewDir}/${package_dir}/${archiveName}")
1254 task copyJars(type: Copy) {
1255 from fileTree(dir: classesDir, include: "**/*.jar").files
1256 into "${jalviewDir}/${package_dir}"
1260 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
1261 task syncJars(type: Sync) {
1262 from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
1263 into "${jalviewDir}/${package_dir}"
1265 include jar.archiveName
1272 description = "Put all required libraries in dist"
1273 // order of "cleanPackageDir", "copyJars", "jar" important!
1274 jar.mustRunAfter cleanPackageDir
1275 syncJars.mustRunAfter cleanPackageDir
1276 dependsOn cleanPackageDir
1279 outputs.dir("${jalviewDir}/${package_dir}")
1284 dependsOn cleanPackageDir
1290 group = "distribution"
1291 description = "Create a single jar file with all dependency libraries merged. Can be run with java -jar"
1295 from ("${jalviewDir}/${libDistDir}") {
1299 attributes 'Implementation-Version': JALVIEW_VERSION
1301 mainClassName = shadow_jar_main_class
1303 classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
1308 task getdownWebsite() {
1309 group = "distribution"
1310 description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
1315 def getdownWebsiteResourceFilenames = []
1316 def getdownTextString = ""
1317 def getdownResourceDir = getdownResourceDir
1318 def getdownResourceFilenames = []
1321 // clean the getdown website and files dir before creating getdown folders
1322 delete getdownWebsiteDir
1323 delete getdownFilesDir
1326 from buildProperties
1327 rename(build_properties_file, getdown_build_properties)
1330 getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
1332 // set some getdown_txt_ properties then go through all properties looking for getdown_txt_...
1333 def props = project.properties.sort { it.key }
1334 if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
1335 props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
1337 if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) {
1338 props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion)
1340 if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
1341 props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
1344 props.put("getdown_txt_title", jalview_name)
1345 props.put("getdown_txt_ui.name", install4jApplicationName)
1347 // start with appbase
1348 getdownTextString += "appbase = ${getdownAppBase}\n"
1349 props.each{ prop, val ->
1350 if (prop.startsWith("getdown_txt_") && val != null) {
1351 if (prop.startsWith("getdown_txt_multi_")) {
1352 def key = prop.substring(18)
1353 val.split(",").each{ v ->
1354 def line = "${key} = ${v}\n"
1355 getdownTextString += line
1358 // file values rationalised
1359 if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1361 if (val.indexOf('/') == 0) {
1364 } else if (val.indexOf('/') > 0) {
1365 // relative path (relative to jalviewDir)
1366 r = file( "${jalviewDir}/${val}" )
1369 val = "${getdown_resource_dir}/" + r.getName()
1370 getdownWebsiteResourceFilenames += val
1371 getdownResourceFilenames += r.getPath()
1374 if (! prop.startsWith("getdown_txt_resource")) {
1375 def line = prop.substring(12) + " = ${val}\n"
1376 getdownTextString += line
1382 getdownWebsiteResourceFilenames.each{ filename ->
1383 getdownTextString += "resource = ${filename}\n"
1385 getdownResourceFilenames.each{ filename ->
1388 into getdownResourceDir
1393 fileTree(file(package_dir)).each{ f ->
1394 if (f.isDirectory()) {
1395 def files = fileTree(dir: f, include: ["*"]).getFiles()
1397 } else if (f.exists()) {
1401 codeFiles.sort().each{f ->
1402 def name = f.getName()
1403 def line = "code = ${getdownAppDistDir}/${name}\n"
1404 getdownTextString += line
1411 // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
1413 if (JAVA_VERSION.equals("11")) {
1414 def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
1415 j11libFiles.sort().each{f ->
1416 def name = f.getName()
1417 def line = "code = ${getdown_j11lib_dir}/${name}\n"
1418 getdownTextString += line
1421 into getdownJ11libDir
1427 // 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.
1428 //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
1429 getdownTextString += "resource = ${getdown_launcher_new}\n"
1430 getdownTextString += "class = ${main_class}\n"
1432 def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
1433 getdown_txt.write(getdownTextString)
1435 def getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
1436 def launchJvl = file("${getdownWebsiteDir}/${getdownLaunchJvl}")
1437 launchJvl.write("appbase=${getdownAppBase}")
1440 from getdownLauncher
1441 rename(file(getdownLauncher).getName(), getdown_launcher_new)
1442 into getdownWebsiteDir
1446 from getdownLauncher
1447 if (file(getdownLauncher).getName() != getdown_launcher) {
1448 rename(file(getdownLauncher).getName(), getdown_launcher)
1450 into getdownWebsiteDir
1453 if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
1456 from getdownLauncher
1457 from "${getdownWebsiteDir}/${getdown_build_properties}"
1458 if (file(getdownLauncher).getName() != getdown_launcher) {
1459 rename(file(getdownLauncher).getName(), getdown_launcher)
1461 into getdownInstallDir
1465 from getdownInstallDir
1466 into getdownFilesInstallDir
1473 from getdownLauncher
1474 from "${getdownWebsiteDir}/${getdown_build_properties}"
1475 if (file(getdownLauncher).getName() != getdown_launcher) {
1476 rename(file(getdownLauncher).getName(), getdown_launcher)
1478 into getdownFilesDir
1482 from getdownResourceDir
1483 into "${getdownFilesDir}/${getdown_resource_dir}"
1488 inputs.dir("${jalviewDir}/${package_dir}")
1490 outputs.dir(getdownWebsiteDir)
1491 outputs.dir(getdownFilesDir)
1495 // a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
1496 task getdownDigestDir(type: JavaExec) {
1498 description "A task to run a getdown Digest on a dir with getdown.txt. Provide a DIGESTDIR property via -PDIGESTDIR=..."
1500 def digestDirPropertyName = "DIGESTDIR"
1502 classpath = files(getdownLauncher)
1503 def digestDir = findProperty(digestDirPropertyName)
1504 if (digestDir == null) {
1505 throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest")
1509 main = "com.threerings.getdown.tools.Digester"
1513 task getdownDigest(type: JavaExec) {
1514 group = "distribution"
1515 description = "Digest the getdown website folder"
1516 dependsOn getdownWebsite
1518 classpath = files(getdownLauncher)
1520 main = "com.threerings.getdown.tools.Digester"
1521 args getdownWebsiteDir
1522 inputs.dir(getdownWebsiteDir)
1523 outputs.file("${getdownWebsiteDir}/digest2.txt")
1528 group = "distribution"
1529 description = "Create the minimal and full getdown app folder for installers and website and create digest file"
1530 dependsOn getdownDigest
1532 if (reportRsyncCommand) {
1533 def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
1534 def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
1535 println "LIKELY RSYNC COMMAND:"
1536 println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
1537 if (RUNRSYNC == "true") {
1539 commandLine "mkdir", "-p", toDir
1542 commandLine "rsync", "-avh", "--delete", fromDir, toDir
1550 tasks.withType(JavaCompile) {
1551 options.encoding = 'UTF-8'
1557 delete getdownWebsiteDir
1558 delete getdownFilesDir
1564 if (file(install4jHomeDir).exists()) {
1566 } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
1567 install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1568 } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
1569 install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
1571 installDir(file(install4jHomeDir))
1573 mediaTypes = Arrays.asList(install4j_media_types.split(","))
1577 task copyInstall4jTemplate {
1578 def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
1579 def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
1580 inputs.file(install4jTemplateFile)
1581 inputs.file(install4jFileAssociationsFile)
1582 inputs.property("CHANNEL", { CHANNEL })
1583 outputs.file(install4jConfFile)
1586 def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
1588 // turn off code signing if no OSX_KEYPASS
1589 if (OSX_KEYPASS == "") {
1590 install4jConfigXml.'**'.codeSigning.each { codeSigning ->
1591 codeSigning.'@macEnabled' = "false"
1593 install4jConfigXml.'**'.windows.each { windows ->
1594 windows.'@runPostProcessor' = "false"
1598 // turn off checksum creation for LOCAL channel
1599 def e = install4jConfigXml.application[0]
1600 if (CHANNEL == "LOCAL") {
1601 e.'@createChecksums' = "false"
1603 e.'@createChecksums' = "true"
1606 // put file association actions where placeholder action is
1607 def install4jFileAssociationsText = install4jFileAssociationsFile.text
1608 def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
1609 install4jConfigXml.'**'.action.any { a -> // .any{} stops after the first one that returns true
1610 if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
1611 def parent = a.parent()
1613 fileAssociationActions.each { faa ->
1616 // don't need to continue in .any loop once replacements have been made
1621 // use Windows Program Group with Examples folder for RELEASE, and Program Group without Examples for everything else
1622 // NB we're deleting the /other/ one!
1623 // Also remove the examples subdir from non-release versions
1624 def customizedIdToDelete = "PROGRAM_GROUP_RELEASE"
1625 // 2.11.1.0 NOT releasing with the Examples folder in the Program Group
1626 if (false && CHANNEL=="RELEASE") { // remove 'false && ' to include Examples folder in RELEASE channel
1627 customizedIdToDelete = "PROGRAM_GROUP_NON_RELEASE"
1629 // remove the examples subdir from Full File Set
1630 def files = install4jConfigXml.files[0]
1631 def fileset = files.filesets.fileset.find { fs -> fs.'@customizedId' == "FULL_FILE_SET" }
1632 def root = files.roots.root.find { r -> r.'@fileset' == fileset.'@id' }
1633 def mountPoint = files.mountPoints.mountPoint.find { mp -> mp.'@root' == root.'@id' }
1634 def dirEntry = files.entries.dirEntry.find { de -> de.'@mountPoint' == mountPoint.'@id' && de.'@subDirectory' == "examples" }
1635 dirEntry.parent().remove(dirEntry)
1637 install4jConfigXml.'**'.action.any { a ->
1638 if (a.'@customizedId' == customizedIdToDelete) {
1639 def parent = a.parent()
1645 // remove the "Uninstall Old Jalview (optional)" symlink from DMG for non-release DS_Stores
1646 if (! (CHANNEL == "RELEASE" || CHANNEL == "TEST-RELEASE" ) ) {
1647 def symlink = install4jConfigXml.'**'.topLevelFiles.symlink.find { sl -> sl.'@name' == "Uninstall Old Jalview (optional).app" }
1648 symlink.parent().remove(symlink)
1651 // write install4j file
1652 install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
1659 delete install4jConfFile
1664 task installers(type: com.install4j.gradle.Install4jTask) {
1665 group = "distribution"
1666 description = "Create the install4j installers"
1668 dependsOn copyInstall4jTemplate
1670 projectFile = install4jConfFile
1672 // create an md5 for the input files to use as version for install4j conf file
1673 def digest = MessageDigest.getInstance("MD5")
1675 (file("${install4jDir}/${install4j_template}").text +
1676 file("${install4jDir}/${install4j_info_plist_file_associations}").text +
1677 file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
1678 def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
1679 if (filesMd5.length() >= 8) {
1680 filesMd5 = filesMd5.substring(0,8)
1682 def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
1683 // make install4jBuildDir relative to jalviewDir
1684 def install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
1687 'JALVIEW_NAME': jalview_name,
1688 'JALVIEW_APPLICATION_NAME': install4jApplicationName,
1689 'JALVIEW_DIR': "../..",
1690 'OSX_KEYSTORE': OSX_KEYSTORE,
1691 'JSIGN_SH': JSIGN_SH,
1692 'JRE_DIR': getdown_app_dir_java,
1693 'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
1694 'JALVIEW_VERSION': JALVIEW_VERSION,
1695 'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
1696 'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
1697 'JAVA_VERSION': JAVA_VERSION,
1698 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
1699 'VERSION': JALVIEW_VERSION,
1700 'MACOS_JAVA_VM_DIR': macosJavaVMDir,
1701 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
1702 'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
1703 'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
1704 'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
1705 'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
1706 'COPYRIGHT_MESSAGE': install4j_copyright_message,
1707 'BUNDLE_ID': install4jBundleId,
1708 'INTERNAL_ID': install4jInternalId,
1709 'WINDOWS_APPLICATION_ID': install4jWinApplicationId,
1710 'MACOS_DS_STORE': install4jDSStore,
1711 'MACOS_DMG_BG_IMAGE': install4jDMGBackgroundImage,
1712 'INSTALLER_NAME': install4jInstallerName,
1713 'INSTALL4J_UTILS_DIR': install4j_utils_dir,
1714 'GETDOWN_WEBSITE_DIR': getdown_website_dir,
1715 'GETDOWN_FILES_DIR': getdown_files_dir,
1716 'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
1717 'GETDOWN_DIST_DIR': getdownAppDistDir,
1718 'GETDOWN_ALT_DIR': getdown_app_dir_alt,
1719 'GETDOWN_INSTALL_DIR': getdown_install_dir,
1720 'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
1721 'BUILD_DIR': install4jBuildDir,
1722 'APPLICATION_CATEGORIES': install4j_application_categories,
1723 'APPLICATION_FOLDER': install4jApplicationFolder,
1724 'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder,
1725 'EXECUTABLE_NAME': install4jExecutableName,
1726 'EXTRA_SCHEME': install4jExtraScheme,
1729 //println("INSTALL4J VARIABLES:")
1730 //variables.each{k,v->println("${k}=${v}")}
1732 destination = "${jalviewDir}/${install4jBuildDir}"
1733 buildSelected = true
1735 if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
1737 disableSigning = true
1741 macKeystorePassword = OSX_KEYPASS
1745 println("Using projectFile "+projectFile)
1748 inputs.dir(getdownWebsiteDir)
1749 inputs.file(install4jConfFile)
1750 inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
1751 inputs.dir(macosJavaVMDir)
1752 inputs.dir(windowsJavaVMDir)
1753 outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
1759 eclipse().configFile(eclipse_codestyle_file)
1764 task sourceDist(type: Tar) {
1765 group "distribution"
1766 description "Create a source .tar.gz file for distribution"
1768 dependsOn convertBuildingMD
1770 def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
1771 def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
1772 // cater for buildship < 3.1 [3.0.1 is max version in eclipse 2018-09]
1774 archiveFileName = outputFileName
1775 } catch (Exception e) {
1776 archiveName = outputFileName
1779 compression Compression.GZIP
1794 "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
1796 "utils/InstallAnywhere",
1811 "gradle.properties",
1822 ".settings/org.eclipse.jdt.core.jalview.prefs",
1826 exclude (EXCLUDE_FILES)
1827 include (PROCESS_FILES)
1828 filter(ReplaceTokens,
1832 'Version-Rel': JALVIEW_VERSION,
1833 'Year-Rel': getDate("yyyy")
1838 exclude (EXCLUDE_FILES)
1839 exclude (PROCESS_FILES)
1840 exclude ("appletlib")
1841 exclude ("**/*locales")
1842 exclude ("*locales/**")
1843 exclude ("utils/InstallAnywhere")
1845 exclude (getdown_files_dir)
1846 exclude (getdown_website_dir)
1848 // exluding these as not using jars as modules yet
1849 exclude ("${j11modDir}/**/*.jar")
1852 include(INCLUDE_FILES)
1854 // from (jalviewDir) {
1855 // // explicit includes for stuff that seemed to not get included
1856 // include(fileTree("test/**/*."))
1857 // exclude(EXCLUDE_FILES)
1858 // exclude(PROCESS_FILES)
1865 dependsOn pubhtmlhelp
1867 inputs.dir("${classesDir}/${help_dir}")
1868 outputs.dir("${buildDir}/distributions/${help_dir}")
1872 task j2sSetHeadlessBuild {
1879 task jalviewjsSetEclipseWorkspace {
1880 def propKey = "jalviewjs_eclipse_workspace"
1882 if (project.hasProperty(propKey)) {
1883 propVal = project.getProperty(propKey)
1884 if (propVal.startsWith("~/")) {
1885 propVal = System.getProperty("user.home") + propVal.substring(1)
1888 def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
1889 def propsFile = file(propsFileName)
1890 def eclipseWsDir = propVal
1891 def props = new Properties()
1893 def writeProps = true
1894 if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
1895 def ins = new FileInputStream(propsFileName)
1898 if (props.getProperty(propKey, null) != null) {
1899 eclipseWsDir = props.getProperty(propKey)
1904 if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
1905 def tempDir = File.createTempDir()
1906 eclipseWsDir = tempDir.getAbsolutePath()
1909 eclipseWorkspace = file(eclipseWsDir)
1912 // do not run a headless transpile when we claim to be in Eclipse
1914 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1915 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
1917 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1921 props.setProperty(propKey, eclipseWsDir)
1922 propsFile.parentFile.mkdirs()
1923 def bytes = new ByteArrayOutputStream()
1924 props.store(bytes, null)
1925 def propertiesString = bytes.toString()
1926 propsFile.text = propertiesString
1932 println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
1935 //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
1936 outputs.file(propsFileName)
1937 outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
1941 task jalviewjsEclipsePaths {
1944 def eclipseRoot = jalviewjs_eclipse_root
1945 if (eclipseRoot.startsWith("~/")) {
1946 eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
1948 if (OperatingSystem.current().isMacOsX()) {
1949 eclipseRoot += "/Eclipse.app"
1950 eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
1951 eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
1952 } else if (OperatingSystem.current().isWindows()) { // check these paths!!
1953 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1954 eclipseRoot += "/eclipse"
1956 eclipseBinary = "${eclipseRoot}/eclipse.exe"
1957 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1958 } else { // linux or unix
1959 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1960 eclipseRoot += "/eclipse"
1961 println("eclipseDir exists")
1963 eclipseBinary = "${eclipseRoot}/eclipse"
1964 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1967 eclipseVersion = "4.13" // default
1968 def assumedVersion = true
1969 if (file(eclipseProduct).exists()) {
1970 def fis = new FileInputStream(eclipseProduct)
1971 def props = new Properties()
1973 eclipseVersion = props.getProperty("version")
1975 assumedVersion = false
1978 def propKey = "eclipse_debug"
1979 eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
1982 // do not run a headless transpile when we claim to be in Eclipse
1984 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1985 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
1987 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1990 if (!assumedVersion) {
1991 println("ECLIPSE VERSION=${eclipseVersion}")
1997 task printProperties {
1999 description "Output to console all System.properties"
2001 System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
2007 dependsOn eclipseProject
2008 dependsOn eclipseClasspath
2009 dependsOn eclipseJdt
2013 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
2014 task jalviewjsEclipseCopyDropins(type: Copy) {
2015 dependsOn jalviewjsEclipsePaths
2017 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
2018 inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
2019 def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
2026 // this eclipse -clean doesn't actually work
2027 task jalviewjsCleanEclipse(type: Exec) {
2028 dependsOn eclipseSetup
2029 dependsOn jalviewjsEclipsePaths
2030 dependsOn jalviewjsEclipseCopyDropins
2032 executable(eclipseBinary)
2033 args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
2039 def inputString = """exit
2042 def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
2043 standardInput = inputByteStream
2046 /* not really working yet
2047 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
2051 task jalviewjsTransferUnzipSwingJs {
2052 def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
2056 from zipTree(file_zip)
2057 into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2061 inputs.file file_zip
2062 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2066 task jalviewjsTransferUnzipLib {
2067 def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
2070 zipFiles.each { file_zip ->
2072 from zipTree(file_zip)
2073 into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2078 inputs.files zipFiles
2079 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2083 task jalviewjsTransferUnzipAllLibs {
2084 dependsOn jalviewjsTransferUnzipSwingJs
2085 dependsOn jalviewjsTransferUnzipLib
2089 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
2091 description "Create the .j2s file from the j2s.* properties"
2093 jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
2094 def siteDirProperty = "j2s.site.directory"
2095 def setSiteDir = false
2096 jalviewjsJ2sProps.each { prop, val ->
2098 if (prop == siteDirProperty) {
2099 if (!(val.startsWith('/') || val.startsWith("file://") )) {
2100 val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
2106 if (!setSiteDir) { // default site location, don't override specifically set property
2107 property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
2110 outputFile = jalviewjsJ2sSettingsFileName
2113 inputs.properties(jalviewjsJ2sProps)
2114 outputs.file(jalviewjsJ2sSettingsFileName)
2119 task jalviewjsEclipseSetup {
2120 dependsOn jalviewjsEclipseCopyDropins
2121 dependsOn jalviewjsSetEclipseWorkspace
2122 dependsOn jalviewjsCreateJ2sSettings
2126 task jalviewjsSyncAllLibs (type: Sync) {
2127 dependsOn jalviewjsTransferUnzipAllLibs
2128 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
2129 inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
2130 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2134 def outputFiles = []
2135 rename { filename ->
2136 outputFiles += "${outputDir}/${filename}"
2142 outputs.files outputFiles
2143 inputs.files inputFiles
2147 task jalviewjsSyncResources (type: Sync) {
2148 def inputFiles = fileTree(dir: resourceDir)
2149 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2153 def outputFiles = []
2154 rename { filename ->
2155 outputFiles += "${outputDir}/${filename}"
2161 outputs.files outputFiles
2162 inputs.files inputFiles
2166 task jalviewjsSyncSiteResources (type: Sync) {
2167 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
2168 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2172 def outputFiles = []
2173 rename { filename ->
2174 outputFiles += "${outputDir}/${filename}"
2180 outputs.files outputFiles
2181 inputs.files inputFiles
2185 task jalviewjsSyncBuildProperties (type: Sync) {
2186 dependsOn createBuildProperties
2187 def inputFiles = [file(buildProperties)]
2188 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2192 def outputFiles = []
2193 rename { filename ->
2194 outputFiles += "${outputDir}/${filename}"
2200 outputs.files outputFiles
2201 inputs.files inputFiles
2205 task jalviewjsProjectImport(type: Exec) {
2206 dependsOn eclipseSetup
2207 dependsOn jalviewjsEclipsePaths
2208 dependsOn jalviewjsEclipseSetup
2211 // do not run a headless import when we claim to be in Eclipse
2213 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2214 throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2216 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2220 //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
2221 def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
2222 executable(eclipseBinary)
2223 args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
2227 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2229 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2232 inputs.file("${jalviewDir}/.project")
2233 outputs.upToDateWhen {
2234 file(projdir).exists()
2239 task jalviewjsTranspile(type: Exec) {
2240 dependsOn jalviewjsEclipseSetup
2241 dependsOn jalviewjsProjectImport
2242 dependsOn jalviewjsEclipsePaths
2245 // do not run a headless transpile when we claim to be in Eclipse
2247 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2248 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2250 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2254 executable(eclipseBinary)
2255 args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
2259 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2261 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2267 stdout = new ByteArrayOutputStream()
2268 stderr = new ByteArrayOutputStream()
2270 def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
2271 def logOutFile = file(logOutFileName)
2272 logOutFile.createNewFile()
2273 logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
2274 BINARY: ${eclipseBinary}
2275 VERSION: ${eclipseVersion}
2276 WORKSPACE: ${eclipseWorkspace}
2277 DEBUG: ${eclipseDebug}
2280 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2281 // combine stdout and stderr
2282 def logErrFOS = logOutFOS
2284 if (jalviewjs_j2s_to_console.equals("true")) {
2285 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2286 new org.apache.tools.ant.util.TeeOutputStream(
2290 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2291 new org.apache.tools.ant.util.TeeOutputStream(
2296 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2299 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2306 if (stdout.toString().contains("Error processing ")) {
2307 // j2s did not complete transpile
2308 //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2309 if (jalviewjs_ignore_transpile_errors.equals("true")) {
2310 println("IGNORING TRANSPILE ERRORS")
2311 println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2313 throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2318 inputs.dir("${jalviewDir}/${sourceDir}")
2319 outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
2320 outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
2324 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
2326 def stdout = new ByteArrayOutputStream()
2327 def stderr = new ByteArrayOutputStream()
2329 def coreFile = file(jsfile)
2331 msg = "Creating core for ${name}...\nGenerating ${jsfile}"
2333 logOutFile.createNewFile()
2334 logOutFile.append(msg+"\n")
2336 def coreTop = file(prefixFile)
2337 def coreBottom = file(suffixFile)
2338 coreFile.getParentFile().mkdirs()
2339 coreFile.createNewFile()
2340 coreFile.write( coreTop.getText("UTF-8") )
2344 def t = f.getText("UTF-8")
2345 t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
2346 coreFile.append( t )
2348 msg = "...file '"+f.getPath()+"' does not exist, skipping"
2350 logOutFile.append(msg+"\n")
2353 coreFile.append( coreBottom.getText("UTF-8") )
2355 msg = "Generating ${zjsfile}"
2357 logOutFile.append(msg+"\n")
2358 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2359 def logErrFOS = logOutFOS
2362 classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
2363 main = "com.google.javascript.jscomp.CommandLineRunner"
2364 jvmArgs = [ "-Dfile.encoding=UTF-8" ]
2365 args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
2368 msg = "\nRunning '"+commandLine.join(' ')+"'\n"
2370 logOutFile.append(msg+"\n")
2372 if (logOutConsole) {
2373 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2374 new org.apache.tools.ant.util.TeeOutputStream(
2378 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2379 new org.apache.tools.ant.util.TeeOutputStream(
2384 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2387 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2394 logOutFile.append(msg+"\n")
2398 task jalviewjsBuildAllCores {
2400 description "Build the core js lib closures listed in the classlists dir"
2401 dependsOn jalviewjsTranspile
2402 dependsOn jalviewjsTransferUnzipSwingJs
2404 def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
2405 def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
2406 def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
2407 def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
2408 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
2409 def prefixFile = "${jsDir}/core/coretop2.js"
2410 def suffixFile = "${jsDir}/core/corebottom2.js"
2412 inputs.file prefixFile
2413 inputs.file suffixFile
2415 def classlistFiles = []
2416 // add the classlists found int the jalviewjs_classlists_dir
2417 fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
2419 def name = file.getName() - ".txt"
2426 // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
2427 //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
2428 classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
2430 jalviewjsCoreClasslists = []
2432 classlistFiles.each {
2435 def file = hash['file']
2436 if (! file.exists()) {
2437 //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
2438 return false // this is a "continue" in groovy .each closure
2440 def name = hash['name']
2442 name = file.getName() - ".txt"
2450 def list = fileTree(dir: j2sDir, includes: filelist)
2452 def jsfile = "${outputDir}/core${name}.js"
2453 def zjsfile = "${outputDir}/core${name}.z.js"
2455 jalviewjsCoreClasslists += [
2464 outputs.file(jsfile)
2465 outputs.file(zjsfile)
2468 // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
2469 def stevesoftClasslistName = "_stevesoft"
2470 def stevesoftClasslist = [
2471 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
2472 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
2473 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
2474 'name': stevesoftClasslistName
2476 jalviewjsCoreClasslists += stevesoftClasslist
2477 inputs.files(stevesoftClasslist['list'])
2478 outputs.file(stevesoftClasslist['jsfile'])
2479 outputs.file(stevesoftClasslist['zjsfile'])
2482 def allClasslistName = "_all"
2483 def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
2484 allJsFiles += fileTree(
2488 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2489 "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
2490 "**/org/jmol/export/JSExporter.js"
2493 allJsFiles += fileTree(
2497 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2498 "**/sun/misc/Unsafe.js",
2499 "**/swingjs/jquery/jquery-editable-select.js",
2500 "**/swingjs/jquery/j2sComboBox.js",
2501 "**/sun/misc/FloatingDecimal.js"
2504 def allClasslist = [
2505 'jsfile': "${outputDir}/core${allClasslistName}.js",
2506 'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
2508 'name': allClasslistName
2510 // not including this version of "all" core at the moment
2511 //jalviewjsCoreClasslists += allClasslist
2512 inputs.files(allClasslist['list'])
2513 outputs.file(allClasslist['jsfile'])
2514 outputs.file(allClasslist['zjsfile'])
2517 def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
2518 logOutFile.getParentFile().mkdirs()
2519 logOutFile.createNewFile()
2520 logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
2522 jalviewjsCoreClasslists.each {
2523 jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
2530 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
2533 into file(outputFile).getParentFile()
2534 rename { filename ->
2535 if (filename.equals(inputFile.getName())) {
2536 return file(outputFile).getName()
2540 filter(ReplaceTokens,
2544 'MAIN': '"'+main_class+'"',
2546 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
2547 'COREKEY': jalviewjs_core_key,
2548 'CORENAME': coreName
2555 task jalviewjsPublishCoreTemplates {
2556 dependsOn jalviewjsBuildAllCores
2557 def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
2558 def inputFile = file(inputFileName)
2559 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2561 def outputFiles = []
2562 jalviewjsCoreClasslists.each { cl ->
2563 def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
2564 cl['outputfile'] = outputFile
2565 outputFiles += outputFile
2569 jalviewjsCoreClasslists.each { cl ->
2570 jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
2573 inputs.file(inputFile)
2574 outputs.files(outputFiles)
2578 task jalviewjsSyncCore (type: Sync) {
2579 dependsOn jalviewjsBuildAllCores
2580 dependsOn jalviewjsPublishCoreTemplates
2581 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
2582 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2586 def outputFiles = []
2587 rename { filename ->
2588 outputFiles += "${outputDir}/${filename}"
2594 outputs.files outputFiles
2595 inputs.files inputFiles
2599 // this Copy version of TransferSiteJs will delete anything else in the target dir
2600 task jalviewjsCopyTransferSiteJs(type: Copy) {
2601 dependsOn jalviewjsTranspile
2602 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2603 into "${jalviewDir}/${jalviewjsSiteDir}"
2607 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
2608 task jalviewjsSyncTransferSiteJs(type: Sync) {
2609 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2611 into "${jalviewDir}/${jalviewjsSiteDir}"
2618 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
2619 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
2620 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
2621 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
2623 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
2624 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
2625 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
2626 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
2629 task jalviewjsPrepareSite {
2631 description "Prepares the website folder including unzipping files and copying resources"
2632 dependsOn jalviewjsSyncAllLibs
2633 dependsOn jalviewjsSyncResources
2634 dependsOn jalviewjsSyncSiteResources
2635 dependsOn jalviewjsSyncBuildProperties
2636 dependsOn jalviewjsSyncCore
2640 task jalviewjsBuildSite {
2642 description "Builds the whole website including transpiled code"
2643 dependsOn jalviewjsCopyTransferSiteJs
2644 dependsOn jalviewjsPrepareSite
2648 task cleanJalviewjsTransferSite {
2650 delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2651 delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2652 delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2653 delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2658 task cleanJalviewjsSite {
2659 dependsOn cleanJalviewjsTransferSite
2661 delete "${jalviewDir}/${jalviewjsSiteDir}"
2666 task jalviewjsSiteTar(type: Tar) {
2668 description "Creates a tar.gz file for the website"
2669 dependsOn jalviewjsBuildSite
2670 def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
2672 archiveFileName = outputFilename
2673 } catch (Exception e) {
2674 archiveName = outputFilename
2677 compression Compression.GZIP
2679 from "${jalviewDir}/${jalviewjsSiteDir}"
2680 into jalviewjs_site_dir // this is inside the tar file
2682 inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
2686 task jalviewjsServer {
2688 def filename = "jalviewjsTest.html"
2689 description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
2690 def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
2693 SimpleHttpFileServerFactory factory = new SimpleHttpFileServerFactory()
2694 def port = Integer.valueOf(jalviewjs_server_port)
2699 while(port < start+1000 && !running) {
2701 def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
2702 jalviewjsServer = factory.start(doc_root, port)
2704 url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
2705 println("SERVER STARTED with document root ${doc_root}.")
2706 println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).")
2707 println("For debug: "+url+"?j2sdebug")
2708 println("For verbose: "+url+"?j2sverbose")
2709 } catch (Exception e) {
2714 <p><a href="${url}">JalviewJS Test. <${url}></a></p>
2715 <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
2716 <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
2718 jalviewjsCoreClasslists.each { cl ->
2719 def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
2721 <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></a></p>
2723 println("For core ${cl.name}: "+urlcore)
2726 file(htmlFile).text = htmlText
2729 outputs.file(htmlFile)
2730 outputs.upToDateWhen({false})
2734 task cleanJalviewjsAll {
2736 description "Delete all configuration and build artifacts to do with JalviewJS build"
2737 dependsOn cleanJalviewjsSite
2738 dependsOn jalviewjsEclipsePaths
2741 delete "${jalviewDir}/${jalviewjsBuildDir}"
2742 delete "${jalviewDir}/${eclipse_bin_dir}"
2743 if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
2744 delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
2746 delete "${jalviewDir}/${jalviewjs_j2s_settings}"
2749 outputs.upToDateWhen( { false } )
2753 task jalviewjsIDE_checkJ2sPlugin {
2754 group "00 JalviewJS in Eclipse"
2755 description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
2758 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
2759 def j2sPluginFile = file(j2sPlugin)
2760 def eclipseHome = System.properties["eclipse.home.location"]
2761 if (eclipseHome == null || ! IN_ECLIPSE) {
2762 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
2764 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
2765 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
2766 if (!eclipseJ2sPluginFile.exists()) {
2767 def msg = "Eclipse J2S Plugin is not installed (could not find '${eclipseJ2sPlugin}')\nTry running task jalviewjsIDE_copyJ2sPlugin"
2768 System.err.println(msg)
2769 throw new StopExecutionException(msg)
2772 def digest = MessageDigest.getInstance("MD5")
2774 digest.update(j2sPluginFile.text.bytes)
2775 def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
2777 digest.update(eclipseJ2sPluginFile.text.bytes)
2778 def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
2780 if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
2781 def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
2782 System.err.println(msg)
2783 throw new StopExecutionException(msg)
2785 def msg = "Eclipse J2S Plugin is the same as '${j2sPlugin}' (this is good)"
2791 task jalviewjsIDE_copyJ2sPlugin {
2792 group "00 JalviewJS in Eclipse"
2793 description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
2796 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
2797 def j2sPluginFile = file(j2sPlugin)
2798 def eclipseHome = System.properties["eclipse.home.location"]
2799 if (eclipseHome == null || ! IN_ECLIPSE) {
2800 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
2802 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
2803 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
2804 def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
2805 System.err.println(msg)
2808 eclipseJ2sPluginFile.getParentFile().mkdirs()
2809 into eclipseJ2sPluginFile.getParent()
2815 task jalviewjsIDE_j2sFile {
2816 group "00 JalviewJS in Eclipse"
2817 description "Creates the .j2s file"
2818 dependsOn jalviewjsCreateJ2sSettings
2822 task jalviewjsIDE_SyncCore {
2823 group "00 JalviewJS in Eclipse"
2824 description "Build the core js lib closures listed in the classlists dir and publish core html from template"
2825 dependsOn jalviewjsSyncCore
2829 task jalviewjsIDE_SyncSiteAll {
2830 dependsOn jalviewjsSyncAllLibs
2831 dependsOn jalviewjsSyncResources
2832 dependsOn jalviewjsSyncSiteResources
2833 dependsOn jalviewjsSyncBuildProperties
2837 cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
2840 task jalviewjsIDE_PrepareSite {
2841 group "00 JalviewJS in Eclipse"
2842 description "Sync libs and resources to site dir, but not closure cores"
2844 dependsOn jalviewjsIDE_SyncSiteAll
2845 //dependsOn cleanJalviewjsTransferSite // not sure why this clean is here -- will slow down a re-run of this task
2849 task jalviewjsIDE_AssembleSite {
2850 group "00 JalviewJS in Eclipse"
2851 description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
2852 dependsOn jalviewjsPrepareSite
2856 task jalviewjsIDE_SiteClean {
2857 group "00 JalviewJS in Eclipse"
2858 description "Deletes the Eclipse transpiled site"
2859 dependsOn cleanJalviewjsSite
2863 task jalviewjsIDE_Server {
2864 group "00 JalviewJS in Eclipse"
2865 description "Starts a webserver on localhost to test the website"
2866 dependsOn jalviewjsServer
2870 // buildship runs this at import or gradle refresh
2871 task eclipseSynchronizationTask {
2872 //dependsOn eclipseSetup
2873 dependsOn createBuildProperties
2875 dependsOn jalviewjsIDE_j2sFile
2876 dependsOn jalviewjsIDE_checkJ2sPlugin
2877 dependsOn jalviewjsIDE_PrepareSite
2882 // buildship runs this at build time or project refresh
2883 task eclipseAutoBuildTask {
2884 //dependsOn jalviewjsIDE_checkJ2sPlugin
2885 //dependsOn jalviewjsIDE_PrepareSite
2891 description "Build the site"
2892 dependsOn jalviewjsBuildSite