Tricks with ant-concat and maven-clean

Recently, I've been doing a lot of work with asciidoc running in a maven environment via maven-site.

Part of the requirement was that files in certain directories demarcated with underscores (_something.adoc etc) needed to be concatenated to a single root .adoc file, which would in turn be parsed into HTML by asciidoctor.

To achieve this, I created a simple-minded concatenation operation using the concat task in Apache Ant.

I've decided to document some insights and share some code, in the hopes that it might help someone else.

Since we're dealing with maven, most (if not all) of the configuration happens inside the pom.xml file. I've decided to share some stripped-down code snippets of the various plugins with commentary.

ant-concat

   <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.8</version>
                <executions>
                    <execution>
                        <id>default-cli</id>
                        <phase>site</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <target>

                                <!-- Collection -->
                                <concat fixlastline="yes"
                                        destfile="${project.basedir}/src/site/asciidoc/collection/result.adoc"
                                        overwrite="yes">
                                    <header filtering="no" trimleading="yes">
                                        Collection Heading
                                        ==================
                                        ${line.separator}
                                        :linkattrs:
                                    </header>
                                    <fileset dir="${project.basedir}/src/site/asciidoc/collection"
                                             includes="**/_*.adoc" excludes="result.adoc">
                                    </fileset>
                                </concat>

                            </target>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

Here we are binding a concat task to the site:run maven lifecycle. Running $ mvn site:run with this configuration will execute whatever is stipulated in <configuration>. In this example, the tasks will run through a fileset (our example sits at ${project.basedir}/src/site/asciidoc/collection) and take all files that start with _ and end with .adoc, but exclude files that are named result.adoc and write them to one file called result.adoc (see the "destfile" property).

  • By default, concat will only select files at 'surface level' - to allow for recursive selection (like, if we have nested directories), we need to set the includes property to **/_*.adoc, instead of _*.adoc.
  • To enforce a line break at the end of each concat iteration, you can add fixlastline="yes" property. Confusingly, all values for "yes/no", instead of "true/false". I don't know, I might have missed the meeting where they decided that's the convention. Another side note - fixlastline doesn't work for embedded content (reference). To force a line break you can apply ${line.separator}.
  • To get link attributes (like target="_blank") to work with asciidoctor I had to add the :linkattrs: property in content areas where I needed them to be interpreted. I'm sure there's a better, more maven-y way to do it.
  • Last lesson: in asciidoc it's important that a heading's 'underline' should have the same character length as the actual heading itself. This is important.

maven-clean

 <plugin>
                <artifactId>maven-clean-plugin</artifactId>
                <version>2.4.1</version>
                <executions>
                    <execution>
                        <id>clean-docs</id>
                        <phase>clean</phase>
                        <goals>
                            <goal>clean</goal>
                        </goals>
                        <configuration>
                            <failOnError>true</failOnError>
                            <verbose>true</verbose>
                            <followSymLinks>true</followSymLinks>
                            <filesets>
                                <fileset>
                                <directory>${project.basedir}/src/site/asciidoc/</directory>
                                    <includes>
                                        <include>collection/result.adoc</include>   
                                    </includes>
                                </fileset>
                            </filesets>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

Need to clean up concatenated files? maven-clean is your friend.

  • Here we're binding the maven-clean operation to it's default lifecycle, which is, conveniently, $ mvn clean.
  • Includes/excludes here behave the same as in ant-concat. You can pretty much specify which directories/files should be included/excluded. In our example, collection/result.adoc will be destroyed on each clean lifecycle.
  • I had to set followSymLinks to 'true' to get directory-specific targets (see above) to work.

In addition to these tricks, there are a myriad of asciidoc/asciidoctor tips (some of which I've alluded to so far) that I might cover in a next post.