Next Level: PlantUML with Gradle
In my blog post about why I love AsciiDoc, I wrote about the usage of plantUml in AsciiDoc. Today I will show you how to configure your Gradle build in such a way that a block like this
[plantUML,"test",png]
----
class Animal
class Cat
class Dog
Animal <|-- Cat
Animal <|-- Dog
----
will be rendered as Class-Diagram like this
Cleanup first
But first things first. Lets evolve the build a bit. Last time I’ve added a default task to the maven build for convenience. Let’s do the same with the build.gradle
by appending
// let's set a defaultTask for convenience
defaultTasks 'asciidoctor'
The default Gradle build looks for the sources in src/docs/asciidoc
, but since I plan to use AsciiDoc as the only format, I would like to put the sources in src/docs
. This is configured by defining an asciidoctor task like this:
asciidoctor {
// configure source and output files and folders
sourceDir = file('src/docs')
sources {
include 'test.asciidoc'
}
outputDir = file('build/docs')
// good to see what the build is doing...
logDocuments = true
}
The sources
statement specifies to only render the main file and not the included files (include.asciidoc
).
AsciiDoc-Diagram Plugin
To include PlantUML diagrams in an AsciiDoc file, we need the AsciiDoc-Diagram Plugin. Since this plugin, like most AsciiDoctor plugins, is a Ruby Gem, we first need to install the JRuby Gradle plugin with the following line:
plugins {
id "org.asciidoctor.convert" version "1.5.3"
// we need this plugin to add ruby gems
id "com.github.jruby-gradle.base" version "1.3.0"
}
With this plugin, we can define a dependency to the AsciiDoc-Diagram Gem:
dependencies {
// this is the gem we need for diagrams
gems 'rubygems:asciidoctor-diagram:1.4.0'
}
The Gem alone is not enough since it also depends on the famous Graphviz library. Unfortunately, this can’t be easily defined as dependency and has to be installed manually.
To make it work, we also have to initialize the JRuby plugin by running the jrubyPrepare
task. THis is done by specifying a dependsOn
for the asciidoctor
task:
asciidoctor {
// the jrubyPrepare tasks takes care of loading the gems
dependsOn jrubyPrepare
// the asciidoctor task depends on this gem
requires = ['asciidoctor-diagram']
// seems to be important :-)
gemPath = jrubyPrepare.outputDir
}
putting all changes together, the build.gradle
file now looks like this:
/*
* This build file is part of the docToolchain
*/
plugins {
id "org.asciidoctor.convert" version "1.5.3"
// we need this plugin to add ruby gems
id "com.github.jruby-gradle.base" version "1.3.0"
}
dependencies {
// this is the gem we need for diagrams
gems 'rubygems:asciidoctor-diagram:1.4.0'
}
asciidoctor {
// configure source and output files and folders
sourceDir = file('src/docs')
sources {
include 'test.asciidoc'
}
outputDir = file('build/docs')
// good to see what the build is doing...
logDocuments = true
// the jrubyPrepare tasks takes care of loading the gems
dependsOn jrubyPrepare
// the asciidoctor task depends on this gem
requires = ['asciidoctor-diagram']
// seems to be important :-)
gemPath = jrubyPrepare.outputDir
}
// let's set a defaultTask for convenience
defaultTasks 'asciidoctor'
To test it, I’ve included the PlantUML fragment from above near the top of the test.asciidoc
source file (after the definitions). The gradlew
statement executed on the commandline will now render the file like this:
Conclusion
As you can see, it is easy to combine AsciiDoc with planUML to define UML diagrams within your documentation.
But one question still remains:
When does it make sense to use plantUML within your document?
The new book Communicating Software Architecture(English) / arc42 in Aktion(German) by Gernot Starke and Peter Hruschka provides a good answer. Since you nearly can’t control the layout of plantUML, it only makes sense when you don’t have to manually control the layout. This is the case for most simple diagrams and dynamic diagrams like a sequence diagram. PlantUML does such a good job with layouting sequence diagrams, that I even would prefere to draw them with PlantUML over any other tool.
PS: the docToolchain project created above is available on github: https://github.com/rdmueller/docToolchain