Dec 17, 2012

Using Ant Paths with the Grails Resources Plugin

My current project is a single-page Grails application that contains a lot of static resources. I’m using the standard Resources plugin and have found myself spending a lot of time keeping the plugin’s config file in sync with my application’s files. I want to try to minimize this hassle by using convention where I can.

Here is an example of how my configuration is set up.

The is a contrived example, but it is very similar to the one I am currently using. As you can see, there is one core module at the top and then a module for each domain. Each module contains a mix of CoffeeScript, LESS, and Handlebars.js templates. Note the dummy.css files at the end of each module. These are here to make sure the plugin bundles the LESS files properly, see this bug.

Support for Ant Paths

The first thing I want to do is try to convert some of these calls to use Ant paths so I don’t have to explicitly declare each file. It turns out that this is not supported by the Resources plugin directly. There is a Jira issue here with a similar request, but it’s over a year old.

Since the config file uses Groovy, we can add support ourselves by creating a function that will locate the files. With the help of this stackoverflow post, I’ve created a function that will create a Set of files similar to the behavior of Ant‘s fileSet.

This will find all the files in the given directory matching the includes pattern. I’ve put this method into a util class and imported it into the config file. Now applying the method to the existing configuration yields this.

Note that I didn’t apply the fileSet method to anything in the core module, because it cares about the file order. We can apply it to the other modules, though, and now the file is shorter and requires less maintenance. But there is still another step we can take.

Using a Common Module Template

You may have noticed that the domain modules in the configuration all follow the same pattern. Handlebars files in ‘/templates/$domain’, LESS files in ‘/css/app/$domain’, etc… Once again we can use Groovy to help us by adding a closure to create a common module template.

After applying this to our config, we now are left with this.

This greatly simplifies our configuration and makes the structure of our files more obvious.

Detecting New Files

One caveat with this approach is that adding new files will not trigger the Resources plugin to reload the modules. It only watches files that are included when the config is parsed. One way to add this functionality is to create a DirectoryWatcher in BootStrap.groovy.

This is not perfect as it will reload all modules, not just the affected ones, so there is still some room for optimization.

With a few lines of Groovy, we’ve made our config file more maintainable, simplified our development process a bit, and created a template that will help make sure our application’s resources continue to follow a logical pattern.

A working example app can be found here.

About the Author

admin profile.

One thought on “Using Ant Paths with the Grails Resources Plugin

  1. Some great ideas you have here. Thanks for sharing.

    One suggestion though. Why not put your module definition into the ResourcesPluginUtils as a static methode:

    static module(name) {
    return { name -> /* closure content */ }
    }

    I think that would work, making your resources file even more clean.

    Then it starts to “smell” like a plugin 🙂

    /Søren

  2. msheehan says:

    Thanks for the comment. You could definitely pull that into the util, though the module closure content may vary by project.

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Blog Posts
Android Development for iOS Developers
Android development has greatly improved since the early days. Maybe you tried it out when Android development was done in Eclipse, emulators were slow and buggy, and Java was the required language. Things have changed […]
Add a custom object to your Liquibase diff
Adding a custom object to your liquibase diff is a pretty simple two step process. Create an implementation of DatabaseObject Create an implementation of SnapshotGenerator In my case I wanted to add tracking of Stored […]
Keeping Secrets Out of Terraform State
There are many instances where you will want to create resources via Terraform with secrets that you just don’t want anyone to see. These could be IAM credentials, certificates, RDS DB credentials, etc. One problem […]
Validating Terraform Plans using Open Policy Agent
When developing infrastructure as code using terraform, it can be difficult to test and validate changes without executing the code against a real environment. The feedback loop between writing a line of code and understanding […]