- Groovy 2 Cookbook
- Andrey Adamovich Luciano Fiandesio
- 406字
- 2021-07-23 15:57:24
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).
- Create a
codenarc.groovy
script in the current directory:@Grab('org.codenarc:CodeNarc:0.18.1') import org.codenarc.CodeNarc CodeNarc.main(args)
- Now you can start CodeNarc to get its default help message:
groovy codenarc.groovy -help
- 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
- 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 heavyGString
to defineString
constants.GString
, which is defined by the"
(double quote), is useful when you need to insert variable expression (for example,${name}
) into theString
. 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 normalString
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 ofx.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.
See also
- CodeNarc's home page: http://codenarc.sourceforge.net/
- List of CodeNarc rules: http://codenarc.sourceforge.net/codenarc-rule-index.html
- CodeNarc's Ant task: http://codenarc.sourceforge.net/codenarc-ant-task.html
- Maven's plugin for CodeNarc: http://mojo.codehaus.org/codenarc-maven-plugin/
- Gradle's plugin for CodeNarc: http://www.gradle.org/docs/current/userguide/codenarc_plugin.html
- Clojure Programming Cookbook
- Learning PostgreSQL
- AngularJS Web Application Development Blueprints
- NLTK基礎教程:用NLTK和Python庫構建機器學習應用
- HTML5 Mobile Development Cookbook
- Python機器學習實戰
- Node.js:來一打 C++ 擴展
- Node.js開發指南
- 移動增值應用開發技術導論
- Orleans:構建高性能分布式Actor服務
- RubyMotion iOS Develoment Essentials
- 大學計算機基礎實驗指導
- Visual Basic程序設計全程指南
- Arduino機器人系統設計及開發
- Software-Defined Networking with OpenFlow(Second Edition)