Checking Groovy code's quality with CodeNarc

As soon as you finish writing your first Groovy scripts or classes, you will probably start wondering how Groovy pros write their code and what are the best practices they are using. One way would be to learn by peeking at the best Groovy code bases (for example, Groovy itself: https://github.com/groovy/groovy-core/tree/master/src/main/groovy). Another way can be using code analysis tools that let you catch common coding mistakes that are already well-known in the community.

In the Java language world, there are many open source static code analysis tools such as PMD (Project Mess Detector) (http://pmd.sourceforge.net/), Checkstyle (http://checkstyle.sourceforge.net/), FindBugs (http://findbugs.sourceforge.net/), and so on. There are also many commercial products and IDEs that support various types of Java source code analysis.

In that regard, Groovy is less rich, though it has one library called CodeNarc (http://codenarc.sourceforge.net). The library is already integrated into the most popular build tools including Ant (see the Integrating Groovy into the build process using Ant recipe), Maven (see the Integrating Groovy into the build process using Maven recipe), and Gradle (see the Integrating Groovy into the build process using Gradle recipe). Also, some IDEs have plugins for CodeNarc.

In this recipe, we will cover the typical use case for the CodeNarc command-line tool and show how it can help to improve your Groovy code and boost your skills with the language.

Getting ready

For the sake of demonstration, we will use the following Groovy script, which on purposely violates several coding rules that CodeNarc inspects:

import java.io.*;

public class DirListing {

  public static void main(String[] args) throws IOException {
    String path;
    if (args.length > 0) {
      path = args[0];
    } else {
      path = ".";
    }
    File directory = new File(path);
    File[] files = directory.listFiles();
    System.out.println("Directory of "
      + directory.getCanonicalFile().getAbsolutePath());
    for (int i = 0; i < files.length; i++) {
      if (files[i].isFile()) {
        File file = files[i];
        System.out.println(file.getName());
      }
    }
  }

}

In fact, the previous code is actually plain Java, but since Groovy almost fully supports Java syntax, the code will run under Groovy as well.

The task that is performed by the script is a simple directory file listing. The program takes a directory path as its first argument. If the argument is omitted, the current directory is used. All first-level file (not directory) names are printed to the standard output.

We assume that the script is placed in the src directory located in your current working folder.

How to do it...

We can launch the CodeNarc command-line interface using Groovy script with a little help from Grape (see the Simplifying dependency management with Grape recipe).

  1. Create a codenarc.groovy script in the current directory:
    @Grab('org.codenarc:CodeNarc:0.18.1')
    import org.codenarc.CodeNarc
    
    CodeNarc.main(args)
  2. Now you can start CodeNarc to get its default help message:
    groovy codenarc.groovy -help
    
  3. To get CodeNarc to generate a report for our poorly coded script, we need to pass more parameters to the codenarc.groovy script:
    groovy codenarc.groovy
        -rulesetfiles="rulesets/unnecessary.xml"
        -title="Directory Listing"
        -basedir=src
  4. This will generate an HTML report inside the current directory that looks like the following screenshot:
    How to do it...

How it works...

The violations that are reported are easy to fix, and most of them are self-explanatory.

As you probably noticed, we specified only one rule set file (rulesets/unnecessary.xml) as an input parameter to CodeNarc. That specific rule-set groups rules for redundant code and can be omitted or simplified. Writing redundant, non-idiomatic code is exactly what Java programmers will face during their early days of Groovy programming since Groovy accepts Java syntax.

As of writing CodeNarc has 300+ rules split into 21 major group (rule set). Each group has its own name that can be referred to in the form of rulesets/<name>.xml. All those rule files are part of the CodeNarc library, and you don't need to download them separately. More information on the existing rules can be found at http://codenarc.sourceforge.net/codenarc-rule-index.html.

Let's go through a few violations to give the reader a taste of Groovy:

  • The UnnecessarySemicolon violation indicates that we terminated our statement with a semicolon and that statement is the only statement on the line. In Groovy, you can omit the ; (semicolon) in these cases.
  • The UnnecessaryPublicModifier violation says that in Groovy, you can omit the public modifier for classes and methods since it's there by default.
  • The UnnecessaryGString violation warns you of the fact that you are using heavy GString to define String constants. GString, which is defined by the " (double quote), is useful when you need to insert variable expression (for example, ${name}) into the String. We discussed variable interpolation in the Using Java classes from Groovy recipe. In order to fix this warning, you just need to use a ' (single quote), which will create a normal String without further processing.
  • The UnnecessaryGetter warning simply notifies you about the fact that in Groovy, you can refer to a getter using a field notation; for example, x.name instead of x.getName().

If we just fix all those violations, our Groovy code will look as follows:

import java.io.*

class DirListing {

  static void main(String[] args) throws IOException {
    String path
    if (args.length > 0) {
      path = args[0]
    } else {
      path = '.'
    }
    File directory = new File(path)
    File[] files = directory.listFiles()
    def dirPath = directory.canonicalFile.absolutePath
    System.out.println("Directory of ${dirPath}")
    for (int i = 0; i < files.length; i++) {
      if (files[i].isFile()) {
        File file = files[i]
        System.out.println(file.name)
      }
    }
  }

}

There's more...

Similarly to spelling or grammar checkers, CodeNarc does not detect all possible styling/coding mistakes. So, there is still room for manual code reviews that may improve your code even more. CodeNarc can be an early indicator for the parts of the code base that need deeper analysis and refactoring.

By using some of the knowledge we've learned in this chapter, as well as the information that we will learn in Chapter 3, Using Groovy Language Features and Chapter 4, Working with Files in Groovy, we can rewrite the original code in a more idiomatic way:

def path = args.size() > 0 ? args[0] : '.'
def directory = new File(path)
def dirPath = directory.canonicalFile.absolutePath
println "Directory of ${dirPath}"
directory.eachFile { File file ->
  if (file.isFile()) {
    println file.name
  }
}

The previous code will produce the same result as our original and modified scripts.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.158.36