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
42 // in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use
43 def string(Object o) {
44 return o == null ? "" : o.toString()
49 jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
50 jalviewDirRelativePath = jalviewDir
52 // local build environment properties
53 // can be "projectDir/local.properties"
54 def localProps = "${projectDir}/local.properties"
56 if (file(localProps).exists()) {
57 propsFile = localProps
59 // or "../projectDir_local.properties"
60 def dirLocalProps = projectDir.getParent() + "/" + projectDir.getName() + "_local.properties"
61 if (file(dirLocalProps).exists()) {
62 propsFile = dirLocalProps
64 if (propsFile != null) {
66 def p = new Properties()
67 def localPropsFIS = new FileInputStream(propsFile)
72 def oldval = findProperty(key)
75 println("Overriding property '${key}' ('${oldval}') with ${file(propsFile).getName()} value '${val}'")
77 println("Setting unknown property '${key}' with ${file(propsFile).getName()}s value '${val}'")
80 } catch (Exception e) {
81 System.out.println("Exception reading local.properties")
86 // Import releaseProps from the RELEASE file
87 // or a file specified via JALVIEW_RELEASE_FILE if defined
88 // Expect jalview.version and target release branch in jalview.release
89 def releaseProps = new Properties();
90 def releasePropFile = findProperty("JALVIEW_RELEASE_FILE");
91 def defaultReleasePropFile = "${jalviewDirAbsolutePath}/RELEASE";
93 (new File(releasePropFile!=null ? releasePropFile : defaultReleasePropFile)).withInputStream {
96 } catch (Exception fileLoadError) {
97 throw new Error("Couldn't load release properties file "+(releasePropFile==null ? defaultReleasePropFile : "from custom location: releasePropFile"),fileLoadError);
100 // Set JALVIEW_VERSION if it is not already set
101 if (findProperty(JALVIEW_VERSION)==null || "".equals(JALVIEW_VERSION)) {
102 JALVIEW_VERSION = releaseProps.get("jalview.version")
105 // this property set when running Eclipse headlessly
106 j2sHeadlessBuildProperty = string("net.sf.j2s.core.headlessbuild")
107 // this property set by Eclipse
108 eclipseApplicationProperty = string("eclipse.application")
109 // CHECK IF RUNNING FROM WITHIN ECLIPSE
110 def eclipseApplicationPropertyVal = System.properties[eclipseApplicationProperty]
111 IN_ECLIPSE = eclipseApplicationPropertyVal != null && eclipseApplicationPropertyVal.startsWith("org.eclipse.ui.")
112 // BUT WITHOUT THE HEADLESS BUILD PROPERTY SET
113 if (System.properties[j2sHeadlessBuildProperty].equals("true")) {
114 println("Setting IN_ECLIPSE to ${IN_ECLIPSE} as System.properties['${j2sHeadlessBuildProperty}'] == '${System.properties[j2sHeadlessBuildProperty]}'")
118 println("WITHIN ECLIPSE IDE")
120 println("HEADLESS BUILD")
123 J2S_ENABLED = (project.hasProperty('j2s.compiler.status') && project['j2s.compiler.status'] != null && project['j2s.compiler.status'] == "enable")
125 println("J2S ENABLED")
128 System.properties.sort { it.key }.each {
129 key, val -> println("SYSTEM PROPERTY ${key}='${val}'")
132 if (false && IN_ECLIPSE) {
133 jalviewDir = jalviewDirAbsolutePath
138 bareSourceDir = string(source_dir)
139 sourceDir = string("${jalviewDir}/${bareSourceDir}")
140 resourceDir = string("${jalviewDir}/${resource_dir}")
141 bareTestSourceDir = string(test_source_dir)
142 testDir = string("${jalviewDir}/${bareTestSourceDir}")
144 classesDir = string("${jalviewDir}/${classes_dir}")
147 useClover = clover.equals("true")
148 cloverBuildDir = "${buildDir}/clover"
149 cloverInstrDir = file("${cloverBuildDir}/clover-instr")
150 cloverClassesDir = file("${cloverBuildDir}/clover-classes")
151 cloverReportDir = file("${buildDir}/reports/clover")
152 cloverTestInstrDir = file("${cloverBuildDir}/clover-test-instr")
153 cloverTestClassesDir = file("${cloverBuildDir}/clover-test-classes")
154 //cloverTestClassesDir = cloverClassesDir
155 cloverDb = string("${cloverBuildDir}/clover.db")
157 resourceClassesDir = useClover ? cloverClassesDir : classesDir
159 testSourceDir = useClover ? cloverTestInstrDir : testDir
160 testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}"
162 getdownWebsiteDir = string("${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}")
165 // the following values might be overridden by the CHANNEL switch
166 getdownChannelName = CHANNEL.toLowerCase()
167 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
168 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
169 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
170 getdownAppDistDir = getdown_app_dir_alt
171 buildProperties = string("${resourceDir}/${build_properties_file}")
172 reportRsyncCommand = false
173 jvlChannelName = CHANNEL.toLowerCase()
174 install4jSuffix = CHANNEL.substring(0, 1).toUpperCase() + CHANNEL.substring(1).toLowerCase(); // BUILD -> Build
175 install4jDSStore = "DS_Store-NON-RELEASE"
176 install4jDMGBackgroundImage = "jalview_dmg_background-NON-RELEASE.png"
177 install4jInstallerName = "${jalview_name} Non-Release Installer"
178 install4jExecutableName = jalview_name.replaceAll("[^\\w]+", "_").toLowerCase()
179 install4jExtraScheme = "jalviewx"
183 // TODO: get bamboo build artifact URL for getdown artifacts
184 getdown_channel_base = bamboo_channelbase
185 getdownChannelName = string("${bamboo_planKey}/${JAVA_VERSION}")
186 getdownAppBase = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
187 jvlChannelName += "_${getdownChannelName}"
188 // automatically add the test group Not-bamboo for exclusion
189 if ("".equals(testng_excluded_groups)) {
190 testng_excluded_groups = "Not-bamboo"
192 install4jExtraScheme = "jalviewb"
196 getdownAppDistDir = getdown_app_dir_release
197 reportRsyncCommand = true
199 install4jDSStore = "DS_Store"
200 install4jDMGBackgroundImage = "jalview_dmg_background.png"
201 install4jInstallerName = "${jalview_name} Installer"
205 getdownChannelName = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
206 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
207 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
208 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
209 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
211 package_dir = string("${ARCHIVEDIR}/${package_dir}")
212 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
215 reportRsyncCommand = true
216 install4jExtraScheme = "jalviewa"
220 getdownChannelName = string("archive/${JALVIEW_VERSION}")
221 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
222 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
223 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
224 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
226 package_dir = string("${ARCHIVEDIR}/${package_dir}")
227 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
230 reportRsyncCommand = true
231 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
232 install4jSuffix = "Archive"
233 install4jExtraScheme = "jalviewa"
237 reportRsyncCommand = true
239 // DEVELOP-RELEASE is usually associated with a Jalview release series so set the version
240 JALVIEW_VERSION=JALVIEW_VERSION+"-develop"
242 install4jSuffix = "Develop"
243 install4jDSStore = "DS_Store-DEVELOP"
244 install4jDMGBackgroundImage = "jalview_dmg_background-DEVELOP.png"
245 install4jExtraScheme = "jalviewd"
246 install4jInstallerName = "${jalview_name} Develop Installer"
250 reportRsyncCommand = true
251 // Don't ignore transpile errors for release build
252 if (jalviewjs_ignore_transpile_errors.equals("true")) {
253 jalviewjs_ignore_transpile_errors = "false"
254 println("Setting jalviewjs_ignore_transpile_errors to 'false'")
256 JALVIEW_VERSION = JALVIEW_VERSION+"-test"
257 install4jSuffix = "Test"
258 install4jDSStore = "DS_Store-TEST-RELEASE"
259 install4jDMGBackgroundImage = "jalview_dmg_background-TEST.png"
260 install4jExtraScheme = "jalviewt"
261 install4jInstallerName = "${jalview_name} Test Installer"
264 case ~/^SCRATCH(|-[-\w]*)$/:
265 getdownChannelName = CHANNEL
266 JALVIEW_VERSION = JALVIEW_VERSION+"-"+CHANNEL
268 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
269 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
270 reportRsyncCommand = true
271 install4jSuffix = "Scratch"
275 if (!file("${LOCALDIR}").exists()) {
276 throw new GradleException("Must provide a LOCALDIR value to produce a local distribution")
278 getdownAppBase = file(file("${LOCALDIR}").getAbsolutePath()).toURI().toString()
279 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
281 JALVIEW_VERSION = "TEST"
282 install4jSuffix = "Test-Local"
283 install4jDSStore = "DS_Store-TEST-RELEASE"
284 install4jDMGBackgroundImage = "jalview_dmg_background-TEST.png"
285 install4jExtraScheme = "jalviewt"
286 install4jInstallerName = "${jalview_name} Test Installer"
290 JALVIEW_VERSION = "TEST"
291 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
292 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
293 install4jExtraScheme = "jalviewl"
296 default: // something wrong specified
297 throw new GradleException("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
301 // override getdownAppBase if requested
302 if (findProperty("getdown_appbase_override") != null) {
303 getdownAppBase = string(getProperty("getdown_appbase_override"))
304 println("Overriding getdown appbase with '${getdownAppBase}'")
306 // sanitise file name for jalview launcher file for this channel
307 jvlChannelName = jvlChannelName.replaceAll("[^\\w\\-]+", "_")
308 // install4j application and folder names
309 if (install4jSuffix == "") {
310 install4jApplicationName = "${jalview_name}"
311 install4jBundleId = "${install4j_bundle_id}"
312 install4jWinApplicationId = install4j_release_win_application_id
314 install4jApplicationName = "${jalview_name} ${install4jSuffix}"
315 install4jBundleId = "${install4j_bundle_id}-" + install4jSuffix.toLowerCase()
316 // add int hash of install4jSuffix to the last part of the application_id
317 def id = install4j_release_win_application_id
318 def idsplitreverse = id.split("-").reverse()
319 idsplitreverse[0] = idsplitreverse[0].toInteger() + install4jSuffix.hashCode()
320 install4jWinApplicationId = idsplitreverse.reverse().join("-")
322 // sanitise folder and id names
323 // install4jApplicationFolder = e.g. "Jalview Build"
324 install4jApplicationFolder = install4jApplicationName
325 .replaceAll("[\"'~:/\\\\\\s]", "_") // replace all awkward filename chars " ' ~ : / \
326 .replaceAll("_+", "_") // collapse __
327 install4jInternalId = install4jApplicationName
329 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
330 .replaceAll("_+", "") // collapse __
331 //.replaceAll("_*-_*", "-") // collapse _-_
332 install4jUnixApplicationFolder = install4jApplicationName
334 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
335 .replaceAll("_+", "_") // collapse __
336 .replaceAll("_*-_*", "-") // collapse _-_
339 getdownAppDir = string("${getdownWebsiteDir}/${getdownAppDistDir}")
340 //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}"
341 getdownResourceDir = string("${getdownWebsiteDir}/${getdown_resource_dir}")
342 getdownInstallDir = string("${getdownWebsiteDir}/${getdown_install_dir}")
343 getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
344 getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
345 /* compile without modules -- using classpath libraries
346 modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
347 modules_runtimeClasspath = modules_compileClasspath
350 gitBranch = string("")
352 println("Using a ${CHANNEL} profile.")
354 additional_compiler_args = []
355 // configure classpath/args for j8/j11 compilation
356 if (JAVA_VERSION.equals("1.8")) {
357 JAVA_INTEGER_VERSION = string("8")
360 libDistDir = j8libDir
361 compile_source_compatibility = 1.8
362 compile_target_compatibility = 1.8
363 // these are getdown.txt properties defined dependent on the JAVA_VERSION
364 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java8_min_version"))
365 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java8_max_version"))
366 // this property is assigned below and expanded to multiple lines in the getdown task
367 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java8_txt_multi_java_location"))
368 // this property is for the Java library used in eclipse
369 eclipseJavaRuntimeName = string("JavaSE-1.8")
370 } else if (JAVA_VERSION.equals("11")) {
371 JAVA_INTEGER_VERSION = string("11")
373 libDistDir = j11libDir
374 compile_source_compatibility = 11
375 compile_target_compatibility = 11
376 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
377 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
378 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
379 eclipseJavaRuntimeName = string("JavaSE-11")
380 /* compile without modules -- using classpath libraries
381 additional_compiler_args += [
382 '--module-path', modules_compileClasspath.asPath,
383 '--add-modules', j11modules
386 } else if (JAVA_VERSION.equals("12") || JAVA_VERSION.equals("13")) {
387 JAVA_INTEGER_VERSION = JAVA_VERSION
389 libDistDir = j11libDir
390 compile_source_compatibility = JAVA_VERSION
391 compile_target_compatibility = JAVA_VERSION
392 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
393 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
394 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
395 eclipseJavaRuntimeName = string("JavaSE-11")
396 /* compile without modules -- using classpath libraries
397 additional_compiler_args += [
398 '--module-path', modules_compileClasspath.asPath,
399 '--add-modules', j11modules
403 throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
408 JAVA_MIN_VERSION = JAVA_VERSION
409 JAVA_MAX_VERSION = JAVA_VERSION
410 def jreInstallsDir = string(jre_installs_dir)
411 if (jreInstallsDir.startsWith("~/")) {
412 jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1)
414 macosJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-mac-x64/jre")
415 macosJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-mac-x64.tar.gz")
416 windowsJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-windows-x64/jre")
417 windowsJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-windows-x64.tar.gz")
418 linuxJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-linux-x64/jre")
419 linuxJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-linux-x64.tar.gz")
420 install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
421 install4jConfFileName = string("jalview-install4j-conf.install4j")
422 install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
423 install4jHomeDir = install4j_home_dir
424 if (install4jHomeDir.startsWith("~/")) {
425 install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1)
430 buildingHTML = string("${jalviewDir}/${doc_dir}/building.html")
431 helpFile = string("${resourceClassesDir}/${help_dir}/help.jhm")
432 helpParentDir = string("${jalviewDir}/${help_parent_dir}")
433 helpSourceDir = string("${helpParentDir}/${help_dir}")
436 relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
437 jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
438 jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}")
440 jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
442 jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
444 jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
445 jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
446 jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
447 jalviewjsJalviewCoreHtmlFile = string("")
448 jalviewjsJalviewCoreName = string(jalviewjs_core_name)
449 jalviewjsCoreClasslists = []
450 jalviewjsJalviewTemplateName = string(jalviewjs_name)
451 jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
452 jalviewjsJ2sProps = null
453 jalviewjsJ2sPlugin = jalviewjs_j2s_plugin
455 eclipseWorkspace = null
456 eclipseBinary = string("")
457 eclipseVersion = string("")
467 outputDir = file(classesDir)
472 srcDirs += helpParentDir
475 jar.destinationDir = file("${jalviewDir}/${package_dir}")
477 compileClasspath = files(sourceSets.main.java.outputDir)
478 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
480 runtimeClasspath = compileClasspath
485 srcDirs cloverInstrDir
486 outputDir = cloverClassesDir
490 srcDirs = sourceSets.main.resources.srcDirs
493 compileClasspath = files( sourceSets.clover.java.outputDir )
494 //compileClasspath += files( testClassesDir )
495 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
496 compileClasspath += fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
497 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
499 runtimeClasspath = compileClasspath
504 srcDirs testSourceDir
505 outputDir = file(testClassesDir)
509 srcDirs = useClover ? sourceSets.clover.resources.srcDirs : sourceSets.main.resources.srcDirs
512 compileClasspath = files( sourceSets.test.java.outputDir )
513 compileClasspath += useClover ? sourceSets.clover.compileClasspath : sourceSets.main.compileClasspath
514 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
516 runtimeClasspath = compileClasspath
522 // eclipse project and settings files creation, also used by buildship
525 name = eclipse_project_name
527 natures 'org.eclipse.jdt.core.javanature',
528 'org.eclipse.jdt.groovy.core.groovyNature',
529 'org.eclipse.buildship.core.gradleprojectnature'
531 buildCommand 'org.eclipse.jdt.core.javabuilder'
532 buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
536 //defaultOutputDir = sourceSets.main.java.outputDir
539 if (it.isCanBeResolved()) {
544 minusConfigurations += removeThese
545 plusConfigurations = [ ]
549 def removeTheseToo = []
550 HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
551 cp.entries.each { entry ->
552 // This conditional removes all src classpathentries that a) have already been added or b) aren't "src" or "test".
553 // e.g. this removes the resources dir being copied into bin/main, bin/test AND bin/clover
554 // we add the resources and help/help dirs in as libs afterwards (see below)
555 if (entry.kind == 'src') {
556 if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) {
557 removeTheseToo += entry
559 alreadyAddedSrcPath.putAt(entry.path, true)
564 cp.entries.removeAll(removeTheseToo)
566 //cp.entries += new Output("${eclipse_bin_dir}/main")
567 if (file(helpParentDir).isDirectory()) {
568 cp.entries += new Library(fileReference(helpParentDir))
570 if (file(resourceDir).isDirectory()) {
571 cp.entries += new Library(fileReference(resourceDir))
574 HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
576 sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
577 //don't want to add outputDir as eclipse is using its own output dir in bin/main
578 if (it.isDirectory() || ! it.exists()) {
579 // don't add dirs to classpath, especially if they don't exist
580 return false // groovy "continue" in .any closure
582 def itPath = it.toString()
583 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
584 // make relative path
585 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
587 if (alreadyAddedLibPath.get(itPath)) {
588 //println("Not adding duplicate entry "+itPath)
590 //println("Adding entry "+itPath)
591 cp.entries += new Library(fileReference(itPath))
592 alreadyAddedLibPath.put(itPath, true)
596 sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
597 //no longer want to add outputDir as eclipse is using its own output dir in bin/main
598 if (it.isDirectory() || ! it.exists()) {
599 // don't add dirs to classpath
600 return false // groovy "continue" in .any closure
603 def itPath = it.toString()
604 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
605 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
607 if (alreadyAddedLibPath.get(itPath)) {
610 def lib = new Library(fileReference(itPath))
611 lib.entryAttributes["test"] = "true"
613 alreadyAddedLibPath.put(itPath, true)
621 containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
626 // for the IDE, use java 11 compatibility
627 sourceCompatibility = compile_source_compatibility
628 targetCompatibility = compile_target_compatibility
629 javaRuntimeName = eclipseJavaRuntimeName
631 // add in jalview project specific properties/preferences into eclipse core preferences
633 withProperties { props ->
634 def jalview_prefs = new Properties()
635 def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
636 jalview_prefs.load(ins)
638 jalview_prefs.forEach { t, v ->
639 if (props.getAt(t) == null) {
643 // codestyle file -- overrides previous formatter prefs
644 def csFile = file("${jalviewDirAbsolutePath}/${eclipse_codestyle_file}")
645 if (csFile.exists()) {
646 XmlParser parser = new XmlParser()
647 def profiles = parser.parse(csFile)
648 def profile = profiles.'profile'.find { p -> (p.'@kind' == "CodeFormatterProfile" && p.'@name' == "Jalview") }
649 if (profile != null) {
650 profile.'setting'.each { s ->
652 def value = s.'@value'
653 if (id != null && value != null) {
654 props.putAt(id, value)
665 // Don't want these to be activated if in headless build
666 synchronizationTasks "eclipseSynchronizationTask"
667 //autoBuildTasks "eclipseAutoBuildTask"
673 /* hack to change eclipse prefs in .settings files other than org.eclipse.jdt.core.prefs */
674 // Class to allow updating arbitrary properties files
675 class PropertiesFile extends PropertiesPersistableConfigurationObject {
676 public PropertiesFile(PropertiesTransformer t) { super(t); }
677 @Override protected void load(Properties properties) { }
678 @Override protected void store(Properties properties) { }
679 @Override protected String getDefaultResourceName() { return ""; }
680 // This is necessary, because PropertiesPersistableConfigurationObject fails
681 // if no default properties file exists.
682 @Override public void loadDefaults() { load(new StringBufferInputStream("")); }
685 // Task to update arbitrary properties files (set outputFile)
686 class PropertiesFileTask extends PropertiesGeneratorTask<PropertiesFile> {
687 private final PropertiesFileContentMerger file;
688 public PropertiesFileTask() { file = new PropertiesFileContentMerger(getTransformer()); }
689 protected PropertiesFile create() { return new PropertiesFile(getTransformer()); }
690 protected void configure(PropertiesFile props) {
691 file.getBeforeMerged().execute(props); file.getWhenMerged().execute(props);
693 public void file(Closure closure) { ConfigureUtil.configure(closure, file); }
696 task eclipseUIPreferences(type: PropertiesFileTask) {
697 description = "Generate Eclipse additional settings"
698 def filename = "org.eclipse.jdt.ui.prefs"
699 outputFile = "$projectDir/.settings/${filename}" as File
702 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
707 task eclipseGroovyCorePreferences(type: PropertiesFileTask) {
708 description = "Generate Eclipse additional settings"
709 def filename = "org.eclipse.jdt.groovy.core.prefs"
710 outputFile = "$projectDir/.settings/${filename}" as File
713 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
718 task eclipseAllPreferences {
720 dependsOn eclipseUIPreferences
721 dependsOn eclipseGroovyCorePreferences
724 eclipseUIPreferences.mustRunAfter eclipseJdt
725 eclipseGroovyCorePreferences.mustRunAfter eclipseJdt
727 /* end of eclipse preferences hack */
735 delete cloverBuildDir
736 delete cloverReportDir
741 task cloverInstrJava(type: JavaExec) {
742 group = "Verification"
743 description = "Create clover instrumented source java files"
745 dependsOn cleanClover
747 inputs.files(sourceSets.main.allJava)
748 outputs.dir(cloverInstrDir)
750 //classpath = fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
751 classpath = sourceSets.clover.compileClasspath
752 main = "com.atlassian.clover.CloverInstr"
760 cloverInstrDir.getPath(),
762 def srcFiles = sourceSets.main.allJava.files
765 { file -> file.absolutePath }
768 args argsList.toArray()
771 delete cloverInstrDir
772 println("Clover: About to instrument "+srcFiles.size() +" files")
777 task cloverInstrTests(type: JavaExec) {
778 group = "Verification"
779 description = "Create clover instrumented source test files"
781 dependsOn cleanClover
783 inputs.files(testDir)
784 outputs.dir(cloverTestInstrDir)
786 classpath = sourceSets.clover.compileClasspath
787 main = "com.atlassian.clover.CloverInstr"
797 cloverTestInstrDir.getPath(),
799 args argsList.toArray()
802 delete cloverTestInstrDir
803 println("Clover: About to instrument test files")
809 group = "Verification"
810 description = "Create clover instrumented all source files"
812 dependsOn cloverInstrJava
813 dependsOn cloverInstrTests
817 cloverClasses.dependsOn cloverInstr
820 task cloverConsoleReport(type: JavaExec) {
821 group = "Verification"
822 description = "Creates clover console report"
825 file(cloverDb).exists()
828 inputs.dir cloverClassesDir
830 classpath = sourceSets.clover.runtimeClasspath
831 main = "com.atlassian.clover.reporters.console.ConsoleReporter"
833 if (cloverreport_mem.length() > 0) {
834 maxHeapSize = cloverreport_mem
836 if (cloverreport_jvmargs.length() > 0) {
837 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
847 args argsList.toArray()
851 task cloverHtmlReport(type: JavaExec) {
852 group = "Verification"
853 description = "Creates clover HTML report"
856 file(cloverDb).exists()
859 def cloverHtmlDir = cloverReportDir
860 inputs.dir cloverClassesDir
861 outputs.dir cloverHtmlDir
863 classpath = sourceSets.clover.runtimeClasspath
864 main = "com.atlassian.clover.reporters.html.HtmlReporter"
866 if (cloverreport_mem.length() > 0) {
867 maxHeapSize = cloverreport_mem
869 if (cloverreport_jvmargs.length() > 0) {
870 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
881 if (cloverreport_html_options.length() > 0) {
882 argsList += cloverreport_html_options.split(" ")
885 args argsList.toArray()
889 task cloverXmlReport(type: JavaExec) {
890 group = "Verification"
891 description = "Creates clover XML report"
894 file(cloverDb).exists()
897 def cloverXmlFile = "${cloverReportDir}/clover.xml"
898 inputs.dir cloverClassesDir
899 outputs.file cloverXmlFile
901 classpath = sourceSets.clover.runtimeClasspath
902 main = "com.atlassian.clover.reporters.xml.XMLReporter"
904 if (cloverreport_mem.length() > 0) {
905 maxHeapSize = cloverreport_mem
907 if (cloverreport_jvmargs.length() > 0) {
908 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
919 if (cloverreport_xml_options.length() > 0) {
920 argsList += cloverreport_xml_options.split(" ")
923 args argsList.toArray()
928 group = "Verification"
929 description = "Creates clover reports"
931 dependsOn cloverXmlReport
932 dependsOn cloverHtmlReport
939 sourceCompatibility = compile_source_compatibility
940 targetCompatibility = compile_target_compatibility
941 options.compilerArgs += additional_compiler_args
942 print ("Setting target compatibility to "+targetCompatibility+"\n")
944 //classpath += configurations.cloverRuntime
950 // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ?
951 sourceCompatibility = compile_source_compatibility
952 targetCompatibility = compile_target_compatibility
953 options.compilerArgs = additional_compiler_args
954 options.encoding = "UTF-8"
956 print ("Setting target compatibility to "+compile_target_compatibility+"\n")
963 sourceCompatibility = compile_source_compatibility
964 targetCompatibility = compile_target_compatibility
965 options.compilerArgs = additional_compiler_args
967 print ("Setting target compatibility to "+targetCompatibility+"\n")
974 delete sourceSets.main.java.outputDir
980 dependsOn cleanClover
982 delete sourceSets.test.java.outputDir
987 // format is a string like date.format("dd MMMM yyyy")
988 def getDate(format) {
989 def date = new Date()
990 return date.format(format)
997 def hashStdOut = new ByteArrayOutputStream()
998 def resultHash = exec {
999 commandLine "git", "rev-parse", "--short", "HEAD"
1000 standardOutput = hashStdOut
1001 ignoreExitValue true
1004 def branchStdOut = new ByteArrayOutputStream()
1005 def resultBranch = exec {
1006 commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
1007 standardOutput = branchStdOut
1008 ignoreExitValue true
1011 gitHash = resultHash.getExitValue() == 0 ? hashStdOut.toString().trim() : "NO_GIT_COMMITID_FOUND"
1012 gitBranch = resultBranch.getExitValue() == 0 ? branchStdOut.toString().trim() : "NO_GIT_BRANCH_FOUND"
1015 outputs.upToDateWhen { false }
1019 task createBuildProperties(type: WriteProperties) {
1021 description = "Create the ${buildProperties} file"
1023 dependsOn setGitVals
1024 inputs.dir(sourceDir)
1025 inputs.dir(resourceDir)
1026 file(buildProperties).getParentFile().mkdirs()
1027 outputFile (buildProperties)
1028 // taking time specific comment out to allow better incremental builds
1029 comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
1030 //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
1031 property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
1032 property "VERSION", JALVIEW_VERSION
1033 property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
1034 outputs.file(outputFile)
1040 delete buildProperties
1045 task cleanBuildingHTML(type: Delete) {
1052 task convertBuildingMD(type: Exec) {
1053 dependsOn cleanBuildingHTML
1054 def buildingMD = "${jalviewDir}/${doc_dir}/building.md"
1055 def css = "${jalviewDir}/${doc_dir}/github.css"
1058 pandoc_exec.split(",").each {
1059 if (file(it.trim()).exists()) {
1065 def buildtoolsPandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
1066 if ((pandoc == null || ! file(pandoc).exists()) && file(buildtoolsPandoc).exists()) {
1067 pandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
1071 if (pandoc != null && file(pandoc).exists()) {
1072 commandLine pandoc, '-s', '-o', buildingHTML, '--metadata', 'pagetitle="Building Jalview from Source"', '--toc', '-H', css, buildingMD
1074 println("Cannot find pandoc. Skipping convert building.md to HTML")
1075 throw new StopExecutionException("Cannot find pandoc. Skipping convert building.md to HTML")
1079 ignoreExitValue true
1081 inputs.file(buildingMD)
1083 outputs.file(buildingHTML)
1087 task syncDocs(type: Sync) {
1088 //dependsOn convertBuildingMD
1089 def syncDir = "${classesDir}/${doc_dir}"
1090 from fileTree("${jalviewDir}/${doc_dir}")
1096 task copyHelp(type: Copy) {
1097 def inputDir = helpSourceDir
1098 def outputDir = "${resourceClassesDir}/${help_dir}"
1103 filter(ReplaceTokens,
1107 'Version-Rel': JALVIEW_VERSION,
1108 'Year-Rel': getDate("yyyy")
1119 inputs.dir(inputDir)
1120 outputs.files(helpFile)
1121 outputs.dir(outputDir)
1125 task syncLib(type: Sync) {
1126 def syncDir = "${resourceClassesDir}/${libDistDir}"
1127 from fileTree("${jalviewDir}/${libDistDir}")
1132 task syncResources(type: Sync) {
1133 dependsOn createBuildProperties
1136 into "${resourceClassesDir}"
1144 dependsOn syncResources
1150 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
1153 //dependsOn compileJava ////? DELETE
1156 dependsOn cloverClasses
1158 dependsOn compileJava //?
1162 includeGroups testng_groups
1163 excludeGroups testng_excluded_groups
1165 useDefaultListeners=true
1168 maxHeapSize = "1024m"
1170 workingDir = jalviewDir
1171 //systemProperties 'clover.jar' System.properties.clover.jar
1172 sourceCompatibility = compile_source_compatibility
1173 targetCompatibility = compile_target_compatibility
1174 jvmArgs += additional_compiler_args
1178 println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
1184 task buildIndices(type: JavaExec) {
1186 classpath = sourceSets.main.compileClasspath
1187 main = "com.sun.java.help.search.Indexer"
1188 workingDir = "${classesDir}/${help_dir}"
1191 inputs.dir("${workingDir}/${argDir}")
1193 outputs.dir("${classesDir}/doc")
1194 outputs.dir("${classesDir}/help")
1195 outputs.file("${workingDir}/JavaHelpSearch/DOCS")
1196 outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
1197 outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
1198 outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
1199 outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
1200 outputs.file("${workingDir}/JavaHelpSearch/TMAP")
1204 task compileLinkCheck(type: JavaCompile) {
1206 classpath = files("${jalviewDir}/${utils_dir}")
1207 destinationDir = file("${jalviewDir}/${utils_dir}")
1208 source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
1210 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1211 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1212 outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
1213 outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
1217 task linkCheck(type: JavaExec) {
1218 dependsOn prepare, compileLinkCheck
1220 def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
1221 classpath = files("${jalviewDir}/${utils_dir}")
1222 main = "HelpLinksChecker"
1223 workingDir = jalviewDir
1224 args = [ "${classesDir}/${help_dir}", "-nointernet" ]
1226 def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
1228 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1231 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1235 inputs.dir("${classesDir}/${help_dir}")
1236 outputs.file(helpLinksCheckerOutFile)
1239 // import the pubhtmlhelp target
1240 ant.properties.basedir = "${jalviewDir}"
1241 ant.properties.helpBuildDir = "${jalviewDirAbsolutePath}/${classes_dir}/${help_dir}"
1242 ant.importBuild "${utils_dir}/publishHelp.xml"
1245 task cleanPackageDir(type: Delete) {
1247 delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
1254 dependsOn buildIndices
1255 dependsOn createBuildProperties
1258 attributes "Main-Class": main_class,
1259 "Permissions": "all-permissions",
1260 "Application-Name": "Jalview Desktop",
1261 "Codebase": application_codebase
1264 destinationDir = file("${jalviewDir}/${package_dir}")
1265 archiveName = rootProject.name+".jar"
1271 exclude "**/*.jar.*"
1273 inputs.dir(classesDir)
1274 outputs.file("${jalviewDir}/${package_dir}/${archiveName}")
1278 task copyJars(type: Copy) {
1279 from fileTree(dir: classesDir, include: "**/*.jar").files
1280 into "${jalviewDir}/${package_dir}"
1284 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
1285 task syncJars(type: Sync) {
1286 from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
1287 into "${jalviewDir}/${package_dir}"
1289 include jar.archiveName
1296 description = "Put all required libraries in dist"
1297 // order of "cleanPackageDir", "copyJars", "jar" important!
1298 jar.mustRunAfter cleanPackageDir
1299 syncJars.mustRunAfter cleanPackageDir
1300 dependsOn cleanPackageDir
1303 outputs.dir("${jalviewDir}/${package_dir}")
1308 dependsOn cleanPackageDir
1314 group = "distribution"
1315 description = "Create a single jar file with all dependency libraries merged. Can be run with java -jar"
1319 from ("${jalviewDir}/${libDistDir}") {
1323 attributes 'Implementation-Version': JALVIEW_VERSION
1325 mainClassName = shadow_jar_main_class
1327 classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
1332 task getdownWebsite() {
1333 group = "distribution"
1334 description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
1339 def getdownWebsiteResourceFilenames = []
1340 def getdownTextString = ""
1341 def getdownResourceDir = getdownResourceDir
1342 def getdownResourceFilenames = []
1345 // clean the getdown website and files dir before creating getdown folders
1346 delete getdownWebsiteDir
1347 delete getdownFilesDir
1350 from buildProperties
1351 rename(build_properties_file, getdown_build_properties)
1354 getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
1356 // set some getdown_txt_ properties then go through all properties looking for getdown_txt_...
1357 def props = project.properties.sort { it.key }
1358 if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
1359 props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
1361 if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) {
1362 props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion)
1364 if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
1365 props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
1368 props.put("getdown_txt_title", jalview_name)
1369 props.put("getdown_txt_ui.name", install4jApplicationName)
1371 // start with appbase
1372 getdownTextString += "appbase = ${getdownAppBase}\n"
1373 props.each{ prop, val ->
1374 if (prop.startsWith("getdown_txt_") && val != null) {
1375 if (prop.startsWith("getdown_txt_multi_")) {
1376 def key = prop.substring(18)
1377 val.split(",").each{ v ->
1378 def line = "${key} = ${v}\n"
1379 getdownTextString += line
1382 // file values rationalised
1383 if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1385 if (val.indexOf('/') == 0) {
1388 } else if (val.indexOf('/') > 0) {
1389 // relative path (relative to jalviewDir)
1390 r = file( "${jalviewDir}/${val}" )
1393 val = "${getdown_resource_dir}/" + r.getName()
1394 getdownWebsiteResourceFilenames += val
1395 getdownResourceFilenames += r.getPath()
1398 if (! prop.startsWith("getdown_txt_resource")) {
1399 def line = prop.substring(12) + " = ${val}\n"
1400 getdownTextString += line
1406 getdownWebsiteResourceFilenames.each{ filename ->
1407 getdownTextString += "resource = ${filename}\n"
1409 getdownResourceFilenames.each{ filename ->
1412 into getdownResourceDir
1417 fileTree(file(package_dir)).each{ f ->
1418 if (f.isDirectory()) {
1419 def files = fileTree(dir: f, include: ["*"]).getFiles()
1421 } else if (f.exists()) {
1425 codeFiles.sort().each{f ->
1426 def name = f.getName()
1427 def line = "code = ${getdownAppDistDir}/${name}\n"
1428 getdownTextString += line
1435 // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
1437 if (JAVA_VERSION.equals("11")) {
1438 def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
1439 j11libFiles.sort().each{f ->
1440 def name = f.getName()
1441 def line = "code = ${getdown_j11lib_dir}/${name}\n"
1442 getdownTextString += line
1445 into getdownJ11libDir
1451 // 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.
1452 //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
1453 getdownTextString += "resource = ${getdown_launcher_new}\n"
1454 getdownTextString += "class = ${main_class}\n"
1456 def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
1457 getdown_txt.write(getdownTextString)
1459 def getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
1460 def launchJvl = file("${getdownWebsiteDir}/${getdownLaunchJvl}")
1461 launchJvl.write("appbase=${getdownAppBase}")
1464 from getdownLauncher
1465 rename(file(getdownLauncher).getName(), getdown_launcher_new)
1466 into getdownWebsiteDir
1470 from getdownLauncher
1471 if (file(getdownLauncher).getName() != getdown_launcher) {
1472 rename(file(getdownLauncher).getName(), getdown_launcher)
1474 into getdownWebsiteDir
1477 if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
1480 from getdownLauncher
1481 from "${getdownWebsiteDir}/${getdown_build_properties}"
1482 if (file(getdownLauncher).getName() != getdown_launcher) {
1483 rename(file(getdownLauncher).getName(), getdown_launcher)
1485 into getdownInstallDir
1489 from getdownInstallDir
1490 into getdownFilesInstallDir
1497 from getdownLauncher
1498 from "${getdownWebsiteDir}/${getdown_build_properties}"
1499 if (file(getdownLauncher).getName() != getdown_launcher) {
1500 rename(file(getdownLauncher).getName(), getdown_launcher)
1502 into getdownFilesDir
1506 from getdownResourceDir
1507 into "${getdownFilesDir}/${getdown_resource_dir}"
1512 inputs.dir("${jalviewDir}/${package_dir}")
1514 outputs.dir(getdownWebsiteDir)
1515 outputs.dir(getdownFilesDir)
1519 // a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
1520 task getdownDigestDir(type: JavaExec) {
1522 description "A task to run a getdown Digest on a dir with getdown.txt. Provide a DIGESTDIR property via -PDIGESTDIR=..."
1524 def digestDirPropertyName = "DIGESTDIR"
1526 classpath = files(getdownLauncher)
1527 def digestDir = findProperty(digestDirPropertyName)
1528 if (digestDir == null) {
1529 throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest")
1533 main = "com.threerings.getdown.tools.Digester"
1537 task getdownDigest(type: JavaExec) {
1538 group = "distribution"
1539 description = "Digest the getdown website folder"
1540 dependsOn getdownWebsite
1542 classpath = files(getdownLauncher)
1544 main = "com.threerings.getdown.tools.Digester"
1545 args getdownWebsiteDir
1546 inputs.dir(getdownWebsiteDir)
1547 outputs.file("${getdownWebsiteDir}/digest2.txt")
1552 group = "distribution"
1553 description = "Create the minimal and full getdown app folder for installers and website and create digest file"
1554 dependsOn getdownDigest
1556 if (reportRsyncCommand) {
1557 def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
1558 def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
1559 println "LIKELY RSYNC COMMAND:"
1560 println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
1561 if (RUNRSYNC == "true") {
1563 commandLine "mkdir", "-p", toDir
1566 commandLine "rsync", "-avh", "--delete", fromDir, toDir
1574 tasks.withType(JavaCompile) {
1575 options.encoding = 'UTF-8'
1581 delete getdownWebsiteDir
1582 delete getdownFilesDir
1588 if (file(install4jHomeDir).exists()) {
1590 } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
1591 install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1592 } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
1593 install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
1595 installDir(file(install4jHomeDir))
1597 mediaTypes = Arrays.asList(install4j_media_types.split(","))
1601 task copyInstall4jTemplate {
1602 def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
1603 def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
1604 inputs.file(install4jTemplateFile)
1605 inputs.file(install4jFileAssociationsFile)
1606 inputs.property("CHANNEL", { CHANNEL })
1607 outputs.file(install4jConfFile)
1610 def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
1612 // turn off code signing if no OSX_KEYPASS
1613 if (OSX_KEYPASS == "") {
1614 install4jConfigXml.'**'.codeSigning.each { codeSigning ->
1615 codeSigning.'@macEnabled' = "false"
1617 install4jConfigXml.'**'.windows.each { windows ->
1618 windows.'@runPostProcessor' = "false"
1622 // turn off checksum creation for LOCAL channel
1623 def e = install4jConfigXml.application[0]
1624 if (CHANNEL == "LOCAL") {
1625 e.'@createChecksums' = "false"
1627 e.'@createChecksums' = "true"
1630 // put file association actions where placeholder action is
1631 def install4jFileAssociationsText = install4jFileAssociationsFile.text
1632 def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
1633 install4jConfigXml.'**'.action.any { a -> // .any{} stops after the first one that returns true
1634 if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
1635 def parent = a.parent()
1637 fileAssociationActions.each { faa ->
1640 // don't need to continue in .any loop once replacements have been made
1645 // use Windows Program Group with Examples folder for RELEASE, and Program Group without Examples for everything else
1646 // NB we're deleting the /other/ one!
1647 // Also remove the examples subdir from non-release versions
1648 def customizedIdToDelete = "PROGRAM_GROUP_RELEASE"
1649 // 2.11.1.0 NOT releasing with the Examples folder in the Program Group
1650 if (false && CHANNEL=="RELEASE") { // remove 'false && ' to include Examples folder in RELEASE channel
1651 customizedIdToDelete = "PROGRAM_GROUP_NON_RELEASE"
1653 // remove the examples subdir from Full File Set
1654 def files = install4jConfigXml.files[0]
1655 def fileset = files.filesets.fileset.find { fs -> fs.'@customizedId' == "FULL_FILE_SET" }
1656 def root = files.roots.root.find { r -> r.'@fileset' == fileset.'@id' }
1657 def mountPoint = files.mountPoints.mountPoint.find { mp -> mp.'@root' == root.'@id' }
1658 def dirEntry = files.entries.dirEntry.find { de -> de.'@mountPoint' == mountPoint.'@id' && de.'@subDirectory' == "examples" }
1659 dirEntry.parent().remove(dirEntry)
1661 install4jConfigXml.'**'.action.any { a ->
1662 if (a.'@customizedId' == customizedIdToDelete) {
1663 def parent = a.parent()
1669 // remove the "Uninstall Old Jalview (optional)" symlink from DMG for non-release DS_Stores
1670 if (! (CHANNEL == "RELEASE" || CHANNEL == "TEST-RELEASE" ) ) {
1671 def symlink = install4jConfigXml.'**'.topLevelFiles.symlink.find { sl -> sl.'@name' == "Uninstall Old Jalview (optional).app" }
1672 symlink.parent().remove(symlink)
1675 // write install4j file
1676 install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
1683 delete install4jConfFile
1688 task installers(type: com.install4j.gradle.Install4jTask) {
1689 group = "distribution"
1690 description = "Create the install4j installers"
1691 dependsOn setGitVals
1693 dependsOn copyInstall4jTemplate
1695 projectFile = install4jConfFile
1697 // create an md5 for the input files to use as version for install4j conf file
1698 def digest = MessageDigest.getInstance("MD5")
1700 (file("${install4jDir}/${install4j_template}").text +
1701 file("${install4jDir}/${install4j_info_plist_file_associations}").text +
1702 file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
1703 def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
1704 if (filesMd5.length() >= 8) {
1705 filesMd5 = filesMd5.substring(0,8)
1707 def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
1708 // make install4jBuildDir relative to jalviewDir
1709 def install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
1712 'JALVIEW_NAME': jalview_name,
1713 'JALVIEW_APPLICATION_NAME': install4jApplicationName,
1714 'JALVIEW_DIR': "../..",
1715 'OSX_KEYSTORE': OSX_KEYSTORE,
1716 'JSIGN_SH': JSIGN_SH,
1717 'JRE_DIR': getdown_app_dir_java,
1718 'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
1719 'JALVIEW_VERSION': JALVIEW_VERSION,
1720 'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
1721 'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
1722 'JAVA_VERSION': JAVA_VERSION,
1723 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
1724 'VERSION': JALVIEW_VERSION,
1725 'MACOS_JAVA_VM_DIR': macosJavaVMDir,
1726 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
1727 'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
1728 'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
1729 'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
1730 'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
1731 'COPYRIGHT_MESSAGE': install4j_copyright_message,
1732 'BUNDLE_ID': install4jBundleId,
1733 'INTERNAL_ID': install4jInternalId,
1734 'WINDOWS_APPLICATION_ID': install4jWinApplicationId,
1735 'MACOS_DS_STORE': install4jDSStore,
1736 'MACOS_DMG_BG_IMAGE': install4jDMGBackgroundImage,
1737 'INSTALLER_NAME': install4jInstallerName,
1738 'INSTALL4J_UTILS_DIR': install4j_utils_dir,
1739 'GETDOWN_WEBSITE_DIR': getdown_website_dir,
1740 'GETDOWN_FILES_DIR': getdown_files_dir,
1741 'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
1742 'GETDOWN_DIST_DIR': getdownAppDistDir,
1743 'GETDOWN_ALT_DIR': getdown_app_dir_alt,
1744 'GETDOWN_INSTALL_DIR': getdown_install_dir,
1745 'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
1746 'BUILD_DIR': install4jBuildDir,
1747 'APPLICATION_CATEGORIES': install4j_application_categories,
1748 'APPLICATION_FOLDER': install4jApplicationFolder,
1749 'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder,
1750 'EXECUTABLE_NAME': install4jExecutableName,
1751 'EXTRA_SCHEME': install4jExtraScheme,
1754 //println("INSTALL4J VARIABLES:")
1755 //variables.each{k,v->println("${k}=${v}")}
1757 destination = "${jalviewDir}/${install4jBuildDir}"
1758 buildSelected = true
1760 if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
1762 disableSigning = true
1766 macKeystorePassword = OSX_KEYPASS
1770 println("Using projectFile "+projectFile)
1773 inputs.dir(getdownWebsiteDir)
1774 inputs.file(install4jConfFile)
1775 inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
1776 inputs.dir(macosJavaVMDir)
1777 inputs.dir(windowsJavaVMDir)
1778 outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
1784 eclipse().configFile(eclipse_codestyle_file)
1789 task sourceDist(type: Tar) {
1790 group "distribution"
1791 description "Create a source .tar.gz file for distribution"
1793 dependsOn convertBuildingMD
1795 def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
1796 def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
1797 // cater for buildship < 3.1 [3.0.1 is max version in eclipse 2018-09]
1799 archiveFileName = outputFileName
1800 } catch (Exception e) {
1801 archiveName = outputFileName
1804 compression Compression.GZIP
1819 "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
1821 "utils/InstallAnywhere",
1836 "gradle.properties",
1847 ".settings/org.eclipse.jdt.core.jalview.prefs",
1851 exclude (EXCLUDE_FILES)
1852 include (PROCESS_FILES)
1853 filter(ReplaceTokens,
1857 'Version-Rel': JALVIEW_VERSION,
1858 'Year-Rel': getDate("yyyy")
1863 exclude (EXCLUDE_FILES)
1864 exclude (PROCESS_FILES)
1865 exclude ("appletlib")
1866 exclude ("**/*locales")
1867 exclude ("*locales/**")
1868 exclude ("utils/InstallAnywhere")
1870 exclude (getdown_files_dir)
1871 exclude (getdown_website_dir)
1873 // exluding these as not using jars as modules yet
1874 exclude ("${j11modDir}/**/*.jar")
1877 include(INCLUDE_FILES)
1879 // from (jalviewDir) {
1880 // // explicit includes for stuff that seemed to not get included
1881 // include(fileTree("test/**/*."))
1882 // exclude(EXCLUDE_FILES)
1883 // exclude(PROCESS_FILES)
1890 dependsOn pubhtmlhelp
1892 inputs.dir("${classesDir}/${help_dir}")
1893 outputs.dir("${buildDir}/distributions/${help_dir}")
1897 task j2sSetHeadlessBuild {
1904 task jalviewjsSetEclipseWorkspace {
1905 def propKey = "jalviewjs_eclipse_workspace"
1907 if (project.hasProperty(propKey)) {
1908 propVal = project.getProperty(propKey)
1909 if (propVal.startsWith("~/")) {
1910 propVal = System.getProperty("user.home") + propVal.substring(1)
1913 def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
1914 def propsFile = file(propsFileName)
1915 def eclipseWsDir = propVal
1916 def props = new Properties()
1918 def writeProps = true
1919 if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
1920 def ins = new FileInputStream(propsFileName)
1923 if (props.getProperty(propKey, null) != null) {
1924 eclipseWsDir = props.getProperty(propKey)
1929 if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
1930 def tempDir = File.createTempDir()
1931 eclipseWsDir = tempDir.getAbsolutePath()
1934 eclipseWorkspace = file(eclipseWsDir)
1937 // do not run a headless transpile when we claim to be in Eclipse
1939 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1940 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
1942 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1946 props.setProperty(propKey, eclipseWsDir)
1947 propsFile.parentFile.mkdirs()
1948 def bytes = new ByteArrayOutputStream()
1949 props.store(bytes, null)
1950 def propertiesString = bytes.toString()
1951 propsFile.text = propertiesString
1957 println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
1960 //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
1961 outputs.file(propsFileName)
1962 outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
1966 task jalviewjsEclipsePaths {
1969 def eclipseRoot = jalviewjs_eclipse_root
1970 if (eclipseRoot.startsWith("~/")) {
1971 eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
1973 if (OperatingSystem.current().isMacOsX()) {
1974 eclipseRoot += "/Eclipse.app"
1975 eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
1976 eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
1977 } else if (OperatingSystem.current().isWindows()) { // check these paths!!
1978 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1979 eclipseRoot += "/eclipse"
1981 eclipseBinary = "${eclipseRoot}/eclipse.exe"
1982 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1983 } else { // linux or unix
1984 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1985 eclipseRoot += "/eclipse"
1986 println("eclipseDir exists")
1988 eclipseBinary = "${eclipseRoot}/eclipse"
1989 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1992 eclipseVersion = "4.13" // default
1993 def assumedVersion = true
1994 if (file(eclipseProduct).exists()) {
1995 def fis = new FileInputStream(eclipseProduct)
1996 def props = new Properties()
1998 eclipseVersion = props.getProperty("version")
2000 assumedVersion = false
2003 def propKey = "eclipse_debug"
2004 eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
2007 // do not run a headless transpile when we claim to be in Eclipse
2009 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2010 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2012 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2015 if (!assumedVersion) {
2016 println("ECLIPSE VERSION=${eclipseVersion}")
2022 task printProperties {
2024 description "Output to console all System.properties"
2026 System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
2032 dependsOn eclipseProject
2033 dependsOn eclipseClasspath
2034 dependsOn eclipseJdt
2038 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
2039 task jalviewjsEclipseCopyDropins(type: Copy) {
2040 dependsOn jalviewjsEclipsePaths
2042 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
2043 inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
2044 def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
2051 // this eclipse -clean doesn't actually work
2052 task jalviewjsCleanEclipse(type: Exec) {
2053 dependsOn eclipseSetup
2054 dependsOn jalviewjsEclipsePaths
2055 dependsOn jalviewjsEclipseCopyDropins
2057 executable(eclipseBinary)
2058 args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
2064 def inputString = """exit
2067 def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
2068 standardInput = inputByteStream
2071 /* not really working yet
2072 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
2076 task jalviewjsTransferUnzipSwingJs {
2077 def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
2081 from zipTree(file_zip)
2082 into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2086 inputs.file file_zip
2087 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2091 task jalviewjsTransferUnzipLib {
2092 def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
2095 zipFiles.each { file_zip ->
2097 from zipTree(file_zip)
2098 into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2103 inputs.files zipFiles
2104 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2108 task jalviewjsTransferUnzipAllLibs {
2109 dependsOn jalviewjsTransferUnzipSwingJs
2110 dependsOn jalviewjsTransferUnzipLib
2114 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
2116 description "Create the .j2s file from the j2s.* properties"
2118 jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
2119 def siteDirProperty = "j2s.site.directory"
2120 def setSiteDir = false
2121 jalviewjsJ2sProps.each { prop, val ->
2123 if (prop == siteDirProperty) {
2124 if (!(val.startsWith('/') || val.startsWith("file://") )) {
2125 val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
2131 if (!setSiteDir) { // default site location, don't override specifically set property
2132 property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
2135 outputFile = jalviewjsJ2sSettingsFileName
2138 inputs.properties(jalviewjsJ2sProps)
2139 outputs.file(jalviewjsJ2sSettingsFileName)
2144 task jalviewjsEclipseSetup {
2145 dependsOn jalviewjsEclipseCopyDropins
2146 dependsOn jalviewjsSetEclipseWorkspace
2147 dependsOn jalviewjsCreateJ2sSettings
2151 task jalviewjsSyncAllLibs (type: Sync) {
2152 dependsOn jalviewjsTransferUnzipAllLibs
2153 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
2154 inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
2155 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2159 def outputFiles = []
2160 rename { filename ->
2161 outputFiles += "${outputDir}/${filename}"
2167 outputs.files outputFiles
2168 inputs.files inputFiles
2172 task jalviewjsSyncResources (type: Sync) {
2173 def inputFiles = fileTree(dir: resourceDir)
2174 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2178 def outputFiles = []
2179 rename { filename ->
2180 outputFiles += "${outputDir}/${filename}"
2186 outputs.files outputFiles
2187 inputs.files inputFiles
2191 task jalviewjsSyncSiteResources (type: Sync) {
2192 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
2193 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2197 def outputFiles = []
2198 rename { filename ->
2199 outputFiles += "${outputDir}/${filename}"
2205 outputs.files outputFiles
2206 inputs.files inputFiles
2210 task jalviewjsSyncBuildProperties (type: Sync) {
2211 dependsOn createBuildProperties
2212 def inputFiles = [file(buildProperties)]
2213 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2217 def outputFiles = []
2218 rename { filename ->
2219 outputFiles += "${outputDir}/${filename}"
2225 outputs.files outputFiles
2226 inputs.files inputFiles
2230 task jalviewjsProjectImport(type: Exec) {
2231 dependsOn eclipseSetup
2232 dependsOn jalviewjsEclipsePaths
2233 dependsOn jalviewjsEclipseSetup
2236 // do not run a headless import when we claim to be in Eclipse
2238 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2239 throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2241 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2245 //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
2246 def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
2247 executable(eclipseBinary)
2248 args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
2252 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2254 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2257 inputs.file("${jalviewDir}/.project")
2258 outputs.upToDateWhen {
2259 file(projdir).exists()
2264 task jalviewjsTranspile(type: Exec) {
2265 dependsOn jalviewjsEclipseSetup
2266 dependsOn jalviewjsProjectImport
2267 dependsOn jalviewjsEclipsePaths
2270 // do not run a headless transpile when we claim to be in Eclipse
2272 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2273 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2275 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2279 executable(eclipseBinary)
2280 args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
2284 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2286 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2292 stdout = new ByteArrayOutputStream()
2293 stderr = new ByteArrayOutputStream()
2295 def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
2296 def logOutFile = file(logOutFileName)
2297 logOutFile.createNewFile()
2298 logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
2299 BINARY: ${eclipseBinary}
2300 VERSION: ${eclipseVersion}
2301 WORKSPACE: ${eclipseWorkspace}
2302 DEBUG: ${eclipseDebug}
2305 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2306 // combine stdout and stderr
2307 def logErrFOS = logOutFOS
2309 if (jalviewjs_j2s_to_console.equals("true")) {
2310 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2311 new org.apache.tools.ant.util.TeeOutputStream(
2315 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2316 new org.apache.tools.ant.util.TeeOutputStream(
2321 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2324 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2331 if (stdout.toString().contains("Error processing ")) {
2332 // j2s did not complete transpile
2333 //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2334 if (jalviewjs_ignore_transpile_errors.equals("true")) {
2335 println("IGNORING TRANSPILE ERRORS")
2336 println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2338 throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2343 inputs.dir("${jalviewDir}/${sourceDir}")
2344 outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
2345 outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
2349 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
2351 def stdout = new ByteArrayOutputStream()
2352 def stderr = new ByteArrayOutputStream()
2354 def coreFile = file(jsfile)
2356 msg = "Creating core for ${name}...\nGenerating ${jsfile}"
2358 logOutFile.createNewFile()
2359 logOutFile.append(msg+"\n")
2361 def coreTop = file(prefixFile)
2362 def coreBottom = file(suffixFile)
2363 coreFile.getParentFile().mkdirs()
2364 coreFile.createNewFile()
2365 coreFile.write( coreTop.getText("UTF-8") )
2369 def t = f.getText("UTF-8")
2370 t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
2371 coreFile.append( t )
2373 msg = "...file '"+f.getPath()+"' does not exist, skipping"
2375 logOutFile.append(msg+"\n")
2378 coreFile.append( coreBottom.getText("UTF-8") )
2380 msg = "Generating ${zjsfile}"
2382 logOutFile.append(msg+"\n")
2383 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2384 def logErrFOS = logOutFOS
2387 classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
2388 main = "com.google.javascript.jscomp.CommandLineRunner"
2389 jvmArgs = [ "-Dfile.encoding=UTF-8" ]
2390 args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
2393 msg = "\nRunning '"+commandLine.join(' ')+"'\n"
2395 logOutFile.append(msg+"\n")
2397 if (logOutConsole) {
2398 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2399 new org.apache.tools.ant.util.TeeOutputStream(
2403 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2404 new org.apache.tools.ant.util.TeeOutputStream(
2409 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2412 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2419 logOutFile.append(msg+"\n")
2423 task jalviewjsBuildAllCores {
2425 description "Build the core js lib closures listed in the classlists dir"
2426 dependsOn jalviewjsTranspile
2427 dependsOn jalviewjsTransferUnzipSwingJs
2429 def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
2430 def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
2431 def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
2432 def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
2433 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
2434 def prefixFile = "${jsDir}/core/coretop2.js"
2435 def suffixFile = "${jsDir}/core/corebottom2.js"
2437 inputs.file prefixFile
2438 inputs.file suffixFile
2440 def classlistFiles = []
2441 // add the classlists found int the jalviewjs_classlists_dir
2442 fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
2444 def name = file.getName() - ".txt"
2451 // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
2452 //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
2453 classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
2455 jalviewjsCoreClasslists = []
2457 classlistFiles.each {
2460 def file = hash['file']
2461 if (! file.exists()) {
2462 //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
2463 return false // this is a "continue" in groovy .each closure
2465 def name = hash['name']
2467 name = file.getName() - ".txt"
2475 def list = fileTree(dir: j2sDir, includes: filelist)
2477 def jsfile = "${outputDir}/core${name}.js"
2478 def zjsfile = "${outputDir}/core${name}.z.js"
2480 jalviewjsCoreClasslists += [
2489 outputs.file(jsfile)
2490 outputs.file(zjsfile)
2493 // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
2494 def stevesoftClasslistName = "_stevesoft"
2495 def stevesoftClasslist = [
2496 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
2497 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
2498 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
2499 'name': stevesoftClasslistName
2501 jalviewjsCoreClasslists += stevesoftClasslist
2502 inputs.files(stevesoftClasslist['list'])
2503 outputs.file(stevesoftClasslist['jsfile'])
2504 outputs.file(stevesoftClasslist['zjsfile'])
2507 def allClasslistName = "_all"
2508 def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
2509 allJsFiles += fileTree(
2513 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2514 "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
2515 "**/org/jmol/export/JSExporter.js"
2518 allJsFiles += fileTree(
2522 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2523 "**/sun/misc/Unsafe.js",
2524 "**/swingjs/jquery/jquery-editable-select.js",
2525 "**/swingjs/jquery/j2sComboBox.js",
2526 "**/sun/misc/FloatingDecimal.js"
2529 def allClasslist = [
2530 'jsfile': "${outputDir}/core${allClasslistName}.js",
2531 'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
2533 'name': allClasslistName
2535 // not including this version of "all" core at the moment
2536 //jalviewjsCoreClasslists += allClasslist
2537 inputs.files(allClasslist['list'])
2538 outputs.file(allClasslist['jsfile'])
2539 outputs.file(allClasslist['zjsfile'])
2542 def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
2543 logOutFile.getParentFile().mkdirs()
2544 logOutFile.createNewFile()
2545 logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
2547 jalviewjsCoreClasslists.each {
2548 jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
2555 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
2558 into file(outputFile).getParentFile()
2559 rename { filename ->
2560 if (filename.equals(inputFile.getName())) {
2561 return file(outputFile).getName()
2565 filter(ReplaceTokens,
2569 'MAIN': '"'+main_class+'"',
2571 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
2572 'COREKEY': jalviewjs_core_key,
2573 'CORENAME': coreName
2580 task jalviewjsPublishCoreTemplates {
2581 dependsOn jalviewjsBuildAllCores
2582 def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
2583 def inputFile = file(inputFileName)
2584 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2586 def outputFiles = []
2587 jalviewjsCoreClasslists.each { cl ->
2588 def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
2589 cl['outputfile'] = outputFile
2590 outputFiles += outputFile
2594 jalviewjsCoreClasslists.each { cl ->
2595 jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
2598 inputs.file(inputFile)
2599 outputs.files(outputFiles)
2603 task jalviewjsSyncCore (type: Sync) {
2604 dependsOn jalviewjsBuildAllCores
2605 dependsOn jalviewjsPublishCoreTemplates
2606 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
2607 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2611 def outputFiles = []
2612 rename { filename ->
2613 outputFiles += "${outputDir}/${filename}"
2619 outputs.files outputFiles
2620 inputs.files inputFiles
2624 // this Copy version of TransferSiteJs will delete anything else in the target dir
2625 task jalviewjsCopyTransferSiteJs(type: Copy) {
2626 dependsOn jalviewjsTranspile
2627 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2628 into "${jalviewDir}/${jalviewjsSiteDir}"
2632 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
2633 task jalviewjsSyncTransferSiteJs(type: Sync) {
2634 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2636 into "${jalviewDir}/${jalviewjsSiteDir}"
2643 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
2644 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
2645 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
2646 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
2648 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
2649 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
2650 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
2651 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
2654 task jalviewjsPrepareSite {
2656 description "Prepares the website folder including unzipping files and copying resources"
2657 dependsOn jalviewjsSyncAllLibs
2658 dependsOn jalviewjsSyncResources
2659 dependsOn jalviewjsSyncSiteResources
2660 dependsOn jalviewjsSyncBuildProperties
2661 dependsOn jalviewjsSyncCore
2665 task jalviewjsBuildSite {
2667 description "Builds the whole website including transpiled code"
2668 dependsOn jalviewjsCopyTransferSiteJs
2669 dependsOn jalviewjsPrepareSite
2673 task cleanJalviewjsTransferSite {
2675 delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2676 delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2677 delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2678 delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2683 task cleanJalviewjsSite {
2684 dependsOn cleanJalviewjsTransferSite
2686 delete "${jalviewDir}/${jalviewjsSiteDir}"
2691 task jalviewjsSiteTar(type: Tar) {
2693 description "Creates a tar.gz file for the website"
2694 dependsOn jalviewjsBuildSite
2695 def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
2697 archiveFileName = outputFilename
2698 } catch (Exception e) {
2699 archiveName = outputFilename
2702 compression Compression.GZIP
2704 from "${jalviewDir}/${jalviewjsSiteDir}"
2705 into jalviewjs_site_dir // this is inside the tar file
2707 inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
2711 task jalviewjsServer {
2713 def filename = "jalviewjsTest.html"
2714 description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
2715 def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
2718 SimpleHttpFileServerFactory factory = new SimpleHttpFileServerFactory()
2719 def port = Integer.valueOf(jalviewjs_server_port)
2724 while(port < start+1000 && !running) {
2726 def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
2727 jalviewjsServer = factory.start(doc_root, port)
2729 url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
2730 println("SERVER STARTED with document root ${doc_root}.")
2731 println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).")
2732 println("For debug: "+url+"?j2sdebug")
2733 println("For verbose: "+url+"?j2sverbose")
2734 } catch (Exception e) {
2739 <p><a href="${url}">JalviewJS Test. <${url}></a></p>
2740 <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
2741 <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
2743 jalviewjsCoreClasslists.each { cl ->
2744 def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
2746 <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></a></p>
2748 println("For core ${cl.name}: "+urlcore)
2751 file(htmlFile).text = htmlText
2754 outputs.file(htmlFile)
2755 outputs.upToDateWhen({false})
2759 task cleanJalviewjsAll {
2761 description "Delete all configuration and build artifacts to do with JalviewJS build"
2762 dependsOn cleanJalviewjsSite
2763 dependsOn jalviewjsEclipsePaths
2766 delete "${jalviewDir}/${jalviewjsBuildDir}"
2767 delete "${jalviewDir}/${eclipse_bin_dir}"
2768 if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
2769 delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
2771 delete "${jalviewDir}/${jalviewjs_j2s_settings}"
2774 outputs.upToDateWhen( { false } )
2778 task jalviewjsIDE_checkJ2sPlugin {
2779 group "00 JalviewJS in Eclipse"
2780 description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
2783 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
2784 def j2sPluginFile = file(j2sPlugin)
2785 def eclipseHome = System.properties["eclipse.home.location"]
2786 if (eclipseHome == null || ! IN_ECLIPSE) {
2787 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
2789 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
2790 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
2791 if (!eclipseJ2sPluginFile.exists()) {
2792 def msg = "Eclipse J2S Plugin is not installed (could not find '${eclipseJ2sPlugin}')\nTry running task jalviewjsIDE_copyJ2sPlugin"
2793 System.err.println(msg)
2794 throw new StopExecutionException(msg)
2797 def digest = MessageDigest.getInstance("MD5")
2799 digest.update(j2sPluginFile.text.bytes)
2800 def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
2802 digest.update(eclipseJ2sPluginFile.text.bytes)
2803 def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
2805 if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
2806 def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
2807 System.err.println(msg)
2808 throw new StopExecutionException(msg)
2810 def msg = "Eclipse J2S Plugin is the same as '${j2sPlugin}' (this is good)"
2816 task jalviewjsIDE_copyJ2sPlugin {
2817 group "00 JalviewJS in Eclipse"
2818 description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
2821 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
2822 def j2sPluginFile = file(j2sPlugin)
2823 def eclipseHome = System.properties["eclipse.home.location"]
2824 if (eclipseHome == null || ! IN_ECLIPSE) {
2825 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
2827 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
2828 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
2829 def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
2830 System.err.println(msg)
2833 eclipseJ2sPluginFile.getParentFile().mkdirs()
2834 into eclipseJ2sPluginFile.getParent()
2840 task jalviewjsIDE_j2sFile {
2841 group "00 JalviewJS in Eclipse"
2842 description "Creates the .j2s file"
2843 dependsOn jalviewjsCreateJ2sSettings
2847 task jalviewjsIDE_SyncCore {
2848 group "00 JalviewJS in Eclipse"
2849 description "Build the core js lib closures listed in the classlists dir and publish core html from template"
2850 dependsOn jalviewjsSyncCore
2854 task jalviewjsIDE_SyncSiteAll {
2855 dependsOn jalviewjsSyncAllLibs
2856 dependsOn jalviewjsSyncResources
2857 dependsOn jalviewjsSyncSiteResources
2858 dependsOn jalviewjsSyncBuildProperties
2862 cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
2865 task jalviewjsIDE_PrepareSite {
2866 group "00 JalviewJS in Eclipse"
2867 description "Sync libs and resources to site dir, but not closure cores"
2869 dependsOn jalviewjsIDE_SyncSiteAll
2870 dependsOn cleanJalviewjsTransferSite
2874 task jalviewjsIDE_AssembleSite {
2875 group "00 JalviewJS in Eclipse"
2876 description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
2877 dependsOn jalviewjsPrepareSite
2881 task jalviewjsIDE_SiteClean {
2882 group "00 JalviewJS in Eclipse"
2883 description "Deletes the Eclipse transpiled site"
2884 dependsOn cleanJalviewjsSite
2888 task jalviewjsIDE_Server {
2889 group "00 JalviewJS in Eclipse"
2890 description "Starts a webserver on localhost to test the website"
2891 dependsOn jalviewjsServer
2895 // buildship runs this at import or gradle refresh
2896 task eclipseSynchronizationTask {
2897 //dependsOn eclipseSetup
2898 dependsOn createBuildProperties
2900 dependsOn jalviewjsIDE_j2sFile
2901 dependsOn jalviewjsIDE_checkJ2sPlugin
2902 dependsOn jalviewjsIDE_PrepareSite
2907 // buildship runs this at build time or project refresh
2908 task eclipseAutoBuildTask {
2909 //dependsOn jalviewjsIDE_checkJ2sPlugin
2910 //dependsOn jalviewjsIDE_PrepareSite
2916 description "Build the site"
2917 dependsOn jalviewjsBuildSite