JAL-3210 more progress with goomph. Error detection for external eclipse transpile.
[jalview.git] / build.gradle
1 import org.apache.tools.ant.filters.ReplaceTokens
2 import org.gradle.internal.os.OperatingSystem
3 import org.gradle.plugins.ide.eclipse.model.*
4 import groovy.transform.ExternalizeMethods
5 //import org.eclipse.osgi.*
6 import com.diffplug.gradle.GoomphCacheLocations
7
8 /*
9 buildscript {
10   repositories {
11     repos
12     mavenCentral()
13     jcenter()
14   }
15   dependencies {
16     //eclipseDeps.each { compile "p2:${it}:+" }
17     //classpath 'org.eclipse.platform:org.eclipse.osgi:3.15.0'
18     //compile group: 'org.eclipse.platform', name: 'org.eclipse.osgi', version: '3.15.0'
19     //classpath 'biz.aQute.bnd:biz.aQute.bnd.gradle:4.4.0'
20   }
21 }
22 */
23
24 plugins {
25   id 'java'
26   id 'application'
27   id 'eclipse'
28   id 'com.diffplug.gradle.oomph.ide' version '3.18.1'
29   id 'com.diffplug.gradle.equinoxlaunch' version '3.18.1'
30 }
31
32 dependencies {
33 }
34
35 repositories {
36   jcenter()
37   mavenCentral()
38   flatDir {
39     dirs gradlePluginsDir
40   }
41 }
42
43 mainClassName = launcherClass
44 def classes = "$jalviewDir/$classesDir"
45
46 // configure classpath/args for j8/j11 compilation
47
48 def jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
49 def libDir
50 def libDistDir
51 def compile_source_compatibility
52 def compile_target_compatibility
53
54 ext {
55   buildProperties = jalviewDir + "/" + classesDir +"/" + buildPropertiesFile
56
57   gitHash = ""
58   gitBranch = ""
59
60   jalviewjsServer = ""
61 }
62
63 def JAVA_INTEGER_VERSION
64 //def additional_compiler_args = []
65 // this property is for the Java library used in eclipse
66 def eclipse_java_runtime_name
67 if (JAVA_VERSION.equals("1.8")) {
68   JAVA_INTEGER_VERSION = "8"
69   //libDir = j8libDir
70   libDir = j11libDir
71   libDistDir = j8libDir
72   compile_source_compatibility = 1.8
73   compile_target_compatibility = 1.8
74   eclipse_java_runtime_name = "JavaSE-1.8"
75 } else if (JAVA_VERSION.equals("11")) {
76   JAVA_INTEGER_VERSION = "11"
77   libDir = j11libDir
78   libDistDir = j11libDir
79   compile_source_compatibility = 11
80   compile_target_compatibility = 11
81   eclipse_java_runtime_name = "JavaSE-11"
82   /* compile without modules -- using classpath libraries
83   additional_compiler_args += [
84   '--module-path', ext.modules_compileClasspath.asPath,
85   '--add-modules', j11modules
86   ]
87   */
88 } else if (JAVA_VERSION.equals("12") || JAVA_VERSION.equals("13")) {
89   JAVA_INTEGER_VERSION = JAVA_VERSION
90   libDir = j11libDir
91   libDistDir = j11libDir
92   compile_source_compatibility = JAVA_VERSION
93   compile_target_compatibility = JAVA_VERSION
94   eclipse_java_runtime_name = "JavaSE-11"
95   /* compile without modules -- using classpath libraries
96   additional_compiler_args += [
97   '--module-path', ext.modules_compileClasspath.asPath,
98   '--add-modules', j11modules
99   ]
100   */
101 } else {
102   throw new GradleException("JAVA_VERSION=$JAVA_VERSION not currently supported by Jalview")
103 }
104
105 sourceSets {
106
107   main {
108     java {
109       srcDirs "$jalviewDir/$sourceDir"
110       outputDir = file("$classes")
111     }
112
113     resources {
114       srcDirs "$jalviewDir/$resourceDir"
115     }
116
117     compileClasspath = files(sourceSets.main.java.outputDir)
118     compileClasspath += fileTree(dir: "$jalviewDir/$libDir", include: ["*.jar"])
119
120     runtimeClasspath = compileClasspath
121   }
122
123 }
124
125 eclipse {
126   project {
127     name = eclipse_project_name
128
129     natures 'org.eclipse.jdt.core.javanature',
130     'org.eclipse.buildship.core.gradleprojectnature'
131
132     buildCommand 'org.eclipse.jdt.core.javabuilder'
133     buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
134   }
135
136   classpath {
137     //defaultOutputDir = sourceSets.main.java.outputDir
138     def removeThese = []
139     configurations.each{ if (it.isCanBeResolved()) {
140         removeThese += it
141       }
142     }
143
144     minusConfigurations += removeThese
145     plusConfigurations = [ ]
146     file {
147
148       whenMerged { cp ->
149         def removeTheseToo = []
150         HashMap<String, Boolean> addedSrcPath = new HashMap<>();
151         cp.entries.each { entry ->
152           if (entry.kind == 'src') {
153             if (addedSrcPath.getAt(entry.path) || !(entry.path == "src" || entry.path == "test")) {
154               removeTheseToo += entry
155             } else {
156               addedSrcPath.putAt(entry.path, true)
157             }
158           }
159         }
160         cp.entries.removeAll(removeTheseToo)
161
162         if (file(eclipse_bin_dir+"/main").isDirectory()) {
163                 cp.entries += new Output(eclipse_bin_dir+"/main")
164         }
165         if (file(helpParentDir).isDirectory()) {
166                 cp.entries += new Library(fileReference(helpParentDir))
167         }
168         if (file(resourceDir).isDirectory()) {
169                 cp.entries += new Library(fileReference(resourceDir))
170         }
171
172         HashMap<String, Boolean> addedLibPath = new HashMap<>();
173
174         // changing from sourcesets.main.classpath to specific Java version lib
175         //sourceSets.main.compileClasspath.each{
176         fileTree("$jalviewDir/$libDistDir").include("**/*.jar").include("*.jar").each {
177           //don't want to add outputDir as eclipse is using its own output dir in bin/main
178           if (it.isDirectory() || ! it.exists()) {
179             // don't add dirs to classpath
180             return
181           }
182           def itPath = it.toString()
183           if (itPath.startsWith(jalviewDirAbsolutePath+"/")) {
184             itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
185           }
186           if (addedLibPath.get(itPath)) {
187             //println("Not adding duplicate entry "+itPath)
188           } else {
189             //println("Adding entry "+itPath)
190             cp.entries += new Library(fileReference(itPath))
191             addedLibPath.put(itPath, true)
192           }
193         }
194       } // whenMerged
195
196     } // file
197
198     containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
199   } // classpath
200
201   jdt {
202     // for the IDE, use java 11 compatibility
203     sourceCompatibility = compile_source_compatibility
204     targetCompatibility = compile_target_compatibility
205     javaRuntimeName = eclipse_java_runtime_name
206
207     /*
208     file {
209     withProperties { props ->
210     def jalview_prefs = new Properties()
211     def ins = new FileInputStream(jalviewDirAbsolutePath+"/"+eclipse_extra_jdt_prefs_file)
212     jalview_prefs.load(ins)
213     ins.close()
214     jalview_prefs.forEach { t, v ->
215     if (props.getAt(t) == null) {
216     props.putAt(t, v)
217     }
218     }
219     }
220     }
221      */
222   } // jdt
223
224   //synchronizationTasks eclipseClasspath
225   //autoBuildTasks eclipseClasspath
226 } // eclipse
227
228 /*
229 compileJava {
230
231   doFirst {
232     sourceCompatibility = compile_source_compatibility
233     targetCompatibility = compile_target_compatibility
234     //options.compilerArgs = additional_compiler_args
235     print ("Setting target compatibility to "+targetCompatibility+"\n")
236   }
237
238 }
239
240 clean {
241   delete sourceSets.main.java.outputDir
242 }
243 */
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268 GoomphCacheLocations.override_workspaces = file(jalviewDirAbsolutePath+"/"+goomph_workspace)
269 oomphIde {
270   repoEclipse goomph_eclipse_version
271   jdt {
272     /*
273     installedJre {
274       //markDefault = true
275       //executionEnvironments = [ eclipse.jdt.javaRuntimeName ]
276     }
277     */
278     //compilerComplianceLevel( JAVA_INTEGER_VERSION )
279   }
280   repo "https://download.eclipse.org/releases/${goomph_eclipse_version_name}/"
281   feature goomph_eclipse_jee_feature, goomph_eclipse_jee_version
282   thirdParty {
283     buildship {
284       repo goomph_repo_buildship
285       feature goomph_feature_buildship
286     }
287
288   }
289
290
291   // CLI ARGS HERE!
292 }
293
294 equinoxLaunch {
295   headlessAppSetup {
296
297     launchTask 'ideJalviewjsBuild', {
298       //it.args = ["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", tempEclipseWorkspace, "-"+jalviewjs_eclipseBuildArg, eclipse_project_name ]
299       it.args = ["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-"+jalviewjs_eclipseBuildArg, eclipse_project_name ]
300     }
301   }
302 }
303
304 task testIde(type: ) {
305 }
306
307 task ideCopyDropins (type: Copy) {
308   dependsOn ideSetupP2
309
310   def inputFiles = fileTree(jalviewjs_utils_dir+"/"+jalviewjs_eclipse_dropins_dir)
311   def outputDir = oomphIde.ideDir + "/" + com.diffplug.gradle.FileMisc.macContentsEclipse() + "/dropins"
312
313   from inputFiles
314   into outputDir
315   def outputFiles = []
316   rename { filename ->
317     outputFiles += outputDir+"/"+filename
318     println("COPYING ${filename} to ${outputFiles}")
319     null
320   }
321   outputs.files outputFiles
322   inputs.files inputFiles
323
324 }
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341 def jalviewjsBuildDir
342 def jalviewjsSiteDir
343 task jalviewjsSitePath {
344   if (jalviewjs_site_dir.startsWith("/")) {
345     jalviewjsSiteDir = jalviewjs_site_dir
346   } else {
347     def relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
348     jalviewjsBuildDir = "${relativeBuildDir}/jalviewjs"
349     jalviewjsSiteDir = jalviewjsBuildDir + "/" + jalviewjs_site_dir
350   }
351 }
352
353 def tempEclipseWorkspace
354 task jalviewjsSetTempEclipseWorkspace {
355   tempEclipseWorkspace = file(jalviewjs_eclipse_workspace)
356   if (!tempEclipseWorkspace.exists()) {
357     tempEclipseWorkspace = file("${buildDir}/tmp/eclipse-workspace")
358     //tempEclipseWorkspace.deleteOnExit()
359   }
360   println("ECLIPSE WORKSPACE: "+tempEclipseWorkspace.getPath())
361 }
362
363 task jalviewjsUnzipFiles {
364   dependsOn jalviewjsSitePath
365
366   def zipFiles = fileTree(dir: jalviewjs_utils_dir+"/"+jalviewjs_libjs_dir).include("*.zip")
367   zipFiles += jalviewjs_utils_dir+"/"+jalviewjs_swingjs_zip
368
369   doLast {
370     zipFiles.each { file_zip -> 
371       copy {
372         from zipTree(file_zip)
373         into jalviewjsSiteDir
374       }
375     }
376   }
377
378   inputs.files zipFiles
379   outputs.dir jalviewjsSiteDir
380 }
381
382 def eclipseDropinsDir
383 def eclipseBinary
384 task jalviewjsEclipsePaths {
385   def eclipseRoot = jalviewjs_eclipse_root
386   if (eclipseRoot.startsWith("~")) {
387     eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
388   }
389         if (OperatingSystem.current().isMacOsX()) {
390     eclipseRoot += "/Eclipse.app"
391                 eclipseDropinsDir = eclipseRoot+"/Contents/Eclipse/dropins"
392                 eclipseBinary = eclipseRoot+"/Contents/MacOS/eclipse"
393         } else if (OperatingSystem.current().isWindows()) { // check these paths!!
394                 eclipseDropinsDir = eclipseRoot+"/dropins"
395                 eclipseBinary = eclipseRoot+"/eclipse"
396         } else { // linux or unix
397                 eclipseDropinsDir = eclipseRoot+"/dropins"
398                 eclipseBinary = eclipseRoot+"/eclipse"
399         }
400 }
401
402 task jalviewjsEclipseCopyDropins (type: Copy) {
403   dependsOn jalviewjsEclipsePaths
404   def inputFiles = fileTree(jalviewjs_utils_dir+"/"+jalviewjs_eclipse_dropins_dir)
405   def outputDir = eclipseDropinsDir
406
407   from inputFiles
408   into outputDir
409   def outputFiles = []
410   rename { filename ->
411     outputFiles += outputDir+"/"+filename
412     null
413   }
414   outputs.files outputFiles
415   inputs.files inputFiles
416 }
417
418 task jalviewjsEclipseSetup {
419   dependsOn jalviewjsEclipseCopyDropins
420   dependsOn jalviewjsSetTempEclipseWorkspace
421 }
422
423
424 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
425   dependsOn jalviewjsSitePath
426   outputFile (jalviewDir+"/"+jalviewjs_j2s_settings)
427   def props = project.properties.sort { it.key }
428   def siteDirProperty = "j2s.site.directory"
429   def setSiteDir = false
430   props.each { prop, val ->
431     if (prop.startsWith("j2s.") && val != null) {
432       if (prop == siteDirProperty) {
433         if (!(val.startsWith("/") || val.startsWith("file://") )) {
434           val = jalviewjsSiteDir+"/"+val
435         }
436         setSiteDir = true
437       }
438       property(prop,val)
439     }
440     if (!setSiteDir) {
441       property(siteDirProperty,"${jalviewjsSiteDir}")
442     }
443   }
444   outputs.file(outputFile)
445 }
446
447 task jalviewjsCopyResources (type: Copy) {
448   dependsOn jalviewjsSitePath
449   def inputFiles = fileTree(dir: jalviewjs_resource_dir)
450   def outputDir = jalviewjsSiteDir+"/"+jalviewjs_j2s_subdir
451
452   from inputFiles
453   into outputDir
454   def outputFiles = []
455   rename { filename ->
456     outputFiles += outputDir+"/"+filename
457     null
458   }
459   outputs.files outputFiles
460   inputs.files inputFiles
461 }
462
463 task jalviewjsCopySiteResources (type: Copy) {
464   dependsOn jalviewjsSitePath
465   def inputFiles = fileTree(dir: jalviewjs_utils_dir+"/"+jalviewjs_site_resource_dir)
466   def outputDir = jalviewjsSiteDir
467
468   from inputFiles
469   into outputDir
470   def outputFiles = []
471   rename { filename ->
472     outputFiles += outputDir+"/"+filename
473     null
474   }
475   outputs.files outputFiles
476   inputs.files inputFiles
477 }
478
479 task cleanJalviewjs {
480   dependsOn jalviewjsSitePath
481   /*
482   delete jalviewDir+"/"+jalviewjsSiteDir
483   delete jalviewDir+"/"+eclipse_bin_dir
484   delete file(tempEclipseWorkspace.getAbsolutePath()+"/.metadata")
485   delete jalviewDir+"/"+jalviewjs_j2s_settings
486   */
487 }
488
489 task jalviewjsProjectImport(type: Exec) {
490   // work out how to do this!
491   dependsOn eclipseProject
492   dependsOn eclipseClasspath
493   dependsOn eclipseJdt
494   dependsOn jalviewjsEclipsePaths
495   dependsOn jalviewjsEclipseSetup
496   executable(eclipseBinary)
497   args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", tempEclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
498
499   def projdir = tempEclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
500   inputs.file(jalviewDir+"/.project")
501   outputs.dir(projdir)
502   outputs.upToDateWhen { file(projdir).exists() }
503 }
504
505
506
507
508
509
510
511
512 task jalviewjsTranspile(type: Exec) {
513   dependsOn jalviewjsCreateJ2sSettings 
514   dependsOn jalviewjsProjectImport
515   dependsOn jalviewjsEclipsePaths
516   executable(eclipseBinary)
517   args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", tempEclipseWorkspace, "-"+jalviewjs_eclipseBuildArg, eclipse_project_name ])
518
519   def stdout
520   def stderr
521   doFirst {
522     stdout = new ByteArrayOutputStream()
523     stderr = new ByteArrayOutputStream()
524     standardOutput = new org.apache.tools.ant.util.TeeOutputStream(new FileOutputStream("${jalviewjsBuildDir}/${jalviewjs_j2s_stdout}"), stdout);
525     errorOutput = new org.apache.tools.ant.util.TeeOutputStream(new FileOutputStream("${jalviewjsBuildDir}/${jalviewjs_j2s_stderr}"), stderr);
526   }
527   doLast {
528     if (stdout.toString().contains("Error processing ")) {
529       // j2s did not complete transpile
530       throw new TaskExecutionException("Error during transpilation:\n${stderr}\n")
531     }
532   }
533
534   inputs.dir(sourceDir)
535   outputs.dir(eclipse_bin_dir+"/main")
536   outputs.dir(jalviewjsSiteDir+"/"+jalviewjs_j2s_subdir)
537   outputs.file(jalviewjsSiteDir+jalviewjs_server_resource)
538   outputs.upToDateWhen { file(jalviewjsSiteDir+jalviewjs_server_resource).exists() }
539
540 }
541
542
543
544
545
546
547
548
549 task jalviewjsBuildSite {
550   dependsOn jalviewjsSitePath
551   dependsOn jalviewjsUnzipFiles
552   dependsOn jalviewjsCopyResources
553   dependsOn jalviewjsCopySiteResources
554   dependsOn jalviewjsTranspile
555 }
556
557 task jalviewjsSiteTar(type: Tar) {
558   dependsOn jalviewjsBuildSite
559   def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
560   try {
561     archiveFileName = outputFilename
562   } catch (Exception e) {
563     archiveName = outputFilename
564   }
565
566   compression Compression.GZIP
567
568   from jalviewjsSiteDir
569   into jalviewjs_site_dir // this is inside the tar file
570
571   inputs.dir(jalviewjsSiteDir)
572 }
573
574 def jalviewjsServer = null
575 task jalviewjsServerStart {
576   dependsOn jalviewjsSitePath
577   doLast {
578
579     if (jalviewjsServer != null) {
580       println("SERVER ALREADY RUNNING. Go to "+jalviewjsServer.getResourceUrl(jalviewjs_server_resource)+" . Run  gradle jalviewjsServerStop  to stop.")
581     } else {
582
583       SimpleHttpFileServerFactory factory = new SimpleHttpFileServerFactory()
584       def port = Integer.valueOf(jalviewjs_server_port)
585       def start = port
586       def running = false
587       while(port < start+1000 && !running) {
588         try {
589           def doc_root = new File(jalviewDirAbsolutePath +"/"+ jalviewjsSiteDir)
590           jalviewjsServer = factory.start(doc_root, port)
591           running = true
592           println("SERVER STARTED with document root ${doc_root}.\nGo to "+jalviewjsServer.getResourceUrl(jalviewjs_server_resource)+" . Run  gradle --stop  to stop (kills all gradle daemons).")
593           //println("Ctrl-c to stop.");java.lang.Thread.sleep(Integer.valueOf(jalviewjs_server_wait)*1000);
594         } catch (Exception e) {
595           port++;
596         }
597       }
598
599     }
600
601   }
602
603 }
604
605 /* server persists in gradle daemon but reference is not accessible across builds
606 task jalviewjsServerStop {
607   doLast {
608
609     if (jalviewjsServer != null) {
610
611       println("SERVER ON PORT "+jalviewjsServer.getPort()+" STOPPING. Run  gradle jalviewjsServerStart  to start again.")
612       jalviewjsServer.stop()
613
614     } else {
615       println("SERVER NOT RUNNING. Run  gradle jalviewjsServerStart  to start.")
616     }
617
618   }
619 }
620 */
621
622 task ideSetup {
623   dependsOn ideSetupP2
624   dependsOn ideCopyDropins
625 }
626
627 task ideBuildSite {
628   dependsOn jalviewjsSitePath
629   dependsOn jalviewjsUnzipFiles
630   dependsOn jalviewjsCopyResources
631   dependsOn jalviewjsCopySiteResources
632   dependsOn ideCopyDropins
633   dependsOn ide
634 }
635
636
637
638
639 task jalviewjs {
640   dependsOn jalviewjsBuildSite
641 }
642
643
644 project.afterEvaluate {
645   tasks.findByName('ideJalviewjsBuild').dependsOn eclipseProject
646   tasks.findByName('ideJalviewjsBuild').dependsOn eclipseClasspath
647   tasks.findByName('ideJalviewjsBuild').dependsOn eclipseJdt
648
649   tasks.findByName('ide').dependsOn eclipseProject
650   tasks.findByName('ide').dependsOn eclipseClasspath
651   tasks.findByName('ide').dependsOn eclipseJdt
652 }
653
654
655