From 9d6f11eae34b48d2464a5334003f777d0b078224 Mon Sep 17 00:00:00 2001 From: Norman Walsh Date: Thu, 10 Sep 2015 10:56:01 +0100 Subject: [PATCH 1/3] Added gradle plugin org.docbook.DocBookTask --- build.gradle | 160 ++++++++++++++- gradle.properties | 1 + .../groovy/org/docbook/DocBookPlugin.groovy | 10 + .../groovy/org/docbook/DocBookTask.groovy | 192 ++++++++++++++++++ src/main/java/org/docbook/DocBook.java | 4 - src/main/java/org/docbook/Main.java | 31 ++- .../org.docbook.task.properties | 1 + 7 files changed, 374 insertions(+), 25 deletions(-) create mode 100644 src/main/groovy/org/docbook/DocBookPlugin.groovy create mode 100644 src/main/groovy/org/docbook/DocBookTask.groovy create mode 100644 src/main/resources/META-INF/gradle-plugins/org.docbook.task.properties diff --git a/build.gradle b/build.gradle index f7eb96b6..5a86f875 100644 --- a/build.gradle +++ b/build.gradle @@ -8,13 +8,14 @@ // Gradle to accept resources directly from xslt/ without losing the // top-level xslt/ part of the path names. So I punted. +import groovy.swing.SwingBuilder +import java.awt.Point + buildscript { repositories { + // maven { url uri('/tmp/repo') } mavenLocal() mavenCentral() - maven { - url 'file://' + new File(System.getProperty('user.home'), '.m2/repository').absolutePath - } maven { url "http://maven.restlet.org" } maven { url "http://developer.marklogic.com/maven2" } maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } @@ -24,6 +25,7 @@ buildscript { plugins { id "java" id "osgi" + id "groovy" id "maven" id "maven-publish" id "signing" @@ -45,6 +47,10 @@ configurations.all { } } +configurations { + pluginApi +} + dependencies { compile fileTree(dir: 'delta').include("*.jar") compile ( @@ -54,8 +60,10 @@ dependencies { [group: 'com.xmlcalabash', name: 'xmlcalabash1-print', version: '1.1.4'], [group: 'com.thaiopensource', name: 'jing', version: '20091111', transitive: false], [group: 'org.docbook', name: 'docbook-xsl-java-saxon', version: '1.2.1-95'], - [group: 'commons-cli', name: 'commons-cli', version: '1.3.1'] + // 1.2 because that's what gradleApi requires :-( + [group: 'commons-cli', name: 'commons-cli', version: '1.2'], ) + pluginApi gradleApi() } project.ext.saxonRelease = saxonVersion.substring(0,5) @@ -68,6 +76,30 @@ def versionPropsFile = file("src/main/resources/etc/version.properties") versionProps['version'] = releaseVersion versionProps.store(versionPropsFile.newWriter(),null) +compileGroovy { + classpath += configurations.pluginApi +} + +compileJava { + classpath += configurations.pluginApi +} + +task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from javadoc.destinationDir +} + +task sourcesJar(type: Jar) { + classifier = 'sources' + from sourceSets.main.allSource +} + +artifacts { + archives jar + archives sourcesJar + archives javadocJar +} + task copyLib(type: Copy) { FileCollection runtime = configurations.runtime FileCollection localLib = fileTree(dir: 'delta').include("*.jar") @@ -245,7 +277,12 @@ jar { javax.xml.*,\ *;resolution:=optional' instruction 'DynamicImport-Package', '*' - instruction 'Class-Path', project.ext.runtimeClasspath + " lib" + // This is a bit of a hack; special case the three most likely + // commercial jar files for printing with CSS or FO. + instruction 'Class-Path', project.ext.runtimeClasspath \ + + " lib/XfoJavaCtl.jar" \ + + " lib/xep.jar" \ + + " lib/prince.jar" } } @@ -357,3 +394,116 @@ task clean.doFirst { delete "test/actual" delete "test/result" } + +/* +uploadArchives { + repositories { + mavenDeployer { + repository(url: uri('/tmp/repo')) + } + } +} +*/ + +signing { + required { gradle.taskGraph.hasTask("uploadArchives") } + sign configurations.archives +} + +// I refuse to put my PGP password in a file. +// +// Adapted from +// https://www.timroes.de/2014/01/19/using-password-prompts-with-gradle-build-files/ +// +// N.B. This can't work in a CI environment so there's no way to +// automatically publish the artifacts from, for example, Travis CI. +// +gradle.taskGraph.whenReady { taskGraph -> + if(taskGraph.hasTask(':uploadArchives')) { + + def pass = '' + if(System.console() == null) { + new SwingBuilder().edt { + dialog(modal: true, + title: 'Enter password', + alwaysOnTop: true, + resizable: false, + locationRelativeTo: null, + locationByPlatform: true, + // On my Linux multi-monitor setup, the dialog "appears" at + // the top of the virtual desktop below my desktop. So move + // the damned thing somewhere visible. Meh. + location: new Point(100,100), + pack: true, + show: true + ) { + vbox { // + label(text: "Please enter key passphrase:") + input = passwordField() + button(defaultButton: true, text: 'OK', actionPerformed: { + pass = input.password; + dispose(); + }) + } + } + } + } else { + pass = System.console().readPassword("\nPlease enter key passphrase: ") + pass = new String(pass) + } + + if (pass.size() <= 0) { + throw new InvalidUserDataException("You must enter a password to proceed.") + } + + allprojects { ext."signing.password" = pass } + + } +} + +uploadArchives { + repositories { + mavenDeployer { + beforeDeployment { MavenDeployment deployment -> + signing.signPom(deployment) + } + + repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { + authentication(userName: sonatypeUsername, password: sonatypePassword) + } + + snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { + authentication(userName: sonatypeUsername, password: sonatypePassword) + } + + pom.project { + name 'DocBook XSLT 2.0 Stylesheets' + packaging 'jar' + description 'DocBook XSLT 2.0 stylesheets' + url 'https://github.com/docbook/xslt20-stylesheets' + + scm { + url 'scm:git@github.com:docbook/xslt20-stylesheets.git' + connection 'scm:git@github.com:docbook/xslt20-stylesheets.git' + developerConnection 'scm:git@github.com:docbook/xslt20-stylesheets.git' + } + + licenses { + license { + name 'Apache License version 2.0' + url 'https://www.apache.org/licenses/LICENSE-2.0' + distribution 'repo' + } + } + + developers { + developer { + id 'ndw' + name 'Norman Walsh' + } + } + } + } + } +} + diff --git a/gradle.properties b/gradle.properties index 40003501..221741e8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,6 +5,7 @@ baseline=0 print=cssprint css=resources/css/paged-bw.css include=.*.xml +group=org.docbook saxonVersion=9.6.0-4 diff --git a/src/main/groovy/org/docbook/DocBookPlugin.groovy b/src/main/groovy/org/docbook/DocBookPlugin.groovy new file mode 100644 index 00000000..6a93528a --- /dev/null +++ b/src/main/groovy/org/docbook/DocBookPlugin.groovy @@ -0,0 +1,10 @@ +package org.docbook + +import org.gradle.api.Project +import org.gradle.api.Plugin + +class DocBookPlugin implements Plugin { + void apply(Project target) { + target.task('orgDocBook', type: DocBookTask) + } +} diff --git a/src/main/groovy/org/docbook/DocBookTask.groovy b/src/main/groovy/org/docbook/DocBookTask.groovy new file mode 100644 index 00000000..e785a5d1 --- /dev/null +++ b/src/main/groovy/org/docbook/DocBookTask.groovy @@ -0,0 +1,192 @@ +package org.docbook + +import com.xmlcalabash.drivers.Main +import com.xmlcalabash.util.ParseArgs +import com.xmlcalabash.util.UserArgs +import org.gradle.api.internal.ConventionTask +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.TaskAction + +import com.xmlcalabash.core.XProcConfiguration; +import com.xmlcalabash.core.XProcRuntime; +import com.xmlcalabash.model.RuntimeValue; +import com.xmlcalabash.runtime.XPipeline; +import net.sf.saxon.s9api.QName; +import net.sf.saxon.s9api.XdmNode; + +class DocBookTask extends ConventionTask { + private Hashtable nsBindings = new Hashtable () + private Hashtable params = new Hashtable () + private Hashtable options = new Hashtable () + private Vector extensions = new Vector () + + private String paramFile = null + private String input = null + private String output = null + + DocBookTask() { + } + + private String getOpt(String optName) { + if (options.containsKey(optName)) { + return options.get(optName) + } else { + return null + } + } + + String getFormat() { + return getOpt("format") + } + + def setFormat(String format) { + options.put("format", format) + return this + } + + String getStyle() { + return getOpt("style") + } + + def setStyle(String style) { + options.put("style", style) + return this + } + + String getPreprocess() { + return getOpt("preprocess") + } + + def setPreprocess(String preprocess) { + options.put("preprocess", preprocess) + return this + } + + String getPostprocess() { + return getOpt("postprocess") + } + + def setpostProcess(String postprocess) { + options.put("postprocess", postprocess) + return this + } + + String getReturnSecondary() { + return getOpt("return-secondary") + } + + def setReturnSecondary(String returnSecondary) { + options.put("return-secondary", returnSecondary) + return this + } + + String getPdf() { + return getOpt("pdf") + } + + def setPdf(String pdf) { + options.put("pdf", pdf) + return this + } + + String getCss() { + return getOpt("css") + } + + def setCss(String css) { + options.put("css", css) + return this + } + + String getParamFile() { + return paramFile + } + + def setParamFile(String paramFile) { + this.paramFile = paramFile + return this + } + + @Input + String getInput() { + return input + } + + def setInput(String input) { + this.input = input + return this + } + + String getOutput() { + return output + } + + def setOutput(String output) { + this.output = output + return this + } + + void namespaceBinding(String prefix, String uri) { + nsBindings.put(prefix,uri) + } + + String param(String qname, String value) { + params.put(qname, value) + } + + List getCalabashExtensions() { + return extensions + } + + def setCalabashExtensions(Iterable extensions) { + this.extensions.clear() + for (String s : extensions) { + this.extensions.add(s) + } + return this + } + + def setCalabashExtensions(String... extensions) { + this.extensions.clear() + for (String s : extensions) { + this.extensions.add(s) + } + return this + } + + @TaskAction + void exec() { + DocBook docbook = new DocBook() + + for (String ns : nsBindings.keySet()) { + docbook.setNamespace(ns, nsBindings.get(ns)) + } + + for (String param : params.keySet()) { + docbook.setParam(param, params.get(param)) + } + + for (String opt : options.keySet()) { + docbook.setOption(opt, options.get(opt)) + } + + if (paramFile != null) { + docbook.addParameterFile(paramFile) + } + + if (output != null) { + docbook.setOption("output", output) + } + + if (input == null) { + throw notAllowed("You must specify the input file") + } + + docbook.run(input) + } + + private static UnsupportedOperationException notAllowed(final String msg) { + return new UnsupportedOperationException (msg) + } + +} diff --git a/src/main/java/org/docbook/DocBook.java b/src/main/java/org/docbook/DocBook.java index dcb44c8b..8d1ea8dd 100644 --- a/src/main/java/org/docbook/DocBook.java +++ b/src/main/java/org/docbook/DocBook.java @@ -33,10 +33,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; import java.security.CodeSource; import java.util.Hashtable; import java.util.Properties; diff --git a/src/main/java/org/docbook/Main.java b/src/main/java/org/docbook/Main.java index bc2f399b..50d91893 100644 --- a/src/main/java/org/docbook/Main.java +++ b/src/main/java/org/docbook/Main.java @@ -1,41 +1,39 @@ package org.docbook; import net.sf.saxon.s9api.SaxonApiException; +import org.apache.commons.cli.BasicParser; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import java.io.IOException; -import java.io.InputStream; -import java.util.Hashtable; import java.util.List; -import java.util.Properties; /** * Created by ndw on 8/30/15. */ public class Main { + @SuppressWarnings("static-access") public static void main(String[] args) throws IOException, SaxonApiException { DocBook docbook = new DocBook(); String usage = "java -jar docbook-xslt2-" + docbook.version() + ".jar [options] dbdoc.xml [param=value [param=value] ...] "; - + // N.B. This is explicitly using Commons-CLI 1.2 because that's the dependency that gradle has Options options = new Options(); - Option format = Option.builder("f").argName("format").longOpt("format").hasArg().desc("The format: (x)html (css)print foprint").build(); - Option style = Option.builder("s").argName("style").longOpt("style").hasArg().desc("Custom final-pass XSL stylesheet").build(); - Option post = Option.builder().argName("postprocess").longOpt("postprocess").hasArg().desc("Post-processing stylesheet").build(); - Option pdf = Option.builder().argName("pdf").longOpt("pdf").hasArg().desc("Name for the output PDF file (print only)").build(); - Option output = Option.builder("o").argName("output").longOpt("output").hasArg().desc("Name for the output file (defaults to stdout)").build(); - Option css = Option.builder().argName("css").longOpt("css").hasArg().desc("A CSS stylesheet (CSS print only)").build(); - - Option help = Option.builder("h").argName("help").longOpt("help").desc("Usage: org.docbook.Main [options] dbdoc.xml").build(); - Option params = Option.builder().argName("params").longOpt("params").hasArg().desc("A file of parameters").build(); - Option ns = Option.builder().argName("namespace").longOpt("ns").hasArgs().numberOfArgs(2).valueSeparator().desc("Namespace binding").build(); + Option format = OptionBuilder.withArgName("format").withLongOpt("format").hasArg().withDescription("The format: (x)html (css)print foprint").create("f"); + Option style = OptionBuilder.withArgName("style").withLongOpt("style").hasArg().withDescription("Custom final-pass XSL stylesheet").create("s"); + Option post = OptionBuilder.withArgName("postprocess").withLongOpt("postprocess").hasArg().withDescription("Post-processing stylesheet").create(); + Option pdf = OptionBuilder.withArgName("pdf").withLongOpt("pdf").hasArg().withDescription("Name for the output PDF file (print only)").create(); + Option output = OptionBuilder.withArgName("output").withLongOpt("output").hasArg().withDescription("Name for the output file (defaults to stdout)").create("o"); + Option css = OptionBuilder.withArgName("css").withLongOpt("css").hasArg().withDescription("A CSS stylesheet (CSS print only)").create(); + Option help = OptionBuilder.withArgName("help").withLongOpt("help").withDescription("Usage: org.docbook.Main [options] dbdoc.xml").create("h"); + Option params = OptionBuilder.withArgName("params").withLongOpt("params").hasArg().withDescription("A file of parameters").create(); + Option ns = OptionBuilder.withArgName("namespace").withLongOpt("ns").hasArgs(2).withValueSeparator().withDescription("Namespace binding").create(); options.addOption(format); options.addOption(style); @@ -47,7 +45,7 @@ public static void main(String[] args) throws IOException, SaxonApiException { options.addOption(ns); options.addOption(help); - CommandLineParser parser = new DefaultParser(); + CommandLineParser parser = new BasicParser(); HelpFormatter formatter = new HelpFormatter(); try { @@ -74,6 +72,7 @@ public static void main(String[] args) throws IOException, SaxonApiException { } } + @SuppressWarnings("unchecked") List rest = cmd.getArgList(); String doc = null; diff --git a/src/main/resources/META-INF/gradle-plugins/org.docbook.task.properties b/src/main/resources/META-INF/gradle-plugins/org.docbook.task.properties new file mode 100644 index 00000000..f2240319 --- /dev/null +++ b/src/main/resources/META-INF/gradle-plugins/org.docbook.task.properties @@ -0,0 +1 @@ +implementation-class=org.docbook.DocBookPlugin From fa547bcf8165e99fd386fcf177f123e4b66aa84c Mon Sep 17 00:00:00 2001 From: Norman Walsh Date: Thu, 10 Sep 2015 11:00:34 +0100 Subject: [PATCH 2/3] Version 2.0.13 released --- gradle.properties | 2 +- xslt/base/VERSION.xsl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 221741e8..7038cb10 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=2.0.12 +version=2.0.13 snapshot= builtBy=Norman Walsh baseline=0 diff --git a/xslt/base/VERSION.xsl b/xslt/base/VERSION.xsl index f58200c7..fd145ee2 100644 --- a/xslt/base/VERSION.xsl +++ b/xslt/base/VERSION.xsl @@ -1,4 +1,4 @@ - + From 473c596377b1c4de047c8433dd8006dfda781f30 Mon Sep 17 00:00:00 2001 From: Norman Walsh Date: Thu, 10 Sep 2015 11:06:26 +0100 Subject: [PATCH 3/3] Fix bug in travis build --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c27b1608..8f517c89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,9 @@ language: java script: gradle dist sudo: false install: -- ".travis/setup-diff.sh" + - echo sonatypeUsername=none >> gradle.properties + - echo sonatypePassword=none >> gradle.properties + - ".travis/setup-diff.sh" env: global: - secure: EEcwLo3rIHqaV46h/AOMGafxqaZcy4i9WA8RlFO53wj23QJGmeUdYa2ka4IC2c+J+iNFYu1+dRkR52G6S6tY3LnsDmZGHj9xT9n7tPr/h/OmMXhdtNy3Nl5AWQORMZhqGCXwMxRZUyhWp6CjtY1LeGaVenwf1A3PiLEQmEJw9nY=