Configuring Grails 3 application with ASCII Docs
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:
[sourcecode]
grails create-app helloDocumentation
[/sourcecode]
This will create a Grails 3 application. Now, open build.gradle
and add following plugin under buildscript dependency block:
[sourcecode language=”groovy”]
classpath ‘org.asciidoctor:asciidoctor-gradle-plugin:1.5.3’
classpath ‘org.ajoberstar:gradle-git:1.4.2’
[/sourcecode]
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 inorg.ajoberstar.github-pages
– publishes files to the gh-pages branch of a Github repositoryorg.ajoberstar.release-base
– general structure for inferring a project version and releasing itorg.ajoberstar.release-opinion
– opinionated defaults fororg.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:
[sourcecode language=”groovy”]
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’
}
}
[/sourcecode]
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:
[sourcecode language=”groovy”]
// 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]) << {
}
[/sourcecode]
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:
[sourcecode language=”groovy”]
apply from: "gradle/documentation.gradle"
apply from: "gradle/publish.gradle"
[/sourcecode]
Hope this helps, I will write another blog about how to create ASCII Docs.