Codenarc Revisited - Gr8Conf EU 2016

Codenarc Revisited - Gr8Conf EU 2016

Codenarc Revisited
------------
When was the last time you looked at code quality? Do you have some old codenarc configuration with half(or more!) of the rules turned off because they were reporting false positives? Or maybe you have @SupressWarnings all over your code? Or perhaps you want to do something small like to enforce tabs vs spaces for all members of your team?

Codenarc is a static analysis tool for Groovy that enforces style, detects bad practices, and suggests improvements. If it has been awhile since you last looked at codenarc, there might be new rules or configuration options to get you back on the path to better code quality. This session will explore what is new with codenarc, options for specific groovy ecosystem projects such as grails, and walk through how to create custom rules for your own project.
------------
Jennifer “Jenn” Strater is a software engineer with a passion for developing and designing applications using new and innovative technologies. Her strengths are in the service layer including building RESTful APIs. Jenn also has experience with relational and NoSQL databases, devops, front-end, and mobile in the healthcare and transportation industries. She learns new tools and systems quickly and introduces new technology learned through local community groups, involvement in the international Groovy community, and when speaking at or attending regional, national, and international conferences.

Jenn is the co-founder of the organization Gr8Ladies and has organized Gr8Workshops for developers interested in an overview and crash course in Groovy technologies. She has presented at various Minnesota tech events, the Grace Hopper Celebration of Women in Computing, Greach, Gr8Conf EU, Gr8Conf US, and Devoxx Belgium.

Starting in September, Jenn will be a master's student at the Technical University of Denmark studying static analysis and compilers with a focus on Groovy with funding from the Fulbright U.S. student program.

1f28a0c1988421be3268026bd6bb6f49?s=128

jlstrater

June 03, 2016
Tweet

