官术网_书友最值得收藏!

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 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.

主站蜘蛛池模板: 万安县| 平利县| 南雄市| 大田县| 内乡县| 云安县| 清丰县| 鄂伦春自治旗| 张北县| 古浪县| 社旗县| 尼勒克县| 武威市| 怀仁县| 元阳县| 封丘县| 犍为县| 桐城市| 永寿县| 商丘市| 林芝县| 苍山县| 大理市| 讷河市| 高要市| 洱源县| 霍林郭勒市| 自贡市| 乐都县| 盖州市| 星座| 青神县| 蓬溪县| 贵州省| 汶川县| 揭阳市| 定安县| 景洪市| 海晏县| 金沙县| 尉氏县|