Codenarc Revisited - Gr8Conf US 2016

Codenarc Revisited - Gr8Conf US 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

July 28, 2016
Tweet

Transcript

  1. Codenarc Revisited Jenn Strater @codeJENNerator

  2. @codeJENNerator 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. @codeJENNerator About Me

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

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

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

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

  8. @codeJENNerator Background • Spring Boot with Groovy

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

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

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

    Groovy • Grails • Anything Else?
  12. @codeJENNerator What is ?

  13. @codeJENNerator 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. @codeJENNerator

  15. @codeJENNerator • Website • codenarc.sourceforge.net

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

  17. @codeJENNerator

  18. @codeJENNerator • Mailing List • https://sourceforge.net/p/codenarc/mailman

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

    Chris Mair
  20. @codeJENNerator Why use Codenarc? • Improves readability • Saves time

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

  23. None
  24. @codeJENNerator

  25. @codeJENNerator def someMethod(def something, def somethingElse) {
 if (something) {


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


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


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

  29. @codeJENNerator

  30. @codeJENNerator println “This is an unnecessary Groovy String”


  31. @codeJENNerator

  32. @codeJENNerator this.something.getThisThing()

  33. @codeJENNerator New Team Member

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

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

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

    Devs converting to Groovy • New Team Members • YOU!
  37. @codeJENNerator Approaches

  38. @codeJENNerator Approaches • Start with one project or team

  39. @codeJENNerator Approaches • Start with one project or team •

    Turn on all rules
  40. @codeJENNerator Approaches • Start with one project or team •

    Turn on all rules • Look at all of the violations
  41. @codeJENNerator 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
  42. @codeJENNerator 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
  43. @codeJENNerator 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
  44. None
  45. @codeJENNerator Approaches • Turn on all the rules • Set

    a violation limit and fail builds that add go above the limit
  46. @codeJENNerator Basics https://flic.kr/p/oiAEx6

  47. @codeJENNerator What is a rule?

  48. @codeJENNerator What is a rule? MissingBlankLineAfterPackage

  49. @codeJENNerator What is a rule? MissingBlankLineAfterPackage package org.codenarc
 import java.util.Date

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

  51. @codeJENNerator What is a ruleset? Formatting Rules ("rulesets/formatting.xml")

  52. @codeJENNerator Rule Configuration

  53. @codeJENNerator Rule Configuration • Priority

  54. @codeJENNerator Rule Configuration • Priority • ViolationMessage

  55. @codeJENNerator Rule Configuration • Priority • ViolationMessage • Description

  56. @codeJENNerator Rule Configuration • Priority • ViolationMessage • Description •

    Name
  57. @codeJENNerator Rule Configuration

  58. @codeJENNerator Rule Configuration • Custom Parameters

  59. @codeJENNerator Rule Configuration • Custom Parameters • applyToClassNames

  60. @codeJENNerator Rule Configuration • Custom Parameters • applyToClassNames • applyToFileNames

  61. @codeJENNerator Ways to add codenarc to your project

  62. @codeJENNerator • runs with gradle check https://docs.gradle.org/current/userguide/codenarc_plugin.html

  63. @codeJENNerator Config Options

  64. @codeJENNerator Config Options • configFile • ignoreFailures • maxPriority1Violations •

    maxPriority2Violations • maxPriority3Violations
  65. @codeJENNerator Config Options

  66. @codeJENNerator Config Options • reportFormat • reportsDir • sourceSets •

    toolVersion
  67. @codeJENNerator

  68. @codeJENNerator codenarc {
 toolVersion = '0.25.2'
 }
 
 codenarcMain {


    configFile file('config/codenarc/codenarc.groovy')
 }
 
 codenarcTest {
 configFile file('config/codenarc/codenarcTest.groovy')
 }
  69. @codeJENNerator • Grails Projects Version < 3.0 • runs with

    grails codenarc http://grails.org/plugin/codenarc Plugin
  70. @codeJENNerator Other Codenarc Plugins

  71. @codeJENNerator Other Codenarc Plugins • IDEs • IntelliJ • Eclipse

  72. @codeJENNerator Other Codenarc Plugins • IDEs • IntelliJ • Eclipse

    • Sonar
  73. @codeJENNerator Other Codenarc Plugins • IDEs • IntelliJ • Eclipse

    • Sonar • Maven
  74. @codeJENNerator Other Codenarc Plugins • IDEs • IntelliJ • Eclipse

    • Sonar • Maven • Jenkins (formerly Hudson)
  75. @codeJENNerator Reports

  76. @codeJENNerator build/reports/codenarc/main.html

  77. @codeJENNerator Jenkins Violations Plugin img src: https://leanjavaengineering.wordpress.com/2010/08/25/grails-codenarc-hudson/

  78. @codeJENNerator Starter Ruleset http://codenarc.sourceforge.net/StarterRuleSet- AllRulesByCategory.groovy.txt https://flic.kr/p/c8QjRC

  79. @codeJENNerator 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 . . . }
  80. @codeJENNerator Turning Off Rules - Comments ruleset { /* //

    rulesets/braces.xml
 ElseBlockBraces(bracesRequiredForElseIf: true)
 ForStatementBraces
 IfStatementBraces
 WhileStatementBraces */ }
  81. @codeJENNerator Turning Off Rules - Enabled:False ruleset { ruleset('rulesets/basic.xml') {

    CatchThrowable(enabled:false) } }
  82. @codeJENNerator Suppress Warnings 
 
 @SuppressWarnings('DuplicateStringLiteral')
 class MyClass {
 def

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

  84. @codeJENNerator 0.21 • No Wildcard Imports • Lots of New

    Formatting Rules • Consecutive Blank Lines • Blank Line Before Package • FileEndsWithoutNewline
  85. @codeJENNerator 0.22 • No Def • Unnecessary Safe Navigation Operator

  86. @codeJENNerator 0.23 • Nested For Loop

  87. @codeJENNerator 0.25 • No Tab Character • Trailing Comma

  88. @codeJENNerator Each Release Improves Existing Rules https://flic.kr/p/3mPXcD

  89. @codeJENNerator Rules Worth Talking About

  90. @codeJENNerator File Ends Without NewLine

  91. @codeJENNerator I don’t like all of the Codenarc Rules! img

    src: https://flic.kr/p/rehEf5
  92. @codeJENNerator Dry • DuplicateListLiteral • DuplicateMapLiteral • DuplicateNumberLiteral • DuplicateStringLiteral

  93. @codeJENNerator Could Be Elvis Lots of false positives

  94. @codeJENNerator JUnit Ruleset Doesn’t work well with Spock

  95. @codeJENNerator No Def https://flic.kr/p/apRkJh

  96. @codeJENNerator No Def • Great for Spring Boot https://flic.kr/p/apRkJh

  97. @codeJENNerator No Def • Great for Spring Boot • Problematic

    with Grails https://flic.kr/p/apRkJh
  98. @codeJENNerator Good in Theory

  99. @codeJENNerator Good in Theory • Unnecessary Return

  100. @codeJENNerator Good in Theory • Unnecessary Return • Line Length

  101. @codeJENNerator Debatable

  102. @codeJENNerator Debatable • Unnecessary Groovy String

  103. @codeJENNerator Debatable • Unnecessary Groovy String • Unnecessary Getter

  104. @codeJENNerator Debatable

  105. @codeJENNerator Debatable • Misordered Static Imports

  106. @codeJENNerator Debatable • Misordered Static Imports • No Wildcard Imports

  107. @codeJENNerator Still Deciding

  108. @codeJENNerator Still Deciding • Complexity Metrics

  109. @codeJENNerator WARNING! • Enhanced Ruleset does not work with the

    gradle codenarc plugin • https://objectpartners.com/2016/03/16/resolving- codenarc-compilation-warnings/
  110. @codeJENNerator 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)
 }
 }
 }
 }
 }
  111. @codeJENNerator Contribute • http://codenarc.sourceforge.net/codenarc- developer-guide.html • https://github.com/CodeNarc/CodeNarc

  112. @codeJENNerator Read the docs for more on.. • Rule Specifics

    • Ant Task • Command Line
  113. @codeJENNerator 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
  114. @codeJENNerator Conclusion

  115. @codeJENNerator Questions? https://flic.kr/p/5DeuzB