JAL-3521 working minimal build.gradle for debian and 2.11.2. Flexmark plugin might...
[jalview.git] / utils / debian / debian_build.gradle
1 /* Convention for properties.  Read from gradle.properties, use lower_case_underlines for property names.
2  * For properties set within build.gradle, use camelCaseNoSpace.
3  */
4 import org.apache.tools.ant.filters.ReplaceTokens
5 import com.vladsch.flexmark.util.ast.Node
6 import com.vladsch.flexmark.html.HtmlRenderer
7 import com.vladsch.flexmark.parser.Parser
8 import com.vladsch.flexmark.util.data.MutableDataSet
9 import com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension
10 import com.vladsch.flexmark.ext.tables.TablesExtension
11 import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension
12 import com.vladsch.flexmark.ext.autolink.AutolinkExtension
13 import com.vladsch.flexmark.ext.anchorlink.AnchorLinkExtension
14 import com.vladsch.flexmark.ext.toc.TocExtension
15
16 buildscript {
17   dependencies {
18     classpath "com.vladsch.flexmark:flexmark-all:0.62.0"
19   }
20 }
21
22 plugins {
23   id 'java'
24   id 'application'
25   id 'com.palantir.git-version' version '0.12.3'
26 }
27
28 // in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use
29 def string(Object o) {
30   return o == null ? "" : o.toString()
31 }
32
33 def overrideProperties(String propsFileName, boolean output = false) {
34   if (propsFileName == null) {
35     return
36   }
37   def propsFile = file(propsFileName)
38   if (propsFile != null && propsFile.exists()) {
39     println("Using properties from file '${propsFileName}'")
40     try {
41       def p = new Properties()
42       def localPropsFIS = new FileInputStream(propsFile)
43       p.load(localPropsFIS)
44       localPropsFIS.close()
45       p.each {
46         key, val -> 
47           def oldval
48           if (project.hasProperty(key)) {
49             oldval = project.findProperty(key)
50             project.setProperty(key, val)
51             if (output) {
52               println("Overriding property '${key}' ('${oldval}') with ${file(propsFile).getName()} value '${val}'")
53             }
54           } else {
55             ext.setProperty(key, val)
56             if (output) {
57               println("Setting ext property '${key}' with ${file(propsFile).getName()}s value '${val}'")
58             }
59           }
60       }
61     } catch (Exception e) {
62       println("Exception reading local.properties")
63       e.printStackTrace()
64     }
65   }
66 }
67
68 ext {
69   jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
70   jalviewDirRelativePath = jalviewDir
71
72   propertiesChannelName = "release"
73   channelDir = string("${jalviewDir}/${channel_properties_dir}/${propertiesChannelName}")
74   channelGradleProperties = string("${channelDir}/channel_gradle.properties")
75   overrideProperties(channelGradleProperties, false)
76   
77   ////  
78   // Import releaseProps from the RELEASE file
79   // or a file specified via JALVIEW_RELEASE_FILE if defined
80   // Expect jalview.version and target release branch in jalview.release        
81   def releaseProps = new Properties();
82   def releasePropFile = findProperty("JALVIEW_RELEASE_FILE");
83   def defaultReleasePropFile = "${jalviewDirAbsolutePath}/RELEASE";
84   try {
85     (new File(releasePropFile!=null ? releasePropFile : defaultReleasePropFile)).withInputStream { 
86      releaseProps.load(it)
87     }
88   } catch (Exception fileLoadError) {
89     throw new Error("Couldn't load release properties file "+(releasePropFile==null ? defaultReleasePropFile : "from custom location: releasePropFile"),fileLoadError);
90   }
91   ////
92   // Set JALVIEW_VERSION if it is not already set
93   if (findProperty("JALVIEW_VERSION")==null || "".equals(JALVIEW_VERSION)) {
94     JALVIEW_VERSION = releaseProps.get("jalview.version")
95   }
96
97   // essentials
98   bareSourceDir = string(source_dir)
99   sourceDir = string("${jalviewDir}/${bareSourceDir}")
100   resourceDir = string("${jalviewDir}/${resource_dir}")
101   bareTestSourceDir = string(test_source_dir)
102   testDir = string("${jalviewDir}/${bareTestSourceDir}")
103
104   classesDir = string("${jalviewDir}/${classes_dir}")
105
106   useClover = false
107
108   resourceClassesDir = classesDir
109
110   testSourceDir = testDir
111   testClassesDir = "${jalviewDir}/${test_output_dir}"
112
113   buildProperties = string("${classesDir}/${build_properties_file}")
114   getdownSetAppBaseProperty = false // whether to pass the appbase and appdistdir to the application
115
116   install4jApplicationName = "${jalview_name}"
117   
118   def details = versionDetails()
119   gitHash = details.gitHash
120   gitBranch = details.branchName
121
122   println("Using a ${CHANNEL} profile.")
123
124   additional_compiler_args = []
125   // configure classpath/args for j8/j11 compilation
126   if (JAVA_VERSION.equals("1.8")) {
127     JAVA_INTEGER_VERSION = string("8")
128     //libDir = j8libDir
129     libDir = j11libDir
130     libDistDir = j8libDir
131     compile_source_compatibility = 1.8
132     compile_target_compatibility = 1.8
133   } else if (JAVA_VERSION.equals("11")) {
134     JAVA_INTEGER_VERSION = string("11")
135     libDir = j11libDir
136     libDistDir = j11libDir
137     compile_source_compatibility = 11
138     compile_target_compatibility = 11
139   } else {
140     throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
141   }
142
143   resourceBuildDir = string("${buildDir}/resources")
144   resourcesBuildDir = string("${resourceBuildDir}/resources_build")
145   helpBuildDir = string("${resourceBuildDir}/help_build")
146   docBuildDir = string("${resourceBuildDir}/doc_build")
147
148   if (buildProperties == null) {
149     buildProperties = string("${resourcesBuildDir}/${build_properties_file}")
150   }
151   buildingHTML = string("${jalviewDir}/${doc_dir}/building.html")
152   helpParentDir = string("${jalviewDir}/${help_parent_dir}")
153   helpSourceDir = string("${helpParentDir}/${help_dir}")
154   helpFile = string("${helpBuildDir}/${help_dir}/help.jhm")
155
156   // ENDEXT
157 }
158
159
160 sourceSets {
161   main {
162     java {
163       srcDirs sourceDir
164       outputDir = file(classesDir)
165     }
166
167     resources {
168       srcDirs = [ resourcesBuildDir, docBuildDir, helpBuildDir ]
169     }
170
171     compileClasspath = files(sourceSets.main.java.outputDir)
172     compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
173
174
175     compileClasspath = files(sourceSets.main.java.outputDir)
176     compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
177
178     runtimeClasspath = compileClasspath
179     runtimeClasspath += files(sourceSets.main.resources.srcDirs)
180   }
181
182   test {
183     java {
184       srcDirs testSourceDir
185       outputDir = file(testClassesDir)
186     }
187
188     resources {
189       srcDirs = useClover ? sourceSets.clover.resources.srcDirs : sourceSets.main.resources.srcDirs
190     }
191
192     compileClasspath = files( sourceSets.test.java.outputDir )
193     compileClasspath += useClover ? sourceSets.clover.compileClasspath : sourceSets.main.compileClasspath
194     compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
195
196     runtimeClasspath = compileClasspath
197     runtimeClasspath += files(sourceSets.test.resources.srcDirs)
198   }
199  /*  test {
200     java {
201       srcDirs testSourceDir
202       outputDir = file(testClassesDir)
203     }
204
205     resources {
206       srcDirs = sourceSets.main.resources.srcDirs
207     }
208
209     compileClasspath = files( sourceSets.test.java.outputDir )
210     compileClasspath += sourceSets.main.compileClasspath
211     compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**   REMOVE_THIS_GAP  /*.jar"])
212
213     runtimeClasspath = compileClasspath
214   }
215 */
216 }
217
218
219 compileJava {
220   sourceCompatibility = compile_source_compatibility
221   targetCompatibility = compile_target_compatibility
222   options.compilerArgs = additional_compiler_args
223   doFirst {
224     print ("Setting target compatibility to "+compile_target_compatibility+"\n")
225   }
226 }
227
228
229 compileTestJava {
230   doFirst {
231     sourceCompatibility = compile_source_compatibility
232     targetCompatibility = compile_target_compatibility
233     options.compilerArgs = additional_compiler_args
234     print ("Setting target compatibility to "+targetCompatibility+"\n")
235   }
236 }
237
238
239 clean {
240   doFirst {
241     delete sourceSets.main.java.outputDir
242   }
243 }
244
245
246 cleanTest {
247   doFirst {
248     delete sourceSets.test.java.outputDir
249   }
250 }
251
252
253 // format is a string like date.format("dd MMMM yyyy")
254 def getDate(format) {
255   def date = new Date()
256   return date.format(format)
257 }
258
259
260 def convertMdToHtml (FileTree mdFiles, File cssFile) {
261   MutableDataSet options = new MutableDataSet()
262
263   def extensions = new ArrayList<>()
264   extensions.add(AnchorLinkExtension.create()) 
265   extensions.add(AutolinkExtension.create())
266   extensions.add(StrikethroughExtension.create())
267   extensions.add(TaskListExtension.create())
268   extensions.add(TablesExtension.create())
269   extensions.add(TocExtension.create())
270   
271   options.set(Parser.EXTENSIONS, extensions)
272
273   // set GFM table parsing options
274   options.set(TablesExtension.WITH_CAPTION, false)
275   options.set(TablesExtension.COLUMN_SPANS, false)
276   options.set(TablesExtension.MIN_HEADER_ROWS, 1)
277   options.set(TablesExtension.MAX_HEADER_ROWS, 1)
278   options.set(TablesExtension.APPEND_MISSING_COLUMNS, true)
279   options.set(TablesExtension.DISCARD_EXTRA_COLUMNS, true)
280   options.set(TablesExtension.HEADER_SEPARATOR_COLUMN_MATCH, true)
281   // GFM anchor links
282   options.set(AnchorLinkExtension.ANCHORLINKS_SET_ID, false)
283   options.set(AnchorLinkExtension.ANCHORLINKS_ANCHOR_CLASS, "anchor")
284   options.set(AnchorLinkExtension.ANCHORLINKS_SET_NAME, true)
285   options.set(AnchorLinkExtension.ANCHORLINKS_TEXT_PREFIX, "<span class=\"octicon octicon-link\"></span>")
286
287   Parser parser = Parser.builder(options).build()
288   HtmlRenderer renderer = HtmlRenderer.builder(options).build()
289
290   mdFiles.each { mdFile ->
291     // add table of contents
292     def mdText = "[TOC]\n"+mdFile.text
293
294     // grab the first top-level title
295     def title = null
296     def titleRegex = /(?m)^#(\s+|([^#]))(.*)/
297     def matcher = mdText =~ titleRegex
298     if (matcher.size() > 0) {
299       // matcher[0][2] is the first character of the title if there wasn't any whitespace after the #
300       title = (matcher[0][2] != null ? matcher[0][2] : "")+matcher[0][3]
301     }
302     // or use the filename if none found
303     if (title == null) {
304       title = mdFile.getName()
305     }
306
307     Node document = parser.parse(mdText)
308     String htmlBody = renderer.render(document)
309     def htmlText = '''<html>
310 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
311 <html xmlns="http://www.w3.org/1999/xhtml">
312   <head>
313     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
314     <meta http-equiv="Content-Style-Type" content="text/css" />
315     <meta name="generator" content="flexmark" />
316 '''
317     htmlText += ((title != null) ? "  <title>${title}</title>" : '' )
318     htmlText += '''
319     <style type="text/css">code{white-space: pre;}</style>
320 '''
321     htmlText += ((cssFile != null) ? cssFile.text : '')
322     htmlText += '''</head>
323   <body>
324 '''
325     htmlText += htmlBody
326     htmlText += '''
327   </body>
328 </html>
329 '''
330
331     def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
332     def htmlFile = file(htmlFilePath)
333     println("Creating ${htmlFilePath}")
334     htmlFile.text = htmlText
335   }
336 }
337
338
339 task copyDocs(type: Copy) {
340   def inputDir = "${jalviewDir}/${doc_dir}"
341   def outputDir = "${docBuildDir}/${doc_dir}"
342   from(inputDir) {
343     include('**/*.txt')
344     include('**/*.md')
345     include('**/*.html')
346     include('**/*.xml')
347     filter(ReplaceTokens,
348       beginToken: '$$',
349       endToken: '$$',
350       tokens: [
351         'Version-Rel': JALVIEW_VERSION,
352         'Year-Rel': getDate("yyyy")
353       ]
354     )
355   }
356   from(inputDir) {
357     exclude('**/*.txt')
358     exclude('**/*.md')
359     exclude('**/*.html')
360     exclude('**/*.xml')
361   }
362   into outputDir
363
364   inputs.dir(inputDir)
365   outputs.dir(outputDir)
366 }
367
368
369 task convertMdFiles {
370   dependsOn copyDocs
371   def mdFiles = fileTree(dir: docBuildDir, include: "**/*.md")
372   def cssFile = file("${jalviewDir}/${flexmark_css}")
373
374   doLast {
375     convertMdToHtml(mdFiles, cssFile)
376   }
377
378   inputs.files(mdFiles)
379   inputs.file(cssFile)
380
381   def htmlFiles = []
382   mdFiles.each { mdFile ->
383     def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
384     htmlFiles.add(file(htmlFilePath))
385   }
386   outputs.files(htmlFiles)
387 }
388
389
390 task copyHelp(type: Copy) {
391   def inputDir = helpSourceDir
392   def outputDir = "${helpBuildDir}/${help_dir}"
393   from(inputDir) {
394     include('**/*.txt')
395     include('**/*.md')
396     include('**/*.html')
397     include('**/*.hs')
398     include('**/*.xml')
399     include('**/*.jhm')
400     filter(ReplaceTokens,
401       beginToken: '$$',
402       endToken: '$$',
403       tokens: [
404         'Version-Rel': JALVIEW_VERSION,
405         'Year-Rel': getDate("yyyy")
406       ]
407     )
408   }
409   from(inputDir) {
410     exclude('**/*.txt')
411     exclude('**/*.md')
412     exclude('**/*.html')
413     exclude('**/*.hs')
414     exclude('**/*.xml')
415     exclude('**/*.jhm')
416   }
417   into outputDir
418
419   inputs.dir(inputDir)
420   outputs.files(helpFile)
421   outputs.dir(outputDir)
422 }
423
424
425 task copyResources(type: Copy) {
426   group = "build"
427   description = "Copy (and make text substitutions in) the resources dir to the build area"
428
429   def inputDir = resourceDir
430   def outputDir = resourcesBuildDir
431   from(inputDir) {
432     include('**/*.txt')
433     include('**/*.md')
434     include('**/*.html')
435     include('**/*.xml')
436     filter(ReplaceTokens,
437       beginToken: '$$',
438       endToken: '$$',
439       tokens: [
440         'Version-Rel': JALVIEW_VERSION,
441         'Year-Rel': getDate("yyyy")
442       ]
443     )
444   }
445   from(inputDir) {
446     exclude('**/*.txt')
447     exclude('**/*.md')
448     exclude('**/*.html')
449     exclude('**/*.xml')
450   }
451   into outputDir
452
453   inputs.dir(inputDir)
454   outputs.dir(outputDir)
455 }
456
457 task copyChannelResources(type: Copy) {
458   dependsOn copyResources
459   group = "build"
460   description = "Copy the channel resources dir to the build resources area"
461
462   def inputDir = "${channelDir}/${resource_dir}"
463   def outputDir = resourcesBuildDir
464   from inputDir
465   into outputDir
466
467   inputs.dir(inputDir)
468   outputs.dir(outputDir)
469 }
470
471 task createBuildProperties(type: WriteProperties) {
472   dependsOn copyResources
473   group = "build"
474   description = "Create the ${buildProperties} file"
475   
476   inputs.dir(sourceDir)
477   inputs.dir(resourcesBuildDir)
478   outputFile (buildProperties)
479   // taking time specific comment out to allow better incremental builds
480   comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
481   //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
482   property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
483   property "VERSION", JALVIEW_VERSION
484   property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
485   if (getdownSetAppBaseProperty) {
486     property "GETDOWNAPPBASE", getdownAppBase
487     property "GETDOWNAPPDISTDIR", getdownAppDistDir
488   }
489   outputs.file(outputFile)
490 }
491
492
493 task buildIndices(type: JavaExec) {
494   dependsOn copyHelp
495   classpath = sourceSets.main.compileClasspath
496   main = "com.sun.java.help.search.Indexer"
497   workingDir = "${helpBuildDir}/${help_dir}"
498   def argDir = "html"
499   args = [ argDir ]
500   inputs.dir("${workingDir}/${argDir}")
501
502   outputs.dir("${classesDir}/doc")
503   outputs.dir("${classesDir}/help")
504   outputs.file("${workingDir}/JavaHelpSearch/DOCS")
505   outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
506   outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
507   outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
508   outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
509   outputs.file("${workingDir}/JavaHelpSearch/TMAP")
510 }
511
512 task buildResources {
513   dependsOn copyResources
514   dependsOn copyChannelResources
515   dependsOn createBuildProperties
516 }
517
518 task prepare {
519   dependsOn buildResources
520   dependsOn copyDocs
521   dependsOn copyHelp
522   dependsOn convertMdFiles
523   dependsOn buildIndices
524 }
525
526
527 compileJava.dependsOn prepare
528 run.dependsOn compileJava
529 //run.dependsOn prepare
530
531
532 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
533 test {
534   dependsOn prepare
535   dependsOn compileJava //?
536
537   useTestNG() {
538     includeGroups testng_groups
539     excludeGroups testng_excluded_groups
540     preserveOrder true
541     useDefaultListeners=true
542   }
543
544   maxHeapSize = "1024m"
545
546   workingDir = jalviewDir
547   //systemProperties 'clover.jar' System.properties.clover.jar
548   def testLaf = project.findProperty("test_laf")
549   if (testLaf != null) {
550     println("Setting Test LaF to '${testLaf}'")
551     systemProperty "laf", testLaf
552   }
553   def testHiDPIScale = project.findProperty("test_HiDPIScale")
554   if (testHiDPIScale != null) {
555     println("Setting Test HiDPI Scale to '${testHiDPIScale}'")
556     systemProperty "sun.java2d.uiScale", testHiDPIScale
557   }
558   sourceCompatibility = compile_source_compatibility
559   targetCompatibility = compile_target_compatibility
560   jvmArgs += additional_compiler_args
561
562   doFirst {
563   }
564 }
565
566
567 task compileLinkCheck(type: JavaCompile) {
568   options.fork = true
569   classpath = files("${jalviewDir}/${utils_dir}")
570   destinationDir = file("${jalviewDir}/${utils_dir}")
571   source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
572
573   inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
574   inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
575   outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
576   outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
577 }
578
579
580 task linkCheck(type: JavaExec) {
581   dependsOn prepare
582   dependsOn compileLinkCheck
583
584   def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
585   classpath = files("${jalviewDir}/${utils_dir}")
586   main = "HelpLinksChecker"
587   workingDir = jalviewDir
588   args = [ "${helpBuildDir}/${help_dir}", "-nointernet" ]
589
590   def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
591   standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
592     outFOS,
593     System.out)
594   errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
595     outFOS,
596     System.err)
597
598   inputs.dir(helpBuildDir)
599   outputs.file(helpLinksCheckerOutFile)
600 }
601
602
603 // import the pubhtmlhelp target
604 ant.properties.basedir = "${jalviewDir}"
605 ant.properties.helpBuildDir = "${helpBuildDir}/${help_dir}"
606 ant.importBuild "${utils_dir}/publishHelp.xml"
607
608
609 task cleanPackageDir(type: Delete) {
610   doFirst {
611     delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
612   }
613 }
614
615
616 jar {
617   dependsOn prepare
618   dependsOn linkCheck
619
620   manifest {
621     attributes "Main-Class": main_class,
622     "Permissions": "all-permissions",
623     "Application-Name": install4jApplicationName,
624     "Codebase": application_codebase,
625     "Implementation-Version": JALVIEW_VERSION
626   }
627
628   def outputDir = "${jalviewDir}/${package_dir}"
629   destinationDirectory = file(outputDir)
630   archiveFileName = rootProject.name+".jar"
631
632   exclude "cache*/**"
633   exclude "*.jar"
634   exclude "*.jar.*"
635   exclude "**/*.jar"
636   exclude "**/*.jar.*"
637
638   inputs.dir(sourceSets.main.java.outputDir)
639   sourceSets.main.resources.srcDirs.each{ dir ->
640     inputs.dir(dir)
641   }
642
643   outputs.file("${outputDir}/${archiveFileName}")
644 }
645