Transcript

  1. Codenarc Revisited Jenn Strater @codeJENNerator

  2. Follow Along • https://github.com/jlstrater/gr8data/tree/master/config/codenarc • https://github.com/jlstrater/groovy-spring-boot-restdocs- example/tree/master/gradle/codenarc

  3. About Me

  4. About Me • Senior Consultant at Object Partners, Inc.

  5. About Me • Senior Consultant at Object Partners, Inc. •

    Co-Founder of Gr8Ladies
  6. About Me • Senior Consultant at Object Partners, Inc. •

    Co-Founder of Gr8Ladies • 2016 - 2017 Fulbright US Student Program Selectee to Denmark
  7. Background

  8. Background • Spring Boot with Groovy

  9. Background • Spring Boot with Groovy • Ratpack with Groovy

  10. Background • Spring Boot with Groovy • Ratpack with Groovy

    • Grails
  11. Background • Spring Boot with Groovy • Ratpack with Groovy

    • Grails • Anything Else?
  12. What is ?

  13. https://github.com/CodeNarc/CodeNarc “CodeNarc is a static analysis tool for Groovy source

    code, enabling monitoring and enforcement of many coding standards and best practices… CodeNarc is similar to popular static analysis tools such as PMD or Checkstyle. Unlike those tools which analyze Java code, CodeNarc analyzes Groovy code.”
  14. None
  15. • Website • codenarc.sourceforge.net

  16. • Website • codenarc.sourceforge.net • Current Version • 0.25.2

  17. None
  18. • Mailing List • https://sourceforge.net/p/codenarc/mailman

  19. • Mailing List • https://sourceforge.net/p/codenarc/mailman • Project Admin • Chris

    Mair
  20. Why use Codenarc? • Improves readability • Saves time with

    code reviews • Code with fewer bugs • Help onboard new team members
  21. None
  22. .equals instead of ==

  23. None
  24. None
  25. def someMethod(def something, def somethingElse) {
 if (something) {
 doSomething()


    }
 else if(somethingElse) {
 doSomethingElse()
 }
 }
  26. def someMethod(def something, def somethingElse) {
 if (something) {
 doSomething()


    }
 else if(somethingElse) {
 doSomethingElse()
 }
 }
  27. def someMethod(def something, def somethingElse) {
 if (something) {
 doSomething()


    }
 else if(somethingElse) {
 doSomethingElse()
 }
 }
  28. The Convert

  29. None
  30. println “This is an unnecessary Groovy String”


  31. None
  32. this.something.getThisThing()

  33. New Team Member

  34. if(true) { } vs if (true) { } vs if

    (ready){ }
  35. Leaning Tower of Code https://flic.kr/p/de4pmb

  36. Summary • Useful For: • Interns/Junior Devs • Java Devs

    converting to Groovy • New Team Members • YOU!
  37. Approaches • Start with one project or team • Turn

    on all rules • Look at all of the violations • Turn off rules that don’t make sense for your team • Fix all the problems • Once you have a good set of rules with minimal false positives, set that as the standard for all teams using Groovy
  38. None
  39. Approaches • Turn on all the rules • Set a

    violation limit and fail builds that add go above the limit
  40. Basics https://flic.kr/p/oiAEx6

  41. What is a rule?

  42. What is a rule? MissingBlankLineAfterPackage

  43. What is a rule? MissingBlankLineAfterPackage package org.codenarc
 import java.util.Date //

    violation
 
 class MyClass {
 void go() { /* ... */ }
 }
  44. What is a ruleset?

  45. What is a ruleset? Formatting Rules ("rulesets/formatting.xml")

  46. Rule Configuration

  47. Rule Configuration • Priority

  48. Rule Configuration • Priority • ViolationMessage

  49. Rule Configuration • Priority • ViolationMessage • Description

  50. Rule Configuration • Priority • ViolationMessage • Description • Name

  51. Rule Configuration

  52. Rule Configuration • Parameters

  53. Rule Configuration • Parameters • applyToClassNames

  54. Rule Configuration • Parameters • applyToClassNames • applyToFileNames

  55. • runs with gradle check https://docs.gradle.org/current/userguide/codenarc_plugin.html

  56. Config Options

  57. Config Options • configFile • ignoreFailures • maxPriority1Violations • maxPriority2Violations

    • maxPriority3Violations
  58. Config Options

  59. Config Options • reportFormat • reportsDir • sourceSets • toolVersion

  60. None
  61. codenarc {
 toolVersion = '0.25.2'
 }
 
 codenarcMain {
 configFile

    file('config/codenarc/codenarc.groovy')
 }
 
 codenarcTest {
 configFile file('config/codenarc/codenarcTest.groovy')
 }
  62. Starter Ruleset http://codenarc.sourceforge.net/StarterRuleSet- AllRulesByCategory.groovy.txt https://flic.kr/p/c8QjRC

  63. config/codenarc/codenarc.groovy ruleset {
 // rulesets/basic.xml
 AssertWithinFinallyBlock
 AssignmentInConditional
 BigDecimalInstantiation
 BitwiseOperatorInConditional
 BooleanGetBoolean


    BrokenNullCheck
 BrokenOddnessCheck
 ClassForName
 ComparisonOfTwoConstants
 ComparisonWithSelf
 ConstantAssertExpression
 ConstantIfExpression
 ConstantTernaryExpression
 . . . // rulesets/braces.xml
 ElseBlockBraces(bracesRequiredForElseIf: true)
 ForStatementBraces
 IfStatementBraces
 WhileStatementBraces . . . }
  64. Turning Off Rules - Comments ruleset { /* // rulesets/braces.xml


    ElseBlockBraces(bracesRequiredForElseIf: true)
 ForStatementBraces
 IfStatementBraces
 WhileStatementBraces */ }
  65. Turning Off Rules - Enabled:False ruleset { ruleset('rulesets/basic.xml') { CatchThrowable(enabled:false)

    } }
  66. Suppress Warnings 
 
 @SuppressWarnings('DuplicateStringLiteral')
 class MyClass {
 def y

    = 'x'
 def z = 'x'
 
 @SuppressWarnings(['IfStatementBraces', 'ThrowException'])
 int getCount() {
 if (!ready) throw new Exception('Not ready')
 }
 }
  67. https://flic.kr/p/rmit9T

  68. 0.21 • No Wildcard Imports • Lots of New Formatting

    Rules • Consecutive Blank Lines • Blank Line Before Package • FileEndsWithoutNewline
  69. 0.22 • No Def • Unnecessary Safe Navigation Operator

  70. 0.23 • Nested For Loop

  71. 0.25 • No Tab Character • Trailing Comma

  72. Each Release Improves Existing Rules https://flic.kr/p/3mPXcD

  73. Rules Worth Talking About

  74. File Ends Without NewLine

  75. I don’t like all of the Codenarc Rules! img src:

    https://flic.kr/p/rehEf5
  76. Dry • DuplicateListLiteral • DuplicateMapLiteral • DuplicateNumberLiteral • DuplicateStringLiteral

  77. Could Be Elvis Lots of false positives

  78. JUnit Ruleset Doesn’t work well with Spock

  79. No Def https://flic.kr/p/apRkJh

  80. No Def • Great for Spring Boot https://flic.kr/p/apRkJh

  81. No Def • Great for Spring Boot • Problematic with

    Grails https://flic.kr/p/apRkJh
  82. Good in Theory

  83. Good in Theory • Unnecessary Return

  84. Good in Theory • Unnecessary Return • Line Length

  85. Debatable

  86. Debatable • Unnecessary Groovy String

  87. Debatable • Unnecessary Groovy String • Unnecessary Getter

  88. Debatable

  89. Debatable • Misordered Static Imports

  90. Debatable • Misordered Static Imports • No Wildcard Imports

  91. Still Deciding

  92. Still Deciding • Complexity Metrics

  93. WARNING! • Enhanced Ruleset does not work with the gradle

    codenarc plugin • https://objectpartners.com/2016/03/16/resolving- codenarc-compilation-warnings/
  94. Reports

  95. build/reports/codenarc/main.html

  96. Create a Custom Rule import org.codenarc.rule.AbstractRule
 import org.codenarc.source.SourceCode
 
 /**


    * Sample rule. Checks for static fields.
 */
 class MyStaticFieldRule extends AbstractRule {
 String name = 'MyStaticField'
 int priority = 2
 
 void applyTo(SourceCode sourceCode, List violations) {
 sourceCode.ast.classes.each { clazz ->
 clazz.fields.each { fieldNode ->
 if (fieldNode.static) {
 violations << createViolation(sourceCode, fieldNode)
 }
 }
 }
 }
 }
  97. Contribute • http://codenarc.sourceforge.net/codenarc- developer-guide.html • https://github.com/CodeNarc/CodeNarc

  98. Read the docs for more on.. • Rule Specifics •

    Ant Task • Command Line
  99. Example Rulesets • Grails • https://github.com/jlstrater/gr8data/tree/master/ config/codenarc • Spring Boot

    • https://github.com/jlstrater/groovy-spring-boot- restdocs-example/tree/master/gradle/codenarc
  100. Conclusion

  101. Questions? https://flic.kr/p/5DeuzB