asciidoctor-maven-plugin
asciidoctor-maven-plugin copied to clipboard
Allow attaching generated documents to build
In a multi-module project, I have set up generation of HTML and PDF files from asciidoc in the top level POM as follows:
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<configuration>
<sourceDirectory>src/docs</sourceDirectory>
<outputDirectory>${generated-docs}</outputDirectory>
</configuration>
<executions>
<execution>
<id>generate-html-docs</id>
<goals>
<goal>process-asciidoc</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<backend>html</backend>
</configuration>
</execution>
<execution>
<id>generate-pdf-docs</id>
<goals>
<goal>process-asciidoc</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<backend>pdf</backend>
</configuration>
</execution>
</executions>
</plugin>
Now the developers can freely add new documents in every submodule without having to set up anything, which is great!
However, we want the generated docs to end up in our corporate repository, which is especially important for release builds. So we have to do something like:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach-documents</id>
<goals>
<goal>attach-artifact</goal>
</goals>
<phase>package</phase>
<configuration>
<artifacts>
<artifact>
<file>${generated-docs}/cool-document.pdf</file>
<type>pdf</type>
<classifier>cool_document</classifier>
</artifact>
<artifact>
<file>${generated-docs}/cool-document.html</file>
<type>html</type>
<classifier>cool_document</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
It is really cumbersome to do this on each and every submodule. What's worse, this approach is likely to produce inconsistencies between the set of attached documents and the set of documents that actually exist.
How about adding a property to asciidoctor-maven-plugin that, when enabled, causes the plugin to attach each generated file as a build artifact? I could live with the fact that such a function would not alter the classifier like I did in the example above (replacing minus with underscore).
I like the idea and technically it is very easy to do, I already have a dirty poc running https://github.com/abelsromero/asciidoctor-maven-plugin/blob/5779eab360b3e3fe68f43767d311086ffc10fb30/src/main/java/org/asciidoctor/maven/AsciidoctorMojo.java#L232-L243.
Running install on a project that generates a pdf and a Html I get this:

