JAL-3130 This commit concentrates on the Mac OS X DMG app bundle, ensuring only one...
[jalview.git] / build.gradle
1 import org.apache.tools.ant.filters.ReplaceTokens
2 import org.gradle.internal.os.OperatingSystem
3
4
5 buildscript {
6   dependencies {
7     //classpath files("$gradlePluginsDir/gradle-macappbundle-2.3.0-patched-2.3.0.jar")
8   }
9 }
10
11 plugins {
12   id 'java'
13   id 'application'
14   id 'com.github.johnrengelman.shadow' version '4.0.3'
15   id 'com.install4j.gradle' version '7.0.9'
16 }
17
18 repositories {
19   jcenter()
20   mavenCentral()
21   flatDir {
22     dirs gradlePluginsDir
23   }
24 }
25
26 mainClassName = launcherClass
27
28 sourceSets {
29
30   main {
31     java {
32       srcDirs "$jalviewDir/$sourceDir"
33       outputDir = file("$jalviewDir/$classesDir")
34     }
35
36     resources {
37       srcDirs "$jalviewDir/$resourceDir"
38       srcDirs "$jalviewDir/$libDir"
39     }
40
41     jar.destinationDir = file("$jalviewDir/$packageDir")
42
43     compileClasspath = files(sourceSets.main.java.outputDir)
44     compileClasspath += fileTree(dir: "$jalviewDir/$libDir", include: ["*.jar"])
45     if (JAVA_VERSION.equals("1.8")) {
46       print("ADDING J11LIBS TO CLASSPATH")
47       compileClasspath += fileTree(dir: "$jalviewDir/$j11libDir", include: ["*.jar"])
48     }
49
50     runtimeClasspath = compileClasspath
51   }
52
53   test {
54     java {
55       srcDirs "$jalviewDir/$testSourceDir"
56       outputDir = file("$jalviewDir/$testOutputDir")
57     }
58
59     resources {
60       srcDirs = sourceSets.main.resources.srcDirs
61     }
62
63     compileClasspath = sourceSets.main.compileClasspath
64     compileClasspath += files( sourceSets.test.java.outputDir )
65     compileClasspath += fileTree(dir: "$jalviewDir/$utilsDir", include: ["**/*.jar"])
66
67     runtimeClasspath = compileClasspath
68   }
69
70   modules {
71     compileClasspath = fileTree(dir: "$jalviewDir/$j11libDir", include: ["*.jar"])
72
73     runtimeClasspath = compileClasspath
74   }
75
76 }
77
78 compileJava {
79
80   doFirst {
81     if (JAVA_VERSION.equals("1.8")) {
82       sourceCompatibility = 1.8
83       targetCompatibility = 1.8
84     } else if (JAVA_VERSION.equals("11")) {
85       sourceCompatibility = 11
86       targetCompatibility = 11
87
88       options.compilerArgs = [
89         '--module-path', sourceSets.modules.compileClasspath.asPath,
90         '--add-modules', j11modules
91       ]
92     }
93     print ("Setting target compatibility to "+targetCompatibility+"\n")
94   }
95
96 }
97
98 clean {
99   delete sourceSets.main.java.outputDir
100 }
101
102 cleanTest {
103   delete sourceSets.test.java.outputDir
104 }
105
106 def getDate(format) {
107   def date = new Date()
108   //return date.format("dd MMMM yyyy")
109   return date.format(format)
110 }
111
112 def getGitHash() {
113   def stdout = new ByteArrayOutputStream()
114   exec {
115     commandLine "git", "rev-parse", "--short", "HEAD"
116     standardOutput = stdout
117     workingDir = jalviewDir
118   }
119   return stdout.toString().trim()
120 }
121
122 def getGitBranch() {
123   def stdout = new ByteArrayOutputStream()
124   exec {
125     commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
126     standardOutput = stdout
127     workingDir = jalviewDir
128   }
129   return stdout.toString().trim()
130 }
131
132 task createBuildProperties(type: WriteProperties) {
133   inputs.dir("$jalviewDir/$sourceDir")
134   inputs.dir("$jalviewDir/$resourceDir")
135   outputFile "$jalviewDir/$classesDir/$buildPropertiesFile"
136   /* taking time/date specific comment out to allow better incremental builds */
137   //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
138   comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
139   property "BUILD_DATE", getDate("dd MMMM yyyy")
140   property "VERSION", JALVIEW_VERSION
141   property "INSTALLATION", INSTALLATION+" git-commit:"+getGitHash()+" ["+getGitBranch()+"]"
142   outputs.file(outputFile)
143   outputs.dir("$jalviewDir/$classesDir")
144 }
145
146 task syncDocs(type: Sync) {
147   def syncDir = "$jalviewDir/$classesDir/$docDir"
148   from fileTree("$jalviewDir/$docDir")
149   into syncDir
150
151 }
152
153 def helpFile = "$jalviewDir/$classesDir/$helpDir/help.jhm"
154 task syncHelp(type: Sync) {
155   inputs.files("$jalviewDir/$helpDir")
156   outputs.files(helpFile)
157
158   def syncDir = "$jalviewDir/$classesDir/$helpDir"
159   from fileTree("$jalviewDir/$helpDir")
160   into syncDir
161 }
162
163 task copyHelp(type: Copy) {
164   def inputDir = "$jalviewDir/$helpDir"
165   def outputDir = "$jalviewDir/$classesDir/$helpDir"
166   from inputDir
167   into outputDir
168   filter(ReplaceTokens, beginToken: '$$', endToken: '$$', tokens: ['Version-Rel': "USING_FILTER"])
169   inputs.dir(inputDir)
170   outputs.files(helpFile)
171   outputs.dir(outputDir)
172 }
173
174 task syncLib(type: Sync) {
175   def syncDir = "$jalviewDir/$classesDir/$libDir"
176   from fileTree("$jalviewDir/$libDir")
177   into syncDir
178 }
179
180 task syncResources(type: Sync) {
181   from "$jalviewDir/$resourceDir"
182   include "**/*.*"
183   exclude "install4j"
184   into "$jalviewDir/$classesDir"
185   preserve {
186     include "**"
187   }
188 }
189
190 task prepare {
191   dependsOn syncResources
192   dependsOn syncDocs
193   dependsOn copyHelp
194 }
195
196 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
197 test {
198   dependsOn prepare
199   dependsOn compileJava
200   useTestNG {
201     includeGroups testngGroups
202   }
203   workingDir = jalviewDir
204   //systemProperties 'clover.jar' System.properties.clover.jar
205 }
206
207 task buildIndices(type: JavaExec) {
208   dependsOn copyHelp
209   classpath = sourceSets.main.compileClasspath
210   main = "com.sun.java.help.search.Indexer"
211   workingDir = "$jalviewDir/$classesDir/$helpDir"
212   def argDir = "html"
213   args = [ argDir ]
214   inputs.dir("$workingDir/$argDir")
215
216   outputs.dir("$jalviewDir/$classesDir/doc")
217   outputs.dir("$jalviewDir/$classesDir/help")
218   outputs.file("$workingDir/JavaHelpSearch/DOCS")
219   outputs.file("$workingDir/JavaHelpSearch/DOCS.TAB")
220   outputs.file("$workingDir/JavaHelpSearch/OFFSETS")
221   outputs.file("$workingDir/JavaHelpSearch/POSITIONS")
222   outputs.file("$workingDir/JavaHelpSearch/SCHEMA")
223   outputs.file("$workingDir/JavaHelpSearch/TMAP")
224 }
225
226 task compileLinkCheck(type: JavaCompile) {
227   options.fork = true
228   classpath = files("$jalviewDir/$utilsDir")
229   destinationDir = file("$jalviewDir/$utilsDir")
230   source = fileTree(dir: "$jalviewDir/$utilsDir", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
231
232   outputs.file("$jalviewDir/$utilsDir/HelpLinksChecker.class")
233   outputs.file("$jalviewDir/$utilsDir/BufferedLineReader.class")
234 }
235
236 task linkCheck(type: JavaExec) {
237   dependsOn prepare, compileLinkCheck
238   classpath = files("$jalviewDir/$utilsDir")
239   main = "HelpLinksChecker"
240   workingDir = "$jalviewDir"
241   args = [ "$classesDir/$helpDir", "-nointernet" ]
242
243   doFirst {
244     standardOutput new FileOutputStream("$jalviewDir/$utilsDir/HelpLinksChecker.out")
245   }
246
247   outputs.file("$jalviewDir/$utilsDir/HelpLinksChecker.out")
248 }
249
250 task cleanPackageDir(type: Delete) {
251   delete fileTree("$jalviewDir/$packageDir").include("*.jar")
252 }
253
254 jar {
255   dependsOn linkCheck
256   dependsOn buildIndices
257   dependsOn createBuildProperties
258
259   manifest {
260     attributes "Main-Class": mainClass,
261     "Permissions": "all-permissions",
262     "Application-Name": "Jalview Desktop",
263     "Codebase": application_codebase
264   }
265
266   destinationDir = file("$jalviewDir/$packageDir")
267   archiveName = rootProject.name+".jar"
268
269   exclude "cache*/**"
270   exclude "*.jar"
271   exclude "*.jar.*"
272   exclude "**/*.jar"
273   exclude "**/*.jar.*"
274
275   inputs.dir("$jalviewDir/$classesDir")
276   outputs.file("$jalviewDir/$packageDir/$archiveName")
277 }
278
279 task copyJars(type: Copy) {
280   from fileTree("$jalviewDir/$classesDir").include("**/*.jar").include("*.jar").files
281   into "$jalviewDir/$packageDir"
282 }
283
284 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
285 task syncJars(type: Sync) {
286   from fileTree("$jalviewDir/$libDir").include("**/*.jar").include("*.jar").files
287   into "$jalviewDir/$packageDir"
288   preserve {
289     include jar.archiveName
290   }
291 }
292
293 task makeDist {
294   // order of "cleanPackageDir", "copyJars", "jar" important!
295   jar.mustRunAfter cleanPackageDir
296   syncJars.mustRunAfter cleanPackageDir
297   dependsOn cleanPackageDir
298   dependsOn syncJars
299   dependsOn jar
300   outputs.dir("$jalviewDir/$packageDir")
301 }
302
303 task cleanDist {
304   dependsOn cleanPackageDir
305   dependsOn cleanTest
306   dependsOn clean
307 }
308
309 shadowJar {
310   dependsOn makeDist
311   if (JAVA_VERSION.equals("11")) {
312     from ("$jalviewDir/$j11libDir") {
313       include("*.jar")
314     }
315   }
316   mainClassName = shadowJarMainClass
317   mergeServiceFiles()
318   classifier = "all"
319   minimize()
320 }
321
322 ext {
323   getdownWebsiteDir = jalviewDir + '/' + getdown_website_dir
324   getdownAppDir = getdownWebsiteDir + '/' + getdown_app_dir
325   getdownJ11libDir = getdownWebsiteDir + '/' + getdown_j11lib_dir
326   getdownResourceDir = getdownWebsiteDir + '/' + getdown_resource_dir
327   getdownLauncher = jalviewDir + '/' + getdown_launcher
328   getdownFilesDir = jalviewDir + '/' + getdown_files_dir
329 }
330
331 task getdownWebsite() {
332   dependsOn makeDist
333   def getdownWebsiteResourceFilenames = []
334   def getdownTextString = ""
335   def getdownResourceDir = project.ext.getdownResourceDir
336   def getdownAppDir = project.ext.getdownAppDir
337   def getdownResourceFilenames = []
338   doFirst {
339     // go through properties looking for getdown_txt_...
340     def props = project.properties.sort { it.key }
341     if (JAVA_VERSION.equals("11")) {
342       props.put("getdown_txt_java_min_version", getdown_alt_java11_min_version)
343     } else {
344       props.put("getdown_txt_java_min_version", getdown_alt_java8_min_version)
345     }
346     props.each{ prop, val ->
347       if (prop.startsWith("getdown_txt_") && val != null) {
348         if (prop.startsWith("getdown_txt_multi_")) {
349           def key = prop.substring(18)
350           val.split(",").each{ v ->
351             def line = key + " = " + v + "\n"
352             getdownTextString += line
353           }
354         } else {
355           // file values rationalised
356           if (val.indexOf('/') > -1) {
357             def r = null
358             if (val.indexOf('/') == 0) {
359               // absolute path
360               r = file(val)
361             } else if (val.indexOf('/') > 0) {
362               // relative path (relative to jalviewDir)
363               r = file( jalviewDir + '/' + val )
364             }
365             if (r.exists()) {
366               val = getdown_resource_dir + '/' + r.getName()
367               getdownWebsiteResourceFilenames += val
368               getdownResourceFilenames += r.getPath()
369             }
370           }
371           def line = prop.substring(12) + " = " + val + "\n"
372           getdownTextString += line
373         }
374       }
375     }
376
377     getdownWebsiteResourceFilenames.each{ filename ->
378       getdownTextString += "resource = "+filename+"\n"
379     }
380     getdownResourceFilenames.each{ filename ->
381       copy {
382         from filename
383         into project.ext.getdownResourceDir
384       }
385     }
386
387     def codeFiles = []
388     makeDist.outputs.files.each{ f ->
389       if (f.isDirectory()) {
390         def files = fileTree(dir: f, include: ["*"]).getFiles()
391         codeFiles += files
392       } else if (f.exists()) {
393         codeFiles += f
394       }
395     }
396     codeFiles.sort().each{f ->
397       def line = "code = " + getdown_app_dir + '/' + f.getName() + "\n"
398       getdownTextString += line
399       copy {
400         from f.getPath()
401         into project.ext.getdownAppDir
402       }
403     }
404
405     if (JAVA_VERSION.equals("11")) {
406       def j11libFiles = fileTree(dir: "$jalviewDir/$j11libDir", include: ["*.jar"]).getFiles()
407       j11libFiles.sort().each{f ->
408         def line = "code = " + getdown_j11lib_dir + '/' + f.getName() + "\n"
409         getdownTextString += line
410         copy {
411           from f.getPath()
412           into project.ext.getdownJ11libDir
413         }
414       }
415     }
416
417     getdownTextString += "code = " + file(getdownLauncher).getName() + "\n"
418     getdownTextString += "class = " + mainClass + "\n"
419
420     def getdown_txt = file(project.ext.getdownWebsiteDir + "/getdown.txt")
421     getdown_txt.write(getdownTextString)
422
423     copy {
424       from getdown_txt
425       into project.ext.getdownFilesDir
426     }
427
428     copy {
429       from getdownLauncher
430       into project.ext.getdownWebsiteDir
431     }
432
433     copy {
434       from getdownLauncher
435       into project.ext.getdownFilesDir
436     }
437
438     copy {
439       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.background_image')
440       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.error_background')
441       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.progress_image')
442       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.icon')
443       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.mac_dock_icon')
444       into project.ext.getdownFilesDir + '/' + getdown_resource_dir 
445     }
446   }
447
448   inputs.dir(jalviewDir + '/' + packageDir)
449   outputs.dir(project.ext.getdownWebsiteDir)
450   outputs.dir(project.ext.getdownFilesDir)
451 }
452
453 task getdownDigest(type: JavaExec) {
454   dependsOn getdownWebsite
455   classpath = files(jalviewDir + '/' + getdown_core)
456   main = "com.threerings.getdown.tools.Digester"
457   args project.ext.getdownWebsiteDir
458   outputs.file(project.ext.getdownWebsiteDir + '/' + "digest2.txt")
459 }
460
461 task getdown() {
462   dependsOn getdownDigest
463 }
464
465 clean {
466   delete project.ext.getdownWebsiteDir
467   delete project.ext.getdownFilesDir
468 }
469
470 install4j {
471   def install4jHomeDir = "/opt/install4j"
472   def hostname = "hostname".execute().text.trim()
473   if (hostname.equals("jv-bamboo")) {
474     install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
475   } else if (OperatingSystem.current().isMacOsX()) {
476     install4jHomeDir = '/Applications/install4j.app/Contents/Resources/app'
477     if (! file(install4jHomeDir).exists()) {
478       install4jHomeDir = System.getProperty("user.home")+install4jHomeDir
479     }
480   } else if (OperatingSystem.current().isLinux()) {
481     install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
482   }
483   installDir = file(install4jHomeDir)
484 }
485
486 task installers(type: com.install4j.gradle.Install4jTask) {
487   dependsOn getdown
488   projectFile = "$jalviewDir/$install4jResourceDir/$install4jConf"
489   variables = [majorVersion: version.substring(2, 11), build: 001]
490   destination = "$jalviewDir/$install4jBuildDir"
491   buildSelected = true
492   inputs.dir(project.ext.getdownWebsiteDir)
493   outputs.dir("$jalviewDir/$install4jBuildDir")
494 }