Documentation as code, code as documentation

Just a few quick tips in the context of “arc42 by example”
December 5, 2018 by Michael

This morning, I read this kind tweet by Raumzeitfalle:

This refers to arc42 by example. There will be a second edition of this book soon, with new contributions from Gernot and new, Ralf.

My example in this book, biking2 is still up to date. I used this now several times at customers and every time, I also recommended my approach of generating the documentation as part of the build process. You see the live output here.

What makes those special are the following facts:

  • The docs are written in Asciidoctor, see: src/docs.
  • I’m using the Asciidoctor Maven plugin. That means they are an essential part of the build and aren’t left to die in a Confluence or whatever.
  • Even more, I use maven-resources-plugin to copy them into the output dir from which they are put into the final artifact.
  • While the documentation is strictly structured by the ideas of arc42, here come’s the fun parts:

    • I’m using jQAssistant to continuously verify my personal quality goals with that project: jQAssistant is a QA tool, which allows the definition and validation of project specific rules on a structural level. It is built upon the graph database Neo4j.
      jQAssistant integrates also in your build process. It first analyzes your sources and dependencies and writes every information it can discover through various plugins into an embedded Neo4j instance. That is the scan step. In the following analyze step, it verifies the data agains build-in or custom rules. You write custom rules as Cypher queries. Now the interesting fact: Those concept and rules can be written in Asciidoctor as well. This one, concepts_structure.adoc, declares my concept of a config and support package. Those concepts are executed in Neo4j and add labels to certain nodes. The label is then used in this rule (structure.adoc):

      MATCH (a:Main:Artifact)
      MATCH (a) -[:CONTAINS]-> (p1:Package) -[:DEPENDS_ON]-> (p2:Package) <-[:CONTAINS]- (a)
      WHERE not p1:Config
        and not (p1) -[:CONTAINS]-> (p2)
        and not p2:Support
        and not p1.fqn = 'ac.simons.biking2.summary'
      RETURN p1, p2

      “Give me all the packages of the main artifact but the config and the summary package that depend on other packages that are not contained in the package itself.” If that query returns an entry, the rule is violated. I use that rule to enforce horizontal, domain specific slices.

      Now, the very same, executable rule becomes part of my documentation (see building block view) by just including them. Isn’t that great?

    • I also include specific information from my class files in the docs. Asciidoctor allows including dedicated part of all text files. For example, I use package-info.java files like this directly in the docs: “bikes”. I did this to a much bigger extend in this repo, find the linked articles there. I love Asciidoctor.
    • Last but not least, I use Spring REST docs in my unit tests. Spring REST docs combines hand-written documentation written with Asciidoctor and auto-generated snippets produced with Spring MVC Test. A simple unit test like this gets instrumented by a call to document like show in this block. This describes expectations about parameters and returned values. If they aren’t there in the request or response, the test fails. So one cannot change the api without adapting documentation. You might have guess: The generated Asciidoctor snippet as included again in the final docs, you find it here.

I started working on the documentation in early 2016, after a great workshop with Peter Hruschka and Gernot Starke. This is now 2 years ago and the tooling just got better and better.

Whether you are writing a monolithic application like my example, micro services or desktop applications. There’s no reason not to document your application.

Here are some more interesting projects, that have similar goals:

Also, as an added bonus, there’s DocGist, that creates rendered Asciidoctor files for you to share. Thanks Michael for the tip.

5 comments

  1. phaus wrote:

    Stakeholders

    “Michael Simons” 😂

    Nice Post, great documentation. One tiny suggestion: would it be possible to render some navigation on top/bottom of a document?
    Like “prev” “top” “index” “next” ?

    That would make the navigation way more easier 🙂

    Posted on December 5, 2018 at 4:53 PM | Permalink
  2. Michael wrote:

    Thanks a lot, Philipp for your kind comment. Means a lot coming from you.

    Regarding navigation: Do you mean in the generated docs or in my blog?
    Possible something like we do in the Neo4j-OGM docs, right? They are Asciidoctor based as well.
    I like the idea, have to poke around a bit.

    Posted on December 5, 2018 at 5:18 PM | Permalink
  3. If you want, you could remove the `maven-resources-plugin to`, since 1.5.5 `asciidoctor-maven-plugin` allows filtering resources.

    Just add this to the asciidoctor configuration
    —-

    ${project.build.outputDirectory}/public/docs

    ${basedir}/src/docs

    biking2-architecture.*
    10_quality_tree.nm5
    degraph.*

    —-

    Posted on December 13, 2018 at 3:00 PM | Permalink
  4. Michael wrote:

    Hi. Thanks for the input. Stupid WordPress killed the tags, though. I’d happily merge a PR on the repo itself.

    Posted on December 14, 2018 at 2:05 PM | Permalink
  5. Michael wrote:

    I like this a lot:

     Date: Fri Dec 14 15:14:05 2018 +0100
     1 file changed, 2 insertions(+), 20 deletions(-)
    
    Posted on December 14, 2018 at 7:21 PM | Permalink
Post a Comment

Your email is never published. We need your name and email address only for verifying a legitimate comment. For more information, a copy of your saved data or a request to delete any data under this address, please send a short notice to michael@simons.ac from the address you used to comment on this entry.
By entering and submitting a comment, wether with or without name or email address, you'll agree that all data you have entered including your IP address will be checked and stored for a limited time by Automattic Inc., 60 29th Street #343, San Francisco, CA 94110-4929, USA. only for the purpose of avoiding spam. You can deny further storage of your data by sending an email to support@wordpress.com, with subject “Deletion of Data stored by Akismet”.
Required fields are marked *