But it has the following problems we need to fix:
- Define the proper artifactType and classifier. I am using the backend and just "docs" right now. To avoid adding constants I'd stick with these values and maybe make the classifier configurable.
- Managing multiple files (or defining packaging format): problem is that when generating more than one file for a backend the artifact is overwritten. Maybe we should create a zip file. Whatever we do we need to think this right.
- There's a minor technical issue about how to find the actual path to the generated file. The poc assumes file extensions, but some are configurable so the logic is not trivial and may contain corner cases. Still, not impossible, just painful. edit: karme biting on this one, my poc broke the build on travis :rofl:
My first thought was to attach a zip file too. That seems like the Maven way. Making each individual file into an artifact doesn't seem right to me. Again, that's just my first thought.
Hmm, maybe I'm missing something, but what's wrong with setting classifier and artifact type based on the output file name, i.e. document_a.pdf gets classifier document_a and type pdf? File names will be unique in any case, so deriving the classifier/type from them feels obvious. It also doesn't rely on a constant and makes things totally obvious for all scenarios, be it "one HTML, one PDF" or "two HTMLs".
The zip file approach, however, doesn't seem optimal to me. Implementing that would in fact duplicate existing functionality: if I wanted a zip file, I can already achieve that today with maven-assembly-plugin, which supports selecting files with wildcards and attaching the zip to the build. Using that plugin, I could even include additional files, like a TOC html file or images folders for HTML. If we implemented stuff like this in the asciidoctor plugin, it would likely not be as flexible or battle-tested as the assembly plugin.
My point is: zip files are already possible, but the "multiple single files as named attachments on projects" approach is not. No other maven plugin can be combined with asciidoctor to do this. I was in fact pondering writing a new plugin like build-helper-maven-plugin with support for wildcard input when a colleague suggested that this could be implemented inside the asciidoctor plugin instead!
Thanks for clarifying!
Hmm, maybe I'm missing something
haha, not at all and I am really glad we are discussing this, it's not the first time it has been proposed some way to publish docs using maven. But I just want to think this through and see all options before commiting to it. Specially I don't want to have a partial feature that covers just a specific case. Please, feel free to work on my poc branch or create your own fork to experiment. Question: what is the final purpouse of this? I mean the idea is publishing the docs into an artifact repository to consume them directly or to include them as dependencies in other projects? or..?
but what's wrong with setting classifier and artifact type based on the output file name
Nothing wrong really, but the file extension needs to be added programatticaly based on the backend and configuration applied (outputFile option and/or out-file attribute). That means having a Map for each converter (standard + popular ones). I'd really like to find a standard approach to avoid that, not for the effort it means, but not to interfere with future converters.
The day Asciidoctor is able to pre-process a doc and give info for build systems, that won't be an issue though.
File names will be unique
That's true, but will only work if you are generating 1 document for each maven configuration. I am under the impression that is your case, is that so?
Thing is that what I have seen so far of the Maven API it only allows to attach a single artifact (= file) for each configuration. That means that if you are converting many .adoc sources into diferent files, only the last one will get installed in the repo. Basically, if you call this more than once, only the last one takes effect.
See how the html files come from different sources but overlap?
[INFO] --- maven-install-plugin:2.4:install (default-install) @ asciidoc-to-html-example ---
[INFO] Installing C:\home\asciidoc-to-html-example\target\asciidoc-to-html-example-1.0.0-SNAPSHOT.jar to C:\Users\-\.m2\repository\org\asciidoctor\maven\asciidoc-to-html-example\1.0.0-SNAPSHOT\asciidoc-to-html-example-1.0.0-SNAPSHOT.jar
[INFO] Installing C:\home\asciidoc-to-html-example\pom.xml to C:\Users\asalgadr\.m2\repository\org\asciidoctor\maven\asciidoc-to-html-example\1.0.0-SNAPSHOT\asciidoc-to-html-example-1.0.0-SNAPSHOT.pom
[INFO] Installing C:\home\asciidoc-to-html-example\target\generated-docs\example-manual.html to C:\Users\-\.m2\repository\org\asciidoctor\maven\asciidoc-to-html-example\1.0.0-SNAPSHOT\asciidoc-to-html-example-1.0.0-SNAPSHOT-docs.html5
[INFO] Installing C:\home\asciidoc-to-html-example\target\generated-docs\example-manual2.html to C:\Users\-\.m2\repository\org\asciidoctor\maven\asciidoc-to-html-example\1.0.0-SNAPSHOT\asciidoc-to-html-example-1.0.0-SNAPSHOT-docs.html5
And then you only get one entry in the maven-metadata-local.xml: https://gist.github.com/abelsromero/cd4768ce6180db582d69e91d2c15d218
Hi @abelsromero. Just stumbled across this Issue and discussion while attempting to simplify our asciidoctor plugin configuration. Currently, we're duplicating <attributes> and <outputFile> across our execution types (pdf and html). I can easily move the <attributes> to the common <configuration> stanza. But, I can't figure out a way to dynamically affect the file type on the generated <outputFile> file name. I have to repeat the same basic configured name in multiple locations across multiple poms.
I see in your POC above that you are looking to reference the <backend> type after stripping off any current file type extension. This is exactly what I would like the plugin to do. Is this type of processing becoming real anytime soon? Thanks!
But, I can't figure out a way to dynamically affect the file type on the generated <outputFile> file name.
If I understand it correctly, you'll like to add an option to say something like "take name from outputFile and automatically set file extension based on backend/converter". Is that so? The only problem I see is that it creates a copuling between the plugin and the converters. We need to decide what backends we support and what to do with the one we don't. Doable, but still, I am not 100% convinced because if the aim is to reduce boilerplate configuration, maybe that can be done using other methods like naming the source file accordingly or using some maven property.
Anyway, we are happy to discuss this again, just create a separated issue to focus on it.
Thanks, @abelsromero, for the quick response and confirmation of the request! I have created the separate issue and will consider other alternatives in the mean time.
Hi, I just stumbled across this issue while researching a problem identical to the original question.
Here's the outline of my problem: I build documentation in a multi-module repository. Each module (save one) converts an adoc to a PDF defining the final name from inside the adoc by setting the variable :outfilesuffix: . This is really useful, because for versioning the documents one just needs to edit the adoc. For my problem this is viable, because each PDF has a document-version as well as the POM version (e.g. think a user-manual-v7.3.1.pdf in a module with a parent POM with version 2.5.7. - not all documents change, if the repository changes).
But now I'm stuck with collecting the various PDFs in the zipper module (the one saved aboved). My first idea was to depend the zipper module on the adoc modules and use DependencySets for the assembly. For this to work, the adoc modules need to attach the generated PDFs (POM version, type pdf). Alas, the build-helper-maven-plugin doesn't know the PDFs title, still can't do wildcards and therefor can't attach the generated PDF.
Of course it would be possible to set the document version inside the adoc modules POMs, but then you have to change at least two files (pom and adoc) whenever you update the document.
So I would vote for a boolean to have the asciidoctor plugin attach the generated PDF (or HTML or whatever backend one chose). Or is there any other way to achieve this and I just haven't found it?
Interesting approach, more hand craftfed of course, but static resources are distributed as a jar https://github.com/spring-io/spring-doc-resources