Quick tip: generate a README.md from a POM

In these days I'm sorting out my code repositories, in particular by definitely tagging as "legacy" those that are dead and converting to Git the others (I've still a strong preference towards Mercurial, but in the end most people use Git and some of my pet projects are also used as mentoring resources), a move that also made it possible to replicate the repositories to GitHub (my primary repository remains BitBucket though).

As part of the sorting up, I realised that most of my projects lacked a decent README file, that both BitBucket and GitHub render in the home page of the project as a nice introduction. A good README should contain both the description of the project and a few practical information, such as linking the issue tracker and a other relevant stuff, as well as provide information for quickly booting the project - in the case of a project whose artifacts are released through the Maven Repo Central, essentially you have to give their GAV coordinates. Furthermore, Shields.io provides a funny set of dynamic badges that can be populated with some info, such as the latest release deployed or information from a CI server.

Of course a consistent structure for a README should be provided for all of my projects and since I'm a lazy guy I really respect the DRY (Don't Repeat Yourself) principle, so I don't want to copy & paste the description of the project from the POM. Recognising that all the required metadata for what I need are precisely in the POM, the idea is obvious: have a tool to create the README from the POM.

As usual, before creating something new it makes sense to search for a solution that someone perhaps already made. I found a Maven plugin made by the Apache Foundation, that they appear to use for their projects, but unfortunately it uses a template whose source is a URL hard-wired in the plugin, without the possibility to be overridden.

But before starting and writing my own plugin, I realised that a simple solution was straightforward: use the maven-resource-plugin. In fact it is able to copy a resource to a destination folder after having interpolated some properties defined in the POM. So I added this profile to my SuperPOM:

<profile>
                        <id>it.tidalwave-generate-readme-md-v1</id>
                        <build>
                            <defaultGoal>dependency:unpack resources:copy-resources</defaultGoal>
                            <plugins>
                                <plugin>
                                    <groupId>org.apache.maven.plugins</groupId>
                                    <artifactId>maven-dependency-plugin</artifactId>
                                    <configuration>
                                        <artifactItems>
                                            <artifactItem>
                                                <groupId>it.tidalwave.thesefoolishthings</groupId>
                                                <artifactId>superpom-config</artifactId>
                                                <version>${tft.superpom.config.version}</version>
                                                <type>jar</type>
                                                <overWrite>true</overWrite>
                                                <outputDirectory>${project.basedir}/target/superpom-resources</outputDirectory>
                                            </artifactItem>
                                        </artifactItems>
                                    </configuration>
                                </plugin>
                                <plugin>
                                    <groupId>org.apache.maven.plugins</groupId>
                                    <artifactId>maven-resources-plugin</artifactId>
                                    <configuration>
                                        <resources>
                                            <resource>
                                                <directory>${project.basedir}/target/superpom-resources/it/tidalwave/readme/</directory>
                                                <filtering>true</filtering>
                                            </resource>
                                        </resources>
                                        <outputDirectory>.</outputDirectory>
                                    </configuration>
                                </plugin>
                            </plugins>
                        </build>
                    </profile>

It downloads and unpacks the template file (which is a README.md file under the directory it/tidalwave/readme) from another artefact previously deployed (it.tidalwave.thesefoolishthings:superpom-config) and copies it into the current directory. This is an excerpt of the template:

![Maven Central](https://img.shields.io/maven-central/v/${project.groupId}/${project.artifactId}.svg)
                    [![Build Status](https://img.shields.io/jenkins/s/http/services.tidalwave.it/ci/${tidalwave.ci.view}_Build_from_Scratch.svg)](${project.ciManagement.url})
                    [![Test Status](https://img.shields.io/jenkins/t/http/services.tidalwave.it/ci/${tidalwave.ci.view}.svg)](${project.ciManagement.url})
                    [![Coverage](https://img.shields.io/jenkins/c/http/services.tidalwave.it/ci/${tidalwave.ci.view}.svg)](${project.ciManagement.url})

                    ${project.name}
                    ================================

                    ${project.description}


                    Bootstrapping
                    -------------

                    In order to build the project, run from the command line:

                    ```mvn -DskipTests```

                    The project can be opened and built by a recent version of the NetBeans, Eclipse or Idea IDEs.


                    Documentation
                    -------------

                    More information can be found on the [homepage](${project.url}) of the project.

                    ...

As you can see the required metadata can be inserted by using the syntax ${project.description}. BTW, that specific property makes it possible to reuse the description of the project that is already in the POM, that at this point can be comfortably written in markdown syntax. All I need to do is running from the top directory of each project:

mvn -Pit.tidalwave-generate-readme-md-v1 -N

and the README.md is locally (re)created, ready to be committed and pushed. Too bad the coverage badge is broken because of a issue with my Jenkins, but it's another story.

Comments are managed by Disqus, which makes use of a few cookies. Please read their cookie policy for more details. If you agree to that policy, please click on the button below to accept it. If you don't, you can still enjoy this site without using Disqus cookies, but you won't be able to see and post comments. Thanks.