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