1 import org.apache.tools.ant.filters.ReplaceTokens
2 import org.gradle.internal.os.OperatingSystem
3 import org.gradle.plugins.ide.internal.generator.PropertiesPersistableConfigurationObject
4 import org.gradle.api.internal.PropertiesTransformer
5 import org.gradle.util.ConfigureUtil
6 import org.gradle.plugins.ide.eclipse.model.Output
7 import org.gradle.plugins.ide.eclipse.model.Library
8 import java.security.MessageDigest
9 import groovy.transform.ExternalizeMethods
10 import groovy.util.XmlParser
11 import groovy.xml.XmlUtil
26 id "com.diffplug.gradle.spotless" version "3.28.0"
27 id 'com.github.johnrengelman.shadow' version '4.0.3'
28 id 'com.install4j.gradle' version '8.0.4'
29 id 'com.dorongold.task-tree' version '1.5' // only needed to display task dependency tree with gradle task1 [task2 ...] taskTree
39 // in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use
40 def string(Object o) {
41 return o == null ? "" : o.toString()
46 jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
47 jalviewDirRelativePath = jalviewDir
49 // local build environment properties
50 // can be "projectDir/local.properties"
51 def localProps = "${projectDir}/local.properties"
53 if (file(localProps).exists()) {
54 propsFile = localProps
56 // or "../projectDir_local.properties"
57 def dirLocalProps = projectDir.getParent() + "/" + projectDir.getName() + "_local.properties"
58 if (file(dirLocalProps).exists()) {
59 propsFile = dirLocalProps
61 if (propsFile != null) {
63 def p = new Properties()
64 def localPropsFIS = new FileInputStream(propsFile)
69 def oldval = findProperty(key)
72 println("Overriding property '${key}' ('${oldval}') with ${file(propsFile).getName()} value '${val}'")
74 println("Setting unknown property '${key}' with ${file(propsFile).getName()}s value '${val}'")
77 } catch (Exception e) {
78 System.out.println("Exception reading local.properties")
83 // Import releaseProps from the RELEASE file
84 // or a file specified via JALVIEW_RELEASE_FILE if defined
85 // Expect jalview.version and target release branch in jalview.release
86 def releaseProps = new Properties();
87 def releasePropFile = findProperty("JALVIEW_RELEASE_FILE");
88 def defaultReleasePropFile = "${jalviewDirAbsolutePath}/RELEASE";
90 (new File(releasePropFile!=null ? releasePropFile : defaultReleasePropFile)).withInputStream {
93 } catch (Exception fileLoadError) {
94 throw new Error("Couldn't load release properties file "+(releasePropFile==null ? defaultReleasePropFile : "from custom location: releasePropFile"),fileLoadError);
97 // Set JALVIEW_VERSION if it is not already set
98 if (findProperty(JALVIEW_VERSION)==null || "".equals(JALVIEW_VERSION)) {
99 JALVIEW_VERSION = releaseProps.get("jalview.version")
102 // this property set when running Eclipse headlessly
103 j2sHeadlessBuildProperty = string("net.sf.j2s.core.headlessbuild")
104 // this property set by Eclipse
105 eclipseApplicationProperty = string("eclipse.application")
106 // CHECK IF RUNNING FROM WITHIN ECLIPSE
107 def eclipseApplicationPropertyVal = System.properties[eclipseApplicationProperty]
108 IN_ECLIPSE = eclipseApplicationPropertyVal != null && eclipseApplicationPropertyVal.startsWith("org.eclipse.ui.")
109 // BUT WITHOUT THE HEADLESS BUILD PROPERTY SET
110 if (System.properties[j2sHeadlessBuildProperty].equals("true")) {
111 println("Setting IN_ECLIPSE to ${IN_ECLIPSE} as System.properties['${j2sHeadlessBuildProperty}'] == '${System.properties[j2sHeadlessBuildProperty]}'")
115 println("WITHIN ECLIPSE IDE")
117 println("HEADLESS BUILD")
120 J2S_ENABLED = (project.hasProperty('j2s.compiler.status') && project['j2s.compiler.status'] != null && project['j2s.compiler.status'] == "enable")
122 println("J2S ENABLED")
125 System.properties.sort { it.key }.each {
126 key, val -> println("SYSTEM PROPERTY ${key}='${val}'")
129 if (false && IN_ECLIPSE) {
130 jalviewDir = jalviewDirAbsolutePath
135 bareSourceDir = string(source_dir)
136 sourceDir = string("${jalviewDir}/${bareSourceDir}")
137 resourceDir = string("${jalviewDir}/${resource_dir}")
138 bareTestSourceDir = string(test_source_dir)
139 testDir = string("${jalviewDir}/${bareTestSourceDir}")
141 classesDir = string("${jalviewDir}/${classes_dir}")
144 useClover = clover.equals("true")
145 cloverBuildDir = "${buildDir}/clover"
146 cloverInstrDir = file("${cloverBuildDir}/clover-instr")
147 cloverClassesDir = file("${cloverBuildDir}/clover-classes")
148 cloverReportDir = file("${buildDir}/reports")
149 cloverTestInstrDir = file("${cloverBuildDir}/clover-test-instr")
150 cloverTestClassesDir = file("${cloverBuildDir}/clover-test-classes")
151 //cloverTestClassesDir = cloverClassesDir
152 cloverDb = string("${cloverBuildDir}/clover.db")
154 resourceClassesDir = useClover ? cloverClassesDir : classesDir
156 testSourceDir = useClover ? cloverTestInstrDir : testDir
157 testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}"
159 getdownWebsiteDir = string("${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}")
162 // the following values might be overridden by the CHANNEL switch
163 getdownChannelName = CHANNEL.toLowerCase()
164 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
165 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
166 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
167 getdownAppDistDir = getdown_app_dir_alt
168 buildProperties = string("${resourceDir}/${build_properties_file}")
169 reportRsyncCommand = false
170 jvlChannelName = CHANNEL.toLowerCase()
171 install4jSuffix = CHANNEL.substring(0, 1).toUpperCase() + CHANNEL.substring(1).toLowerCase(); // BUILD -> Build
172 install4jDSStore = "DS_Store-NON-RELEASE"
173 install4jDMGBackgroundImage = "jalview_dmg_background-NON-RELEASE.png"
174 install4jInstallerName = "${jalview_name} Non-Release Installer"
175 install4jExecutableName = jalview_name.replaceAll("[^\\w]+", "_").toLowerCase()
176 install4jExtraScheme = "jalviewx"
180 // TODO: get bamboo build artifact URL for getdown artifacts
181 getdown_channel_base = bamboo_channelbase
182 getdownChannelName = string("${bamboo_planKey}/${JAVA_VERSION}")
183 getdownAppBase = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
184 jvlChannelName += "_${getdownChannelName}"
185 // automatically add the test group Not-bamboo for exclusion
186 if ("".equals(testng_excluded_groups)) {
187 testng_excluded_groups = "Not-bamboo"
189 install4jExtraScheme = "jalviewb"
193 getdownAppDistDir = getdown_app_dir_release
194 reportRsyncCommand = true
196 install4jDSStore = "DS_Store"
197 install4jDMGBackgroundImage = "jalview_dmg_background.png"
198 install4jInstallerName = "${jalview_name} Installer"
202 getdownChannelName = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
203 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
204 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
205 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
206 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
208 package_dir = string("${ARCHIVEDIR}/${package_dir}")
209 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
212 reportRsyncCommand = true
213 install4jExtraScheme = "jalviewa"
217 getdownChannelName = string("archive/${JALVIEW_VERSION}")
218 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
219 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
220 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
221 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
223 package_dir = string("${ARCHIVEDIR}/${package_dir}")
224 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
227 reportRsyncCommand = true
228 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
229 install4jSuffix = "Archive"
230 install4jExtraScheme = "jalviewa"
234 reportRsyncCommand = true
236 // DEVELOP-RELEASE is usually associated with a Jalview release series so set the version
237 JALVIEW_VERSION=JALVIEW_VERSION+"-develop"
239 install4jSuffix = "Develop"
240 install4jDSStore = "DS_Store-DEVELOP"
241 install4jDMGBackgroundImage = "jalview_dmg_background-DEVELOP.png"
242 install4jExtraScheme = "jalviewd"
243 install4jInstallerName = "${jalview_name} Develop Installer"
247 reportRsyncCommand = true
248 // Don't ignore transpile errors for release build
249 if (jalviewjs_ignore_transpile_errors.equals("true")) {
250 jalviewjs_ignore_transpile_errors = "false"
251 println("Setting jalviewjs_ignore_transpile_errors to 'false'")
253 JALVIEW_VERSION = JALVIEW_VERSION+"-test"
254 install4jSuffix = "Test"
255 install4jDSStore = "DS_Store-TEST-RELEASE"
256 install4jDMGBackgroundImage = "jalview_dmg_background-TEST.png"
257 install4jExtraScheme = "jalviewt"
258 install4jInstallerName = "${jalview_name} Test Installer"
261 case ~/^SCRATCH(|-[-\w]*)$/:
262 getdownChannelName = CHANNEL
263 JALVIEW_VERSION = JALVIEW_VERSION+"-"+CHANNEL
265 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
266 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
267 reportRsyncCommand = true
268 install4jSuffix = "Scratch"
272 if (!file("${LOCALDIR}").exists()) {
273 throw new GradleException("Must provide a LOCALDIR value to produce a local distribution")
275 getdownAppBase = file(file("${LOCALDIR}").getAbsolutePath()).toURI().toString()
276 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
278 JALVIEW_VERSION = "TEST"
279 install4jSuffix = "Test-Local"
280 install4jDSStore = "DS_Store-TEST-RELEASE"
281 install4jDMGBackgroundImage = "jalview_dmg_background-TEST.png"
282 install4jExtraScheme = "jalviewt"
283 install4jInstallerName = "${jalview_name} Test Installer"
287 JALVIEW_VERSION = "TEST"
288 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
289 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
290 install4jExtraScheme = "jalviewl"
293 default: // something wrong specified
294 throw new GradleException("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
298 // override getdownAppBase if requested
299 if (findProperty("getdown_appbase_override") != null) {
300 getdownAppBase = string(getProperty("getdown_appbase_override"))
301 println("Overriding getdown appbase with '${getdownAppBase}'")
303 // sanitise file name for jalview launcher file for this channel
304 jvlChannelName = jvlChannelName.replaceAll("[^\\w\\-]+", "_")
305 // install4j application and folder names
306 if (install4jSuffix == "") {
307 install4jApplicationName = "${jalview_name}"
308 install4jBundleId = "${install4j_bundle_id}"
309 install4jWinApplicationId = install4j_release_win_application_id
311 install4jApplicationName = "${jalview_name} ${install4jSuffix}"
312 install4jBundleId = "${install4j_bundle_id}-" + install4jSuffix.toLowerCase()
313 // add int hash of install4jSuffix to the last part of the application_id
314 def id = install4j_release_win_application_id
315 def idsplitreverse = id.split("-").reverse()
316 idsplitreverse[0] = idsplitreverse[0].toInteger() + install4jSuffix.hashCode()
317 install4jWinApplicationId = idsplitreverse.reverse().join("-")
319 // sanitise folder and id names
320 // install4jApplicationFolder = e.g. "Jalview Build"
321 install4jApplicationFolder = install4jApplicationName
322 .replaceAll("[\"'~:/\\\\\\s]", "_") // replace all awkward filename chars " ' ~ : / \
323 .replaceAll("_+", "_") // collapse __
324 install4jInternalId = install4jApplicationName
326 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
327 .replaceAll("_+", "") // collapse __
328 //.replaceAll("_*-_*", "-") // collapse _-_
329 install4jUnixApplicationFolder = install4jApplicationName
331 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
332 .replaceAll("_+", "_") // collapse __
333 .replaceAll("_*-_*", "-") // collapse _-_
336 getdownAppDir = string("${getdownWebsiteDir}/${getdownAppDistDir}")
337 //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}"
338 getdownResourceDir = string("${getdownWebsiteDir}/${getdown_resource_dir}")
339 getdownInstallDir = string("${getdownWebsiteDir}/${getdown_install_dir}")
340 getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
341 getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
342 /* compile without modules -- using classpath libraries
343 modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
344 modules_runtimeClasspath = modules_compileClasspath
347 gitBranch = string("")
349 println("Using a ${CHANNEL} profile.")
351 additional_compiler_args = []
352 // configure classpath/args for j8/j11 compilation
353 if (JAVA_VERSION.equals("1.8")) {
354 JAVA_INTEGER_VERSION = string("8")
357 libDistDir = j8libDir
358 compile_source_compatibility = 1.8
359 compile_target_compatibility = 1.8
360 // these are getdown.txt properties defined dependent on the JAVA_VERSION
361 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java8_min_version"))
362 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java8_max_version"))
363 // this property is assigned below and expanded to multiple lines in the getdown task
364 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java8_txt_multi_java_location"))
365 // this property is for the Java library used in eclipse
366 eclipseJavaRuntimeName = string("JavaSE-1.8")
367 } else if (JAVA_VERSION.equals("11")) {
368 JAVA_INTEGER_VERSION = string("11")
370 libDistDir = j11libDir
371 compile_source_compatibility = 11
372 compile_target_compatibility = 11
373 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
374 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
375 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
376 eclipseJavaRuntimeName = string("JavaSE-11")
377 /* compile without modules -- using classpath libraries
378 additional_compiler_args += [
379 '--module-path', modules_compileClasspath.asPath,
380 '--add-modules', j11modules
383 } else if (JAVA_VERSION.equals("12") || JAVA_VERSION.equals("13")) {
384 JAVA_INTEGER_VERSION = JAVA_VERSION
386 libDistDir = j11libDir
387 compile_source_compatibility = JAVA_VERSION
388 compile_target_compatibility = JAVA_VERSION
389 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
390 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
391 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
392 eclipseJavaRuntimeName = string("JavaSE-11")
393 /* compile without modules -- using classpath libraries
394 additional_compiler_args += [
395 '--module-path', modules_compileClasspath.asPath,
396 '--add-modules', j11modules
400 throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
405 JAVA_MIN_VERSION = JAVA_VERSION
406 JAVA_MAX_VERSION = JAVA_VERSION
407 def jreInstallsDir = string(jre_installs_dir)
408 if (jreInstallsDir.startsWith("~/")) {
409 jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1)
411 macosJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-mac-x64/jre")
412 macosJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-mac-x64.tar.gz")
413 windowsJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-windows-x64/jre")
414 windowsJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-windows-x64.tar.gz")
415 linuxJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-linux-x64/jre")
416 linuxJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-linux-x64.tar.gz")
417 install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
418 install4jConfFileName = string("jalview-install4j-conf.install4j")
419 install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
420 install4jHomeDir = install4j_home_dir
421 if (install4jHomeDir.startsWith("~/")) {
422 install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1)
427 buildingHTML = string("${jalviewDir}/${doc_dir}/building.html")
428 helpFile = string("${resourceClassesDir}/${help_dir}/help.jhm")
429 helpParentDir = string("${jalviewDir}/${help_parent_dir}")
430 helpSourceDir = string("${helpParentDir}/${help_dir}")
433 relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
434 jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
435 jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}")
437 jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
439 jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
441 jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
442 jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
443 jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
444 jalviewjsJalviewCoreHtmlFile = string("")
445 jalviewjsJalviewCoreName = string(jalviewjs_core_name)
446 jalviewjsCoreClasslists = []
447 jalviewjsJalviewTemplateName = string(jalviewjs_name)
448 jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
449 jalviewjsJ2sProps = null
450 jalviewjsJ2sPlugin = jalviewjs_j2s_plugin
452 eclipseWorkspace = null
453 eclipseBinary = string("")
454 eclipseVersion = string("")
464 outputDir = file(classesDir)
469 srcDirs += helpParentDir
472 jar.destinationDir = file("${jalviewDir}/${package_dir}")
474 compileClasspath = files(sourceSets.main.java.outputDir)
475 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
477 runtimeClasspath = compileClasspath
482 srcDirs cloverInstrDir
483 outputDir = cloverClassesDir
487 srcDirs = sourceSets.main.resources.srcDirs
490 compileClasspath = files( sourceSets.clover.java.outputDir )
491 //compileClasspath += files( testClassesDir )
492 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
493 compileClasspath += fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
494 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
496 runtimeClasspath = compileClasspath
501 srcDirs testSourceDir
502 outputDir = file(testClassesDir)
506 srcDirs = useClover ? sourceSets.clover.resources.srcDirs : sourceSets.main.resources.srcDirs
509 compileClasspath = files( sourceSets.test.java.outputDir )
510 compileClasspath += useClover ? sourceSets.clover.compileClasspath : sourceSets.main.compileClasspath
511 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
513 runtimeClasspath = compileClasspath
519 // eclipse project and settings files creation, also used by buildship
522 name = eclipse_project_name
524 natures 'org.eclipse.jdt.core.javanature',
525 'org.eclipse.jdt.groovy.core.groovyNature',
526 'org.eclipse.buildship.core.gradleprojectnature'
528 buildCommand 'org.eclipse.jdt.core.javabuilder'
529 buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
533 //defaultOutputDir = sourceSets.main.java.outputDir
536 if (it.isCanBeResolved()) {
541 minusConfigurations += removeThese
542 plusConfigurations = [ ]
546 def removeTheseToo = []
547 HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
548 cp.entries.each { entry ->
549 // This conditional removes all src classpathentries that a) have already been added or b) aren't "src" or "test".
550 // e.g. this removes the resources dir being copied into bin/main, bin/test AND bin/clover
551 // we add the resources and help/help dirs in as libs afterwards (see below)
552 if (entry.kind == 'src') {
553 if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) {
554 removeTheseToo += entry
556 alreadyAddedSrcPath.putAt(entry.path, true)
561 cp.entries.removeAll(removeTheseToo)
563 //cp.entries += new Output("${eclipse_bin_dir}/main")
564 if (file(helpParentDir).isDirectory()) {
565 cp.entries += new Library(fileReference(helpParentDir))
567 if (file(resourceDir).isDirectory()) {
568 cp.entries += new Library(fileReference(resourceDir))
571 HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
573 sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
574 //don't want to add outputDir as eclipse is using its own output dir in bin/main
575 if (it.isDirectory() || ! it.exists()) {
576 // don't add dirs to classpath, especially if they don't exist
577 return false // groovy "continue" in .any closure
579 def itPath = it.toString()
580 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
581 // make relative path
582 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
584 if (alreadyAddedLibPath.get(itPath)) {
585 //println("Not adding duplicate entry "+itPath)
587 //println("Adding entry "+itPath)
588 cp.entries += new Library(fileReference(itPath))
589 alreadyAddedLibPath.put(itPath, true)
593 sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
594 //no longer want to add outputDir as eclipse is using its own output dir in bin/main
595 if (it.isDirectory() || ! it.exists()) {
596 // don't add dirs to classpath
597 return false // groovy "continue" in .any closure
600 def itPath = it.toString()
601 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
602 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
604 if (alreadyAddedLibPath.get(itPath)) {
607 def lib = new Library(fileReference(itPath))
608 lib.entryAttributes["test"] = "true"
610 alreadyAddedLibPath.put(itPath, true)
618 containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
623 // for the IDE, use java 11 compatibility
624 sourceCompatibility = compile_source_compatibility
625 targetCompatibility = compile_target_compatibility
626 javaRuntimeName = eclipseJavaRuntimeName
628 // add in jalview project specific properties/preferences into eclipse core preferences
630 withProperties { props ->
631 def jalview_prefs = new Properties()
632 def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
633 jalview_prefs.load(ins)
635 jalview_prefs.forEach { t, v ->
636 if (props.getAt(t) == null) {
640 // codestyle file -- overrides previous formatter prefs
641 def csFile = file("${jalviewDirAbsolutePath}/${eclipse_codestyle_file}")
642 if (csFile.exists()) {
643 XmlParser parser = new XmlParser()
644 def profiles = parser.parse(csFile)
645 def profile = profiles.'profile'.find { p -> (p.'@kind' == "CodeFormatterProfile" && p.'@name' == "Jalview") }
646 if (profile != null) {
647 profile.'setting'.each { s ->
649 def value = s.'@value'
650 if (id != null && value != null) {
651 props.putAt(id, value)
662 // Don't want these to be activated if in headless build
663 synchronizationTasks "eclipseSynchronizationTask"
664 //autoBuildTasks "eclipseAutoBuildTask"
670 /* hack to change eclipse prefs in .settings files other than org.eclipse.jdt.core.prefs */
671 // Class to allow updating arbitrary properties files
672 class PropertiesFile extends PropertiesPersistableConfigurationObject {
673 public PropertiesFile(PropertiesTransformer t) { super(t); }
674 @Override protected void load(Properties properties) { }
675 @Override protected void store(Properties properties) { }
676 @Override protected String getDefaultResourceName() { return ""; }
677 // This is necessary, because PropertiesPersistableConfigurationObject fails
678 // if no default properties file exists.
679 @Override public void loadDefaults() { load(new StringBufferInputStream("")); }
682 // Task to update arbitrary properties files (set outputFile)
683 class PropertiesFileTask extends PropertiesGeneratorTask<PropertiesFile> {
684 private final PropertiesFileContentMerger file;
685 public PropertiesFileTask() { file = new PropertiesFileContentMerger(getTransformer()); }
686 protected PropertiesFile create() { return new PropertiesFile(getTransformer()); }
687 protected void configure(PropertiesFile props) {
688 file.getBeforeMerged().execute(props); file.getWhenMerged().execute(props);
690 public void file(Closure closure) { ConfigureUtil.configure(closure, file); }
693 task eclipseUIPreferences(type: PropertiesFileTask) {
694 description = "Generate Eclipse additional settings"
695 def filename = "org.eclipse.jdt.ui.prefs"
696 outputFile = "$projectDir/.settings/${filename}" as File
699 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
704 task eclipseGroovyCorePreferences(type: PropertiesFileTask) {
705 description = "Generate Eclipse additional settings"
706 def filename = "org.eclipse.jdt.groovy.core.prefs"
707 outputFile = "$projectDir/.settings/${filename}" as File
710 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
715 task eclipseAllPreferences {
717 dependsOn eclipseUIPreferences
718 dependsOn eclipseGroovyCorePreferences
721 eclipseUIPreferences.mustRunAfter eclipseJdt
722 eclipseGroovyCorePreferences.mustRunAfter eclipseJdt
724 /* end of eclipse preferences hack */
732 delete cloverBuildDir
737 task cloverInstrJava(type: JavaExec) {
738 group = "Verification"
739 description = "Create clover instrumented source java files"
741 dependsOn cleanClover
743 inputs.files(sourceSets.main.allJava)
744 outputs.dir(cloverInstrDir)
746 //classpath = fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
747 classpath = sourceSets.clover.compileClasspath
748 main = "com.atlassian.clover.CloverInstr"
756 cloverInstrDir.getPath(),
758 def srcFiles = sourceSets.main.allJava.files
761 { file -> file.absolutePath }
764 args argsList.toArray()
767 delete cloverInstrDir
768 println("Clover: About to instrument "+srcFiles.size() +" files")
773 task cloverInstrTests(type: JavaExec) {
774 group = "Verification"
775 description = "Create clover instrumented source test files"
777 dependsOn cleanClover
779 inputs.files(testDir)
780 outputs.dir(cloverTestInstrDir)
782 classpath = sourceSets.clover.compileClasspath
783 main = "com.atlassian.clover.CloverInstr"
793 cloverTestInstrDir.getPath(),
795 args argsList.toArray()
798 delete cloverTestInstrDir
799 println("Clover: About to instrument test files")
805 group = "Verification"
806 description = "Create clover instrumented all source files"
808 dependsOn cloverInstrJava
809 dependsOn cloverInstrTests
813 cloverClasses.dependsOn cloverInstr
816 task cloverConsoleReport(type: JavaExec) {
817 group = "Verification"
818 description = "Creates clover console report"
821 file(cloverDb).exists()
824 inputs.dir cloverClassesDir
826 classpath = sourceSets.clover.runtimeClasspath
827 main = "com.atlassian.clover.reporters.console.ConsoleReporter"
829 if (cloverreport_mem.length() > 0) {
830 maxHeapSize = cloverreport_mem
832 if (cloverreport_jvmargs.length() > 0) {
833 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
843 args argsList.toArray()
847 task cloverHtmlReport(type: JavaExec) {
848 group = "Verification"
849 description = "Creates clover HTML report"
852 file(cloverDb).exists()
855 def cloverHtmlDir = "${cloverReportDir}/clover"
856 inputs.dir cloverClassesDir
857 outputs.dir cloverHtmlDir
859 classpath = sourceSets.clover.runtimeClasspath
860 main = "com.atlassian.clover.reporters.html.HtmlReporter"
862 if (cloverreport_mem.length() > 0) {
863 maxHeapSize = cloverreport_mem
865 if (cloverreport_jvmargs.length() > 0) {
866 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
877 if (cloverreport_html_options.length() > 0) {
878 argsList += cloverreport_html_options.split(" ")
881 args argsList.toArray()
885 task cloverXmlReport(type: JavaExec) {
886 group = "Verification"
887 description = "Creates clover XML report"
890 file(cloverDb).exists()
893 def cloverXmlFile = "${cloverReportDir}/clover.xml"
894 inputs.dir cloverClassesDir
895 outputs.file cloverXmlFile
897 classpath = sourceSets.clover.runtimeClasspath
898 main = "com.atlassian.clover.reporters.xml.XMLReporter"
900 if (cloverreport_mem.length() > 0) {
901 maxHeapSize = cloverreport_mem
903 if (cloverreport_jvmargs.length() > 0) {
904 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
915 if (cloverreport_xml_options.length() > 0) {
916 argsList += cloverreport_xml_options.split(" ")
919 args argsList.toArray()
924 group = "Verification"
925 description = "Creates clover reports"
927 dependsOn cloverXmlReport
928 dependsOn cloverHtmlReport
935 sourceCompatibility = compile_source_compatibility
936 targetCompatibility = compile_target_compatibility
937 options.compilerArgs += additional_compiler_args
938 print ("Setting target compatibility to "+targetCompatibility+"\n")
940 //classpath += configurations.cloverRuntime
946 // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ?
947 sourceCompatibility = compile_source_compatibility
948 targetCompatibility = compile_target_compatibility
949 options.compilerArgs = additional_compiler_args
950 options.encoding = "UTF-8"
952 print ("Setting target compatibility to "+compile_target_compatibility+"\n")
959 sourceCompatibility = compile_source_compatibility
960 targetCompatibility = compile_target_compatibility
961 options.compilerArgs = additional_compiler_args
963 print ("Setting target compatibility to "+targetCompatibility+"\n")
970 delete sourceSets.main.java.outputDir
976 dependsOn cleanClover
978 delete sourceSets.test.java.outputDir
983 // format is a string like date.format("dd MMMM yyyy")
984 def getDate(format) {
985 def date = new Date()
986 return date.format(format)
991 def hashStdOut = new ByteArrayOutputStream()
993 commandLine "git", "rev-parse", "--short", "HEAD"
994 standardOutput = hashStdOut
998 def branchStdOut = new ByteArrayOutputStream()
1000 commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
1001 standardOutput = branchStdOut
1002 ignoreExitValue true
1005 gitHash = hashStdOut.toString().trim()
1006 gitBranch = branchStdOut.toString().trim()
1008 outputs.upToDateWhen { false }
1012 task createBuildProperties(type: WriteProperties) {
1014 description = "Create the ${buildProperties} file"
1016 dependsOn setGitVals
1017 inputs.dir(sourceDir)
1018 inputs.dir(resourceDir)
1019 file(buildProperties).getParentFile().mkdirs()
1020 outputFile (buildProperties)
1021 // taking time specific comment out to allow better incremental builds
1022 comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
1023 //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
1024 property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
1025 property "VERSION", JALVIEW_VERSION
1026 property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
1027 outputs.file(outputFile)
1033 delete buildProperties
1038 task cleanBuildingHTML(type: Delete) {
1045 task convertBuildingMD(type: Exec) {
1046 dependsOn cleanBuildingHTML
1047 def buildingMD = "${jalviewDir}/${doc_dir}/building.md"
1048 def css = "${jalviewDir}/${doc_dir}/github.css"
1051 pandoc_exec.split(",").each {
1052 if (file(it.trim()).exists()) {
1058 def buildtoolsPandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
1059 if ((pandoc == null || ! file(pandoc).exists()) && file(buildtoolsPandoc).exists()) {
1060 pandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
1064 if (pandoc != null && file(pandoc).exists()) {
1065 commandLine pandoc, '-s', '-o', buildingHTML, '--metadata', 'pagetitle="Building Jalview from Source"', '--toc', '-H', css, buildingMD
1067 println("Cannot find pandoc. Skipping convert building.md to HTML")
1068 throw new StopExecutionException("Cannot find pandoc. Skipping convert building.md to HTML")
1072 ignoreExitValue true
1074 inputs.file(buildingMD)
1076 outputs.file(buildingHTML)
1080 task syncDocs(type: Sync) {
1081 dependsOn convertBuildingMD
1082 def syncDir = "${classesDir}/${doc_dir}"
1083 from fileTree("${jalviewDir}/${doc_dir}")
1089 task copyHelp(type: Copy) {
1090 def inputDir = helpSourceDir
1091 def outputDir = "${resourceClassesDir}/${help_dir}"
1096 filter(ReplaceTokens,
1100 'Version-Rel': JALVIEW_VERSION,
1101 'Year-Rel': getDate("yyyy")
1112 inputs.dir(inputDir)
1113 outputs.files(helpFile)
1114 outputs.dir(outputDir)
1118 task syncLib(type: Sync) {
1119 def syncDir = "${resourceClassesDir}/${libDistDir}"
1120 from fileTree("${jalviewDir}/${libDistDir}")
1125 task syncResources(type: Sync) {
1126 dependsOn createBuildProperties
1129 into "${resourceClassesDir}"
1137 dependsOn syncResources
1143 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
1146 //dependsOn compileJava ////? DELETE
1149 dependsOn cloverClasses
1151 dependsOn compileJava //?
1155 includeGroups testng_groups
1156 excludeGroups testng_excluded_groups
1158 useDefaultListeners=true
1161 maxHeapSize = "1024m"
1163 workingDir = jalviewDir
1164 //systemProperties 'clover.jar' System.properties.clover.jar
1165 sourceCompatibility = compile_source_compatibility
1166 targetCompatibility = compile_target_compatibility
1167 jvmArgs += additional_compiler_args
1171 println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
1177 task buildIndices(type: JavaExec) {
1179 classpath = sourceSets.main.compileClasspath
1180 main = "com.sun.java.help.search.Indexer"
1181 workingDir = "${classesDir}/${help_dir}"
1184 inputs.dir("${workingDir}/${argDir}")
1186 outputs.dir("${classesDir}/doc")
1187 outputs.dir("${classesDir}/help")
1188 outputs.file("${workingDir}/JavaHelpSearch/DOCS")
1189 outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
1190 outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
1191 outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
1192 outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
1193 outputs.file("${workingDir}/JavaHelpSearch/TMAP")
1197 task compileLinkCheck(type: JavaCompile) {
1199 classpath = files("${jalviewDir}/${utils_dir}")
1200 destinationDir = file("${jalviewDir}/${utils_dir}")
1201 source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
1203 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1204 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1205 outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
1206 outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
1210 task linkCheck(type: JavaExec) {
1211 dependsOn prepare, compileLinkCheck
1213 def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
1214 classpath = files("${jalviewDir}/${utils_dir}")
1215 main = "HelpLinksChecker"
1216 workingDir = jalviewDir
1217 args = [ "${classesDir}/${help_dir}", "-nointernet" ]
1219 def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
1221 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1224 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1228 inputs.dir("${classesDir}/${help_dir}")
1229 outputs.file(helpLinksCheckerOutFile)
1232 // import the pubhtmlhelp target
1233 ant.properties.basedir = "${jalviewDir}"
1234 ant.properties.helpBuildDir = "${jalviewDirAbsolutePath}/${classes_dir}/${help_dir}"
1235 ant.importBuild "${utils_dir}/publishHelp.xml"
1238 task cleanPackageDir(type: Delete) {
1240 delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
1247 dependsOn buildIndices
1248 dependsOn createBuildProperties
1251 attributes "Main-Class": main_class,
1252 "Permissions": "all-permissions",
1253 "Application-Name": "Jalview Desktop",
1254 "Codebase": application_codebase
1257 destinationDir = file("${jalviewDir}/${package_dir}")
1258 archiveName = rootProject.name+".jar"
1264 exclude "**/*.jar.*"
1266 inputs.dir(classesDir)
1267 outputs.file("${jalviewDir}/${package_dir}/${archiveName}")
1271 task copyJars(type: Copy) {
1272 from fileTree(dir: classesDir, include: "**/*.jar").files
1273 into "${jalviewDir}/${package_dir}"
1277 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
1278 task syncJars(type: Sync) {
1279 from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
1280 into "${jalviewDir}/${package_dir}"
1282 include jar.archiveName
1289 description = "Put all required libraries in dist"
1290 // order of "cleanPackageDir", "copyJars", "jar" important!
1291 jar.mustRunAfter cleanPackageDir
1292 syncJars.mustRunAfter cleanPackageDir
1293 dependsOn cleanPackageDir
1296 outputs.dir("${jalviewDir}/${package_dir}")
1301 dependsOn cleanPackageDir
1307 group = "distribution"
1311 from ("${jalviewDir}/${libDistDir}") {
1315 attributes 'Implementation-Version': JALVIEW_VERSION
1317 mainClassName = shadow_jar_main_class
1319 classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
1324 task getdownWebsite() {
1325 group = "distribution"
1326 description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
1331 def getdownWebsiteResourceFilenames = []
1332 def getdownTextString = ""
1333 def getdownResourceDir = getdownResourceDir
1334 def getdownResourceFilenames = []
1337 // clean the getdown website and files dir before creating getdown folders
1338 delete getdownWebsiteDir
1339 delete getdownFilesDir
1342 from buildProperties
1343 rename(build_properties_file, getdown_build_properties)
1346 getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
1348 // set some getdown_txt_ properties then go through all properties looking for getdown_txt_...
1349 def props = project.properties.sort { it.key }
1350 if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
1351 props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
1353 if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) {
1354 props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion)
1356 if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
1357 props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
1360 props.put("getdown_txt_title", jalview_name)
1361 props.put("getdown_txt_ui.name", install4jApplicationName)
1363 // start with appbase
1364 getdownTextString += "appbase = ${getdownAppBase}\n"
1365 props.each{ prop, val ->
1366 if (prop.startsWith("getdown_txt_") && val != null) {
1367 if (prop.startsWith("getdown_txt_multi_")) {
1368 def key = prop.substring(18)
1369 val.split(",").each{ v ->
1370 def line = "${key} = ${v}\n"
1371 getdownTextString += line
1374 // file values rationalised
1375 if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1377 if (val.indexOf('/') == 0) {
1380 } else if (val.indexOf('/') > 0) {
1381 // relative path (relative to jalviewDir)
1382 r = file( "${jalviewDir}/${val}" )
1385 val = "${getdown_resource_dir}/" + r.getName()
1386 getdownWebsiteResourceFilenames += val
1387 getdownResourceFilenames += r.getPath()
1390 if (! prop.startsWith("getdown_txt_resource")) {
1391 def line = prop.substring(12) + " = ${val}\n"
1392 getdownTextString += line
1398 getdownWebsiteResourceFilenames.each{ filename ->
1399 getdownTextString += "resource = ${filename}\n"
1401 getdownResourceFilenames.each{ filename ->
1404 into getdownResourceDir
1409 fileTree(file(package_dir)).each{ f ->
1410 if (f.isDirectory()) {
1411 def files = fileTree(dir: f, include: ["*"]).getFiles()
1413 } else if (f.exists()) {
1417 codeFiles.sort().each{f ->
1418 def name = f.getName()
1419 def line = "code = ${getdownAppDistDir}/${name}\n"
1420 getdownTextString += line
1427 // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
1429 if (JAVA_VERSION.equals("11")) {
1430 def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
1431 j11libFiles.sort().each{f ->
1432 def name = f.getName()
1433 def line = "code = ${getdown_j11lib_dir}/${name}\n"
1434 getdownTextString += line
1437 into getdownJ11libDir
1443 // 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.
1444 //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
1445 getdownTextString += "resource = ${getdown_launcher_new}\n"
1446 getdownTextString += "class = ${main_class}\n"
1448 def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
1449 getdown_txt.write(getdownTextString)
1451 def getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
1452 def launchJvl = file("${getdownWebsiteDir}/${getdownLaunchJvl}")
1453 launchJvl.write("appbase=${getdownAppBase}")
1456 from getdownLauncher
1457 rename(file(getdownLauncher).getName(), getdown_launcher_new)
1458 into getdownWebsiteDir
1462 from getdownLauncher
1463 if (file(getdownLauncher).getName() != getdown_launcher) {
1464 rename(file(getdownLauncher).getName(), getdown_launcher)
1466 into getdownWebsiteDir
1469 if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
1472 from getdownLauncher
1473 from "${getdownWebsiteDir}/${getdown_build_properties}"
1474 if (file(getdownLauncher).getName() != getdown_launcher) {
1475 rename(file(getdownLauncher).getName(), getdown_launcher)
1477 into getdownInstallDir
1481 from getdownInstallDir
1482 into getdownFilesInstallDir
1489 from getdownLauncher
1490 from "${getdownWebsiteDir}/${getdown_build_properties}"
1491 if (file(getdownLauncher).getName() != getdown_launcher) {
1492 rename(file(getdownLauncher).getName(), getdown_launcher)
1494 into getdownFilesDir
1498 from getdownResourceDir
1499 into "${getdownFilesDir}/${getdown_resource_dir}"
1504 inputs.dir("${jalviewDir}/${package_dir}")
1506 outputs.dir(getdownWebsiteDir)
1507 outputs.dir(getdownFilesDir)
1511 // a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
1512 task getdownDigestDir(type: JavaExec) {
1514 description "A task to run a getdown Digest on a dir with getdown.txt. Provide a DIGESTDIR property via -PDIGESTDIR=..."
1516 def digestDirPropertyName = "DIGESTDIR"
1518 classpath = files(getdownLauncher)
1519 def digestDir = findProperty(digestDirPropertyName)
1520 if (digestDir == null) {
1521 throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest")
1525 main = "com.threerings.getdown.tools.Digester"
1529 task getdownDigest(type: JavaExec) {
1530 group = "distribution"
1531 description = "Digest the getdown website folder"
1532 dependsOn getdownWebsite
1534 classpath = files(getdownLauncher)
1536 main = "com.threerings.getdown.tools.Digester"
1537 args getdownWebsiteDir
1538 inputs.dir(getdownWebsiteDir)
1539 outputs.file("${getdownWebsiteDir}/digest2.txt")
1544 group = "distribution"
1545 description = "Create the minimal and full getdown app folder for installers and website and create digest file"
1546 dependsOn getdownDigest
1548 if (reportRsyncCommand) {
1549 def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
1550 def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
1551 println "LIKELY RSYNC COMMAND:"
1552 println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
1553 if (RUNRSYNC == "true") {
1555 commandLine "mkdir", "-p", toDir
1558 commandLine "rsync", "-avh", "--delete", fromDir, toDir
1566 tasks.withType(JavaCompile) {
1567 options.encoding = 'UTF-8'
1573 delete getdownWebsiteDir
1574 delete getdownFilesDir
1580 if (file(install4jHomeDir).exists()) {
1582 } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
1583 install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1584 } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
1585 install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
1587 installDir(file(install4jHomeDir))
1589 mediaTypes = Arrays.asList(install4j_media_types.split(","))
1593 task copyInstall4jTemplate {
1594 def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
1595 def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
1596 inputs.file(install4jTemplateFile)
1597 inputs.file(install4jFileAssociationsFile)
1598 inputs.property("CHANNEL", { CHANNEL })
1599 outputs.file(install4jConfFile)
1602 def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
1604 // turn off code signing if no OSX_KEYPASS
1605 if (OSX_KEYPASS == "") {
1606 install4jConfigXml.'**'.codeSigning.each { codeSigning ->
1607 codeSigning.'@macEnabled' = "false"
1609 install4jConfigXml.'**'.windows.each { windows ->
1610 windows.'@runPostProcessor' = "false"
1614 // turn off checksum creation for LOCAL channel
1615 def e = install4jConfigXml.application[0]
1616 if (CHANNEL == "LOCAL") {
1617 e.'@createChecksums' = "false"
1619 e.'@createChecksums' = "true"
1622 // put file association actions where placeholder action is
1623 def install4jFileAssociationsText = install4jFileAssociationsFile.text
1624 def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
1625 install4jConfigXml.'**'.action.any { a -> // .any{} stops after the first one that returns true
1626 if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
1627 def parent = a.parent()
1629 fileAssociationActions.each { faa ->
1632 // don't need to continue in .any loop once replacements have been made
1637 // use Windows Program Group with Examples folder for RELEASE, and Program Group without Examples for everything else
1638 // NB we're deleting the /other/ one!
1639 // Also remove the examples subdir from non-release versions
1640 def customizedIdToDelete = "PROGRAM_GROUP_RELEASE"
1641 // 2.11.1.0 NOT releasing with the Examples folder in the Program Group
1642 if (false && CHANNEL=="RELEASE") { // remove 'false && ' to include Examples folder in RELEASE channel
1643 customizedIdToDelete = "PROGRAM_GROUP_NON_RELEASE"
1645 // remove the examples subdir from Full File Set
1646 def files = install4jConfigXml.files[0]
1647 def fileset = files.filesets.fileset.find { fs -> fs.'@customizedId' == "FULL_FILE_SET" }
1648 def root = files.roots.root.find { r -> r.'@fileset' == fileset.'@id' }
1649 def mountPoint = files.mountPoints.mountPoint.find { mp -> mp.'@root' == root.'@id' }
1650 def dirEntry = files.entries.dirEntry.find { de -> de.'@mountPoint' == mountPoint.'@id' && de.'@subDirectory' == "examples" }
1651 dirEntry.parent().remove(dirEntry)
1653 install4jConfigXml.'**'.action.any { a ->
1654 if (a.'@customizedId' == customizedIdToDelete) {
1655 def parent = a.parent()
1661 // remove the "Uninstall Old Jalview (optional)" symlink from DMG for non-release DS_Stores
1662 if (! (CHANNEL == "RELEASE" || CHANNEL == "TEST-RELEASE" ) ) {
1663 def symlink = install4jConfigXml.'**'.topLevelFiles.symlink.find { sl -> sl.'@name' == "Uninstall Old Jalview (optional).app" }
1664 symlink.parent().remove(symlink)
1667 // write install4j file
1668 install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
1675 delete install4jConfFile
1680 task installers(type: com.install4j.gradle.Install4jTask) {
1681 group = "distribution"
1682 description = "Create the install4j installers"
1683 dependsOn setGitVals
1685 dependsOn copyInstall4jTemplate
1687 projectFile = install4jConfFile
1689 // create an md5 for the input files to use as version for install4j conf file
1690 def digest = MessageDigest.getInstance("MD5")
1692 (file("${install4jDir}/${install4j_template}").text +
1693 file("${install4jDir}/${install4j_info_plist_file_associations}").text +
1694 file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
1695 def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
1696 if (filesMd5.length() >= 8) {
1697 filesMd5 = filesMd5.substring(0,8)
1699 def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
1700 // make install4jBuildDir relative to jalviewDir
1701 def install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
1704 'JALVIEW_NAME': jalview_name,
1705 'JALVIEW_APPLICATION_NAME': install4jApplicationName,
1706 'JALVIEW_DIR': "../..",
1707 'OSX_KEYSTORE': OSX_KEYSTORE,
1708 'JSIGN_SH': JSIGN_SH,
1709 'JRE_DIR': getdown_app_dir_java,
1710 'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
1711 'JALVIEW_VERSION': JALVIEW_VERSION,
1712 'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
1713 'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
1714 'JAVA_VERSION': JAVA_VERSION,
1715 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
1716 'VERSION': JALVIEW_VERSION,
1717 'MACOS_JAVA_VM_DIR': macosJavaVMDir,
1718 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
1719 'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
1720 'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
1721 'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
1722 'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
1723 'COPYRIGHT_MESSAGE': install4j_copyright_message,
1724 'BUNDLE_ID': install4jBundleId,
1725 'INTERNAL_ID': install4jInternalId,
1726 'WINDOWS_APPLICATION_ID': install4jWinApplicationId,
1727 'MACOS_DS_STORE': install4jDSStore,
1728 'MACOS_DMG_BG_IMAGE': install4jDMGBackgroundImage,
1729 'INSTALLER_NAME': install4jInstallerName,
1730 'INSTALL4J_UTILS_DIR': install4j_utils_dir,
1731 'GETDOWN_WEBSITE_DIR': getdown_website_dir,
1732 'GETDOWN_FILES_DIR': getdown_files_dir,
1733 'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
1734 'GETDOWN_DIST_DIR': getdownAppDistDir,
1735 'GETDOWN_ALT_DIR': getdown_app_dir_alt,
1736 'GETDOWN_INSTALL_DIR': getdown_install_dir,
1737 'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
1738 'BUILD_DIR': install4jBuildDir,
1739 'APPLICATION_CATEGORIES': install4j_application_categories,
1740 'APPLICATION_FOLDER': install4jApplicationFolder,
1741 'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder,
1742 'EXECUTABLE_NAME': install4jExecutableName,
1743 'EXTRA_SCHEME': install4jExtraScheme,
1746 //println("INSTALL4J VARIABLES:")
1747 //variables.each{k,v->println("${k}=${v}")}
1749 destination = "${jalviewDir}/${install4jBuildDir}"
1750 buildSelected = true
1752 if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
1754 disableSigning = true
1758 macKeystorePassword = OSX_KEYPASS
1762 println("Using projectFile "+projectFile)
1765 inputs.dir(getdownWebsiteDir)
1766 inputs.file(install4jConfFile)
1767 inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
1768 inputs.dir(macosJavaVMDir)
1769 inputs.dir(windowsJavaVMDir)
1770 outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
1776 eclipse().configFile(eclipse_codestyle_file)
1781 task sourceDist(type: Tar) {
1783 def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
1784 def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
1785 // cater for buildship < 3.1 [3.0.1 is max version in eclipse 2018-09]
1787 archiveFileName = outputFileName
1788 } catch (Exception e) {
1789 archiveName = outputFileName
1792 compression Compression.GZIP
1807 "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
1809 "utils/InstallAnywhere",
1824 "gradle.properties",
1835 ".settings/org.eclipse.jdt.core.jalview.prefs",
1839 exclude (EXCLUDE_FILES)
1840 include (PROCESS_FILES)
1841 filter(ReplaceTokens,
1845 'Version-Rel': JALVIEW_VERSION,
1846 'Year-Rel': getDate("yyyy")
1851 exclude (EXCLUDE_FILES)
1852 exclude (PROCESS_FILES)
1853 exclude ("appletlib")
1854 exclude ("**/*locales")
1855 exclude ("*locales/**")
1856 exclude ("utils/InstallAnywhere")
1858 exclude (getdown_files_dir)
1859 exclude (getdown_website_dir)
1861 // exluding these as not using jars as modules yet
1862 exclude ("${j11modDir}/**/*.jar")
1865 include(INCLUDE_FILES)
1867 // from (jalviewDir) {
1868 // // explicit includes for stuff that seemed to not get included
1869 // include(fileTree("test/**/*."))
1870 // exclude(EXCLUDE_FILES)
1871 // exclude(PROCESS_FILES)
1878 dependsOn pubhtmlhelp
1880 inputs.dir("${classesDir}/${help_dir}")
1881 outputs.dir("${buildDir}/distributions/${help_dir}")
1885 task j2sSetHeadlessBuild {
1892 task jalviewjsSetEclipseWorkspace {
1893 def propKey = "jalviewjs_eclipse_workspace"
1895 if (project.hasProperty(propKey)) {
1896 propVal = project.getProperty(propKey)
1897 if (propVal.startsWith("~/")) {
1898 propVal = System.getProperty("user.home") + propVal.substring(1)
1901 def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
1902 def propsFile = file(propsFileName)
1903 def eclipseWsDir = propVal
1904 def props = new Properties()
1906 def writeProps = true
1907 if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
1908 def ins = new FileInputStream(propsFileName)
1911 if (props.getProperty(propKey, null) != null) {
1912 eclipseWsDir = props.getProperty(propKey)
1917 if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
1918 def tempDir = File.createTempDir()
1919 eclipseWsDir = tempDir.getAbsolutePath()
1922 eclipseWorkspace = file(eclipseWsDir)
1925 // do not run a headless transpile when we claim to be in Eclipse
1927 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1928 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
1930 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1934 props.setProperty(propKey, eclipseWsDir)
1935 propsFile.parentFile.mkdirs()
1936 def bytes = new ByteArrayOutputStream()
1937 props.store(bytes, null)
1938 def propertiesString = bytes.toString()
1939 propsFile.text = propertiesString
1945 println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
1948 //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
1949 outputs.file(propsFileName)
1950 outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
1954 task jalviewjsEclipsePaths {
1957 def eclipseRoot = jalviewjs_eclipse_root
1958 if (eclipseRoot.startsWith("~/")) {
1959 eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
1961 if (OperatingSystem.current().isMacOsX()) {
1962 eclipseRoot += "/Eclipse.app"
1963 eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
1964 eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
1965 } else if (OperatingSystem.current().isWindows()) { // check these paths!!
1966 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1967 eclipseRoot += "/eclipse"
1969 eclipseBinary = "${eclipseRoot}/eclipse.exe"
1970 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1971 } else { // linux or unix
1972 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1973 eclipseRoot += "/eclipse"
1974 println("eclipseDir exists")
1976 eclipseBinary = "${eclipseRoot}/eclipse"
1977 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1980 eclipseVersion = "4.13" // default
1981 def assumedVersion = true
1982 if (file(eclipseProduct).exists()) {
1983 def fis = new FileInputStream(eclipseProduct)
1984 def props = new Properties()
1986 eclipseVersion = props.getProperty("version")
1988 assumedVersion = false
1991 def propKey = "eclipse_debug"
1992 eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
1995 // do not run a headless transpile when we claim to be in Eclipse
1997 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1998 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2000 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2003 if (!assumedVersion) {
2004 println("ECLIPSE VERSION=${eclipseVersion}")
2010 task printProperties {
2012 description "Output to console all System.properties"
2014 System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
2020 dependsOn eclipseProject
2021 dependsOn eclipseClasspath
2022 dependsOn eclipseJdt
2026 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
2027 task jalviewjsEclipseCopyDropins(type: Copy) {
2028 dependsOn jalviewjsEclipsePaths
2030 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
2031 inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
2032 def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
2039 // this eclipse -clean doesn't actually work
2040 task jalviewjsCleanEclipse(type: Exec) {
2041 dependsOn eclipseSetup
2042 dependsOn jalviewjsEclipsePaths
2043 dependsOn jalviewjsEclipseCopyDropins
2045 executable(eclipseBinary)
2046 args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
2052 def inputString = """exit
2055 def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
2056 standardInput = inputByteStream
2059 /* not really working yet
2060 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
2064 task jalviewjsTransferUnzipSwingJs {
2065 def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
2069 from zipTree(file_zip)
2070 into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2074 inputs.file file_zip
2075 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2079 task jalviewjsTransferUnzipLib {
2080 def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
2083 zipFiles.each { file_zip ->
2085 from zipTree(file_zip)
2086 into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2091 inputs.files zipFiles
2092 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2096 task jalviewjsTransferUnzipAllLibs {
2097 dependsOn jalviewjsTransferUnzipSwingJs
2098 dependsOn jalviewjsTransferUnzipLib
2102 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
2104 description "Create the .j2s file from the j2s.* properties"
2106 jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
2107 def siteDirProperty = "j2s.site.directory"
2108 def setSiteDir = false
2109 jalviewjsJ2sProps.each { prop, val ->
2111 if (prop == siteDirProperty) {
2112 if (!(val.startsWith('/') || val.startsWith("file://") )) {
2113 val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
2119 if (!setSiteDir) { // default site location, don't override specifically set property
2120 property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
2123 outputFile = jalviewjsJ2sSettingsFileName
2126 inputs.properties(jalviewjsJ2sProps)
2127 outputs.file(jalviewjsJ2sSettingsFileName)
2132 task jalviewjsEclipseSetup {
2133 dependsOn jalviewjsEclipseCopyDropins
2134 dependsOn jalviewjsSetEclipseWorkspace
2135 dependsOn jalviewjsCreateJ2sSettings
2139 task jalviewjsSyncAllLibs (type: Sync) {
2140 dependsOn jalviewjsTransferUnzipAllLibs
2141 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
2142 inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
2143 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2147 def outputFiles = []
2148 rename { filename ->
2149 outputFiles += "${outputDir}/${filename}"
2155 outputs.files outputFiles
2156 inputs.files inputFiles
2160 task jalviewjsSyncResources (type: Sync) {
2161 def inputFiles = fileTree(dir: resourceDir)
2162 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2166 def outputFiles = []
2167 rename { filename ->
2168 outputFiles += "${outputDir}/${filename}"
2174 outputs.files outputFiles
2175 inputs.files inputFiles
2179 task jalviewjsSyncSiteResources (type: Sync) {
2180 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
2181 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2185 def outputFiles = []
2186 rename { filename ->
2187 outputFiles += "${outputDir}/${filename}"
2193 outputs.files outputFiles
2194 inputs.files inputFiles
2198 task jalviewjsSyncBuildProperties (type: Sync) {
2199 dependsOn createBuildProperties
2200 def inputFiles = [file(buildProperties)]
2201 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2205 def outputFiles = []
2206 rename { filename ->
2207 outputFiles += "${outputDir}/${filename}"
2213 outputs.files outputFiles
2214 inputs.files inputFiles
2218 task jalviewjsProjectImport(type: Exec) {
2219 dependsOn eclipseSetup
2220 dependsOn jalviewjsEclipsePaths
2221 dependsOn jalviewjsEclipseSetup
2224 // do not run a headless import when we claim to be in Eclipse
2226 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2227 throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2229 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2233 //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
2234 def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
2235 executable(eclipseBinary)
2236 args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
2240 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2242 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2245 inputs.file("${jalviewDir}/.project")
2246 outputs.upToDateWhen {
2247 file(projdir).exists()
2252 task jalviewjsTranspile(type: Exec) {
2253 dependsOn jalviewjsEclipseSetup
2254 dependsOn jalviewjsProjectImport
2255 dependsOn jalviewjsEclipsePaths
2258 // do not run a headless transpile when we claim to be in Eclipse
2260 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2261 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2263 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2267 executable(eclipseBinary)
2268 args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
2272 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2274 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2280 stdout = new ByteArrayOutputStream()
2281 stderr = new ByteArrayOutputStream()
2283 def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
2284 def logOutFile = file(logOutFileName)
2285 logOutFile.createNewFile()
2286 logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
2287 BINARY: ${eclipseBinary}
2288 VERSION: ${eclipseVersion}
2289 WORKSPACE: ${eclipseWorkspace}
2290 DEBUG: ${eclipseDebug}
2293 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2294 // combine stdout and stderr
2295 def logErrFOS = logOutFOS
2297 if (jalviewjs_j2s_to_console.equals("true")) {
2298 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2299 new org.apache.tools.ant.util.TeeOutputStream(
2303 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2304 new org.apache.tools.ant.util.TeeOutputStream(
2309 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2312 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2319 if (stdout.toString().contains("Error processing ")) {
2320 // j2s did not complete transpile
2321 //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2322 if (jalviewjs_ignore_transpile_errors.equals("true")) {
2323 println("IGNORING TRANSPILE ERRORS")
2324 println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2326 throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2331 inputs.dir("${jalviewDir}/${sourceDir}")
2332 outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
2333 outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
2337 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
2339 def stdout = new ByteArrayOutputStream()
2340 def stderr = new ByteArrayOutputStream()
2342 def coreFile = file(jsfile)
2344 msg = "Creating core for ${name}...\nGenerating ${jsfile}"
2346 logOutFile.createNewFile()
2347 logOutFile.append(msg+"\n")
2349 def coreTop = file(prefixFile)
2350 def coreBottom = file(suffixFile)
2351 coreFile.getParentFile().mkdirs()
2352 coreFile.createNewFile()
2353 coreFile.write( coreTop.getText("UTF-8") )
2357 def t = f.getText("UTF-8")
2358 t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
2359 coreFile.append( t )
2361 msg = "...file '"+f.getPath()+"' does not exist, skipping"
2363 logOutFile.append(msg+"\n")
2366 coreFile.append( coreBottom.getText("UTF-8") )
2368 msg = "Generating ${zjsfile}"
2370 logOutFile.append(msg+"\n")
2371 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2372 def logErrFOS = logOutFOS
2375 classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
2376 main = "com.google.javascript.jscomp.CommandLineRunner"
2377 jvmArgs = [ "-Dfile.encoding=UTF-8" ]
2378 args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
2381 msg = "\nRunning '"+commandLine.join(' ')+"'\n"
2383 logOutFile.append(msg+"\n")
2385 if (logOutConsole) {
2386 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2387 new org.apache.tools.ant.util.TeeOutputStream(
2391 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2392 new org.apache.tools.ant.util.TeeOutputStream(
2397 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2400 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2407 logOutFile.append(msg+"\n")
2411 task jalviewjsBuildAllCores {
2413 description "Build the core js lib closures listed in the classlists dir"
2414 dependsOn jalviewjsTranspile
2415 dependsOn jalviewjsTransferUnzipSwingJs
2417 def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
2418 def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
2419 def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
2420 def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
2421 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
2422 def prefixFile = "${jsDir}/core/coretop2.js"
2423 def suffixFile = "${jsDir}/core/corebottom2.js"
2425 inputs.file prefixFile
2426 inputs.file suffixFile
2428 def classlistFiles = []
2429 // add the classlists found int the jalviewjs_classlists_dir
2430 fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
2432 def name = file.getName() - ".txt"
2439 // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
2440 //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
2441 classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
2443 jalviewjsCoreClasslists = []
2445 classlistFiles.each {
2448 def file = hash['file']
2449 if (! file.exists()) {
2450 //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
2451 return false // this is a "continue" in groovy .each closure
2453 def name = hash['name']
2455 name = file.getName() - ".txt"
2463 def list = fileTree(dir: j2sDir, includes: filelist)
2465 def jsfile = "${outputDir}/core${name}.js"
2466 def zjsfile = "${outputDir}/core${name}.z.js"
2468 jalviewjsCoreClasslists += [
2477 outputs.file(jsfile)
2478 outputs.file(zjsfile)
2481 // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
2482 def stevesoftClasslistName = "_stevesoft"
2483 def stevesoftClasslist = [
2484 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
2485 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
2486 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
2487 'name': stevesoftClasslistName
2489 jalviewjsCoreClasslists += stevesoftClasslist
2490 inputs.files(stevesoftClasslist['list'])
2491 outputs.file(stevesoftClasslist['jsfile'])
2492 outputs.file(stevesoftClasslist['zjsfile'])
2495 def allClasslistName = "_all"
2496 def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
2497 allJsFiles += fileTree(
2501 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2502 "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
2503 "**/org/jmol/export/JSExporter.js"
2506 allJsFiles += fileTree(
2510 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2511 "**/sun/misc/Unsafe.js",
2512 "**/swingjs/jquery/jquery-editable-select.js",
2513 "**/swingjs/jquery/j2sComboBox.js",
2514 "**/sun/misc/FloatingDecimal.js"
2517 def allClasslist = [
2518 'jsfile': "${outputDir}/core${allClasslistName}.js",
2519 'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
2521 'name': allClasslistName
2523 // not including this version of "all" core at the moment
2524 //jalviewjsCoreClasslists += allClasslist
2525 inputs.files(allClasslist['list'])
2526 outputs.file(allClasslist['jsfile'])
2527 outputs.file(allClasslist['zjsfile'])
2530 def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
2531 logOutFile.getParentFile().mkdirs()
2532 logOutFile.createNewFile()
2533 logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
2535 jalviewjsCoreClasslists.each {
2536 jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
2543 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
2546 into file(outputFile).getParentFile()
2547 rename { filename ->
2548 if (filename.equals(inputFile.getName())) {
2549 return file(outputFile).getName()
2553 filter(ReplaceTokens,
2557 'MAIN': '"'+main_class+'"',
2559 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
2560 'COREKEY': jalviewjs_core_key,
2561 'CORENAME': coreName
2568 task jalviewjsPublishCoreTemplates {
2569 dependsOn jalviewjsBuildAllCores
2570 def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
2571 def inputFile = file(inputFileName)
2572 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2574 def outputFiles = []
2575 jalviewjsCoreClasslists.each { cl ->
2576 def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
2577 cl['outputfile'] = outputFile
2578 outputFiles += outputFile
2582 jalviewjsCoreClasslists.each { cl ->
2583 jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
2586 inputs.file(inputFile)
2587 outputs.files(outputFiles)
2591 task jalviewjsSyncCore (type: Sync) {
2592 dependsOn jalviewjsBuildAllCores
2593 dependsOn jalviewjsPublishCoreTemplates
2594 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
2595 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2599 def outputFiles = []
2600 rename { filename ->
2601 outputFiles += "${outputDir}/${filename}"
2607 outputs.files outputFiles
2608 inputs.files inputFiles
2612 // this Copy version of TransferSiteJs will delete anything else in the target dir
2613 task jalviewjsCopyTransferSiteJs(type: Copy) {
2614 dependsOn jalviewjsTranspile
2615 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2616 into "${jalviewDir}/${jalviewjsSiteDir}"
2620 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
2621 task jalviewjsSyncTransferSiteJs(type: Sync) {
2622 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2624 into "${jalviewDir}/${jalviewjsSiteDir}"
2631 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
2632 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
2633 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
2634 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
2636 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
2637 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
2638 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
2639 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
2642 task jalviewjsPrepareSite {
2644 description "Prepares the website folder including unzipping files and copying resources"
2645 dependsOn jalviewjsSyncAllLibs
2646 dependsOn jalviewjsSyncResources
2647 dependsOn jalviewjsSyncSiteResources
2648 dependsOn jalviewjsSyncBuildProperties
2649 dependsOn jalviewjsSyncCore
2653 task jalviewjsBuildSite {
2655 description "Builds the whole website including transpiled code"
2656 dependsOn jalviewjsCopyTransferSiteJs
2657 dependsOn jalviewjsPrepareSite
2661 task cleanJalviewjsTransferSite {
2663 delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2664 delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2665 delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2666 delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2671 task cleanJalviewjsSite {
2672 dependsOn cleanJalviewjsTransferSite
2674 delete "${jalviewDir}/${jalviewjsSiteDir}"
2679 task jalviewjsSiteTar(type: Tar) {
2681 description "Creates a tar.gz file for the website"
2682 dependsOn jalviewjsBuildSite
2683 def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
2685 archiveFileName = outputFilename
2686 } catch (Exception e) {
2687 archiveName = outputFilename
2690 compression Compression.GZIP
2692 from "${jalviewDir}/${jalviewjsSiteDir}"
2693 into jalviewjs_site_dir // this is inside the tar file
2695 inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
2699 task jalviewjsServer {
2701 def filename = "jalviewjsTest.html"
2702 description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
2703 def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
2706 SimpleHttpFileServerFactory factory = new SimpleHttpFileServerFactory()
2707 def port = Integer.valueOf(jalviewjs_server_port)
2712 while(port < start+1000 && !running) {
2714 def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
2715 jalviewjsServer = factory.start(doc_root, port)
2717 url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
2718 println("SERVER STARTED with document root ${doc_root}.")
2719 println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).")
2720 println("For debug: "+url+"?j2sdebug")
2721 println("For verbose: "+url+"?j2sverbose")
2722 } catch (Exception e) {
2727 <p><a href="${url}">JalviewJS Test. <${url}></a></p>
2728 <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
2729 <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
2731 jalviewjsCoreClasslists.each { cl ->
2732 def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
2734 <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></a></p>
2736 println("For core ${cl.name}: "+urlcore)
2739 file(htmlFile).text = htmlText
2742 outputs.file(htmlFile)
2743 outputs.upToDateWhen({false})
2747 task cleanJalviewjsAll {
2749 description "Delete all configuration and build artifacts to do with JalviewJS build"
2750 dependsOn cleanJalviewjsSite
2751 dependsOn jalviewjsEclipsePaths
2754 delete "${jalviewDir}/${jalviewjsBuildDir}"
2755 delete "${jalviewDir}/${eclipse_bin_dir}"
2756 if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
2757 delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
2759 delete "${jalviewDir}/${jalviewjs_j2s_settings}"
2762 outputs.upToDateWhen( { false } )
2766 task jalviewjsIDE_checkJ2sPlugin {
2767 group "00 JalviewJS in Eclipse"
2768 description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
2771 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
2772 def j2sPluginFile = file(j2sPlugin)
2773 def eclipseHome = System.properties["eclipse.home.location"]
2774 if (eclipseHome == null || ! IN_ECLIPSE) {
2775 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
2777 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
2778 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
2779 if (!eclipseJ2sPluginFile.exists()) {
2780 def msg = "Eclipse J2S Plugin is not installed (could not find '${eclipseJ2sPlugin}')\nTry running task jalviewjsIDE_copyJ2sPlugin"
2781 System.err.println(msg)
2782 throw new StopExecutionException(msg)
2785 def digest = MessageDigest.getInstance("MD5")
2787 digest.update(j2sPluginFile.text.bytes)
2788 def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
2790 digest.update(eclipseJ2sPluginFile.text.bytes)
2791 def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
2793 if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
2794 def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
2795 System.err.println(msg)
2796 throw new StopExecutionException(msg)
2798 def msg = "Eclipse J2S Plugin is the same as '${j2sPlugin}' (this is good)"
2804 task jalviewjsIDE_copyJ2sPlugin {
2805 group "00 JalviewJS in Eclipse"
2806 description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
2809 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
2810 def j2sPluginFile = file(j2sPlugin)
2811 def eclipseHome = System.properties["eclipse.home.location"]
2812 if (eclipseHome == null || ! IN_ECLIPSE) {
2813 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
2815 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
2816 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
2817 def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
2818 System.err.println(msg)
2821 eclipseJ2sPluginFile.getParentFile().mkdirs()
2822 into eclipseJ2sPluginFile.getParent()
2828 task jalviewjsIDE_j2sFile {
2829 group "00 JalviewJS in Eclipse"
2830 description "Creates the .j2s file"
2831 dependsOn jalviewjsCreateJ2sSettings
2835 task jalviewjsIDE_SyncCore {
2836 group "00 JalviewJS in Eclipse"
2837 description "Build the core js lib closures listed in the classlists dir and publish core html from template"
2838 dependsOn jalviewjsSyncCore
2842 task jalviewjsIDE_SyncSiteAll {
2843 dependsOn jalviewjsSyncAllLibs
2844 dependsOn jalviewjsSyncResources
2845 dependsOn jalviewjsSyncSiteResources
2846 dependsOn jalviewjsSyncBuildProperties
2850 cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
2853 task jalviewjsIDE_PrepareSite {
2854 group "00 JalviewJS in Eclipse"
2855 description "Sync libs and resources to site dir, but not closure cores"
2857 dependsOn jalviewjsIDE_SyncSiteAll
2858 dependsOn cleanJalviewjsTransferSite
2862 task jalviewjsIDE_AssembleSite {
2863 group "00 JalviewJS in Eclipse"
2864 description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
2865 dependsOn jalviewjsPrepareSite
2869 task jalviewjsIDE_SiteClean {
2870 group "00 JalviewJS in Eclipse"
2871 description "Deletes the Eclipse transpiled site"
2872 dependsOn cleanJalviewjsSite
2876 task jalviewjsIDE_Server {
2877 group "00 JalviewJS in Eclipse"
2878 description "Starts a webserver on localhost to test the website"
2879 dependsOn jalviewjsServer
2883 // buildship runs this at import or gradle refresh
2884 task eclipseSynchronizationTask {
2885 //dependsOn eclipseSetup
2886 dependsOn createBuildProperties
2888 dependsOn jalviewjsIDE_j2sFile
2889 dependsOn jalviewjsIDE_checkJ2sPlugin
2890 dependsOn jalviewjsIDE_PrepareSite
2895 // buildship runs this at build time or project refresh
2896 task eclipseAutoBuildTask {
2897 //dependsOn jalviewjsIDE_checkJ2sPlugin
2898 //dependsOn jalviewjsIDE_PrepareSite
2904 description "Build the site"
2905 dependsOn jalviewjsBuildSite