Configuring Grails 3 application with ASCII Docs

26 / Oct / 2016 by Puneet Behl 0 comments

Documentation is a very important aspect in any software development project because it helps us to understand how our software application works.

Recently, I have been trying to give back to Grails community by updating existing plugins to Grails 3, creating and updating documentation of Grails plugins and by opening bug report. Mostly Grails 3 plugins are hosted on Github which gives you power of creating your own documentation and publish the same over Github. There are several ways of creating documentation, such as:

  • Grails Docs
  • ASCII Docs
  • GitHub pages etc.

Today, we are going to see how we can configure Grails 3 project to build, publish documentation over Github.

Configure Grails 3 project to build, publish documentation over Github

So, let’s first create a basic Grails 3 application using:

	grails create-app helloDocumentation

This will create a Grails 3 application. Now, open build.gradle and add following plugin under buildscript dependency block:


	classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.3'
    classpath 'org.ajoberstar:gradle-git:1.4.2'

asciidoc-gradle-plugin adds a task asciidoctor. You can configure this task as per your need. Read here more about configuration.

gradle-git will add a set of gradle plugins such as:

  • org.ajoberstar.grgit – provides a Grgit instance, allowing interaction with the Git repository the Gradle project is contained in
  • org.ajoberstar.github-pages – publishes files to the gh-pages branch of a Github repository
  • org.ajoberstar.release-base – general structure for inferring a project version and releasing it
  • org.ajoberstar.release-opinion – opinionated defaults for org.ajoberstar.release-base

But, we will only be using org.ajoberstar.github-pages to publish the documentation to Github.

Now, create a file documentation.gradle under /gradle/documentation.gradle here we will define gradle tasks to generate documentation. Following is the content of file:


buildscript {
    repositories {
        maven { url 'https://repo.grails.org/grails/core' }
    }
    dependencies {
        classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.3'
        classpath 'org.asciidoctor:asciidoctorj-epub3:1.5.0-alpha.6'
        classpath 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.11'
    }
}

apply plugin: 'org.asciidoctor.convert'

def asciidoctorAttributes = [
        copyright           : 'Apache License, Version 2.0',
        docinfo1            : 'true',
        doctype             : 'book',
        encoding            : 'utf-8',
        icons               : 'font',
        id                  : project.name + ':' + project.version,
        idprefix            : '',
        idseparator         : '-',
        lang                : 'en',
        linkattrs           : true,
        numbered            : '',
        producer            : 'Asciidoctor',
        revnumber           : project.version,
        setanchors          : true,
        'source-highlighter' : 'prettify',
        toc                 : 'left',
        toc2                : '',
        toclevels           : '2',
        grailsVersion       : project.grailsVersion
]

import org.asciidoctor.gradle.AsciidoctorTask

tasks.withType(AsciidoctorTask) {
    attributes asciidoctorAttributes
    outputDir new File(buildDir, 'docs/docs')
    separateOutputDirs = false
    sourceDir = file('src/docs')
    sources {
        include 'index.adoc'
        include 'ref/index.adoc'
    }
}

task asciidoc(type: AsciidoctorTask, description: 'Generates single-page HTML and PDF') {
    backends 'html5', 'pdf'
}

task docs(dependsOn: [asciidoc]) << {
    File dir = new File(buildDir, 'docs/docs')
    ['pdf'].each { String ext ->
        File f = new File(dir, 'index.' + ext)
        if (f.exists()) {
            f.renameTo new File(dir, project.name + '-' + project.version + '.' + ext)
        }
    }

    File quickRefDir = new File(buildDir, 'docs/docs/ref')
    ['pdf'].each { String ext ->
        File f = new File(quickRefDir, 'index.' + ext)
        if (f.exists()) {
            f.renameTo new File(quickRefDir, project.name + '-' + project.version + '-' + 'quickReference' + '.' + ext)
        }
    }

    File ghpages = new File(buildDir, 'docs/index.html')
    if (ghpages.exists()) {
        ghpages.delete()
    }
    ghpages << file('src/docs/index.tmpl').text.replaceAll('@VERSION@', project.version)

    copy {
        from 'src/docs'
        into new File(buildDir, 'docs').path
        include '**/*.png'
    }
}

Though, one could have this in single build.gradle file but I like to keep them organized in different files. So, in documentation.gradle we defined following:

  • Some basic ASCII Docs attributes
  • Output and Source directory
  • Which files to include
  • Type of docs, such as – single page html and pdf
  • Template to use for index.html (i.e. index.tmpl)

So far, we have logic in place to generate documentation but we still need to configure task to publish it over GitHub. Now, create a new file named /gradle/publish.gradle with following content:

// Publish gh-pages on github
apply plugin: "org.ajoberstar.github-pages"

ext {
    githubApiKey = System.getProperty('githubApiKey')
}

githubPages {
    repoUri = 'https://github.com/<GIT_HUB_SLUG>'

    credentials {
        username = project.hasProperty('githubApiKey') ? project.githubApiKey : ''
        password = ''
    }

    pages {
        from "${buildDir}/docs"
    }
}

task publishDocs(dependsOn: [docs, publishGhPages]) << {

}

Basically, here we need permission for publishing to GitHub, so you need to define githubApiKey under System properties with your own API key. And you can generate the API Key here. Otherwise, it will ask you to enter your GitHub username and password everytime you run gradle publishDocs.

Finally, the last thing remaining is to include both of these gradle files into main build.gradle as follows:

apply from: "gradle/documentation.gradle"
apply from: "gradle/publish.gradle"

Hope this helps, I will write another blog about how to create ASCII Docs.

FOUND THIS USEFUL? SHARE IT

Leave a comment -