Slide 1

Slide 1 text

Codenarc Revisited Jenn Strater @codeJENNerator

Slide 2

Slide 2 text

@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

Slide 3

Slide 3 text

@codeJENNerator About Me

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

@codeJENNerator About Me • Senior Consultant at Object Partners, Inc. • Co-Founder of Gr8Ladies • 2016 - 2017 Fulbright US Student Program Selectee to Denmark

Slide 7

Slide 7 text

@codeJENNerator Background

Slide 8

Slide 8 text

@codeJENNerator Background • Spring Boot with Groovy

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

@codeJENNerator Background • Spring Boot with Groovy • Ratpack with Groovy • Grails • Anything Else?

Slide 12

Slide 12 text

@codeJENNerator What is ?

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

@codeJENNerator

Slide 15

Slide 15 text

@codeJENNerator • Website • codenarc.sourceforge.net

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

@codeJENNerator

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

@codeJENNerator Why use Codenarc? • Improves readability • Saves time with code reviews • Code with fewer bugs • Help onboard new team members

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

@codeJENNerator .equals instead of ==

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

@codeJENNerator

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

@codeJENNerator The Convert

Slide 29

Slide 29 text

@codeJENNerator

Slide 30

Slide 30 text

@codeJENNerator println “This is an unnecessary Groovy String”


Slide 31

Slide 31 text

@codeJENNerator

Slide 32

Slide 32 text

@codeJENNerator this.something.getThisThing()

Slide 33

Slide 33 text

@codeJENNerator New Team Member

Slide 34

Slide 34 text

@codeJENNerator if(true) { } vs if (true) { } vs if (ready){ }

Slide 35

Slide 35 text

@codeJENNerator Leaning Tower of Code https://flic.kr/p/de4pmb

Slide 36

Slide 36 text

@codeJENNerator Summary • Useful For: • Interns/Junior Devs • Java Devs converting to Groovy • New Team Members • YOU!

Slide 37

Slide 37 text

@codeJENNerator Approaches

Slide 38

Slide 38 text

@codeJENNerator Approaches • Start with one project or team

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

@codeJENNerator Approaches • Start with one project or team • Turn on all rules • Look at all of the violations

Slide 41

Slide 41 text

@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

Slide 42

Slide 42 text

@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

Slide 43

Slide 43 text

@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

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

@codeJENNerator Approaches • Turn on all the rules • Set a violation limit and fail builds that add go above the limit

Slide 46

Slide 46 text

@codeJENNerator Basics https://flic.kr/p/oiAEx6

Slide 47

Slide 47 text

@codeJENNerator What is a rule?

Slide 48

Slide 48 text

@codeJENNerator What is a rule? MissingBlankLineAfterPackage

Slide 49

Slide 49 text

@codeJENNerator What is a rule? MissingBlankLineAfterPackage package org.codenarc
 import java.util.Date // violation
 
 class MyClass {
 void go() { /* ... */ }
 }

Slide 50

Slide 50 text

@codeJENNerator What is a ruleset?

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

@codeJENNerator Rule Configuration

Slide 53

Slide 53 text

@codeJENNerator Rule Configuration • Priority

Slide 54

Slide 54 text

@codeJENNerator Rule Configuration • Priority • ViolationMessage

Slide 55

Slide 55 text

@codeJENNerator Rule Configuration • Priority • ViolationMessage • Description

Slide 56

Slide 56 text

@codeJENNerator Rule Configuration • Priority • ViolationMessage • Description • Name

Slide 57

Slide 57 text

@codeJENNerator Rule Configuration

Slide 58

Slide 58 text

@codeJENNerator Rule Configuration • Custom Parameters

Slide 59

Slide 59 text

@codeJENNerator Rule Configuration • Custom Parameters • applyToClassNames

Slide 60

Slide 60 text

@codeJENNerator Rule Configuration • Custom Parameters • applyToClassNames • applyToFileNames

Slide 61

Slide 61 text

@codeJENNerator Ways to add codenarc to your project

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

@codeJENNerator Config Options

Slide 64

Slide 64 text

@codeJENNerator Config Options • configFile • ignoreFailures • maxPriority1Violations • maxPriority2Violations • maxPriority3Violations

Slide 65

Slide 65 text

@codeJENNerator Config Options

Slide 66

Slide 66 text

@codeJENNerator Config Options • reportFormat • reportsDir • sourceSets • toolVersion

Slide 67

Slide 67 text

@codeJENNerator

Slide 68

Slide 68 text

@codeJENNerator codenarc {
 toolVersion = '0.25.2'
 }
 
 codenarcMain {
 configFile file('config/codenarc/codenarc.groovy')
 }
 
 codenarcTest {
 configFile file('config/codenarc/codenarcTest.groovy')
 }

Slide 69

Slide 69 text

@codeJENNerator • Grails Projects Version < 3.0 • runs with grails codenarc http://grails.org/plugin/codenarc Plugin

Slide 70

Slide 70 text

@codeJENNerator Other Codenarc Plugins

Slide 71

Slide 71 text

@codeJENNerator Other Codenarc Plugins • IDEs • IntelliJ • Eclipse

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

@codeJENNerator Other Codenarc Plugins • IDEs • IntelliJ • Eclipse • Sonar • Maven • Jenkins (formerly Hudson)

Slide 75

Slide 75 text

@codeJENNerator Reports

Slide 76

Slide 76 text

@codeJENNerator build/reports/codenarc/main.html

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

@codeJENNerator Turning Off Rules - Enabled:False ruleset { ruleset('rulesets/basic.xml') { CatchThrowable(enabled:false) } }

Slide 82

Slide 82 text

@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')
 }
 }

Slide 83

Slide 83 text

https://flic.kr/p/rmit9T

Slide 84

Slide 84 text

@codeJENNerator 0.21 • No Wildcard Imports • Lots of New Formatting Rules • Consecutive Blank Lines • Blank Line Before Package • FileEndsWithoutNewline

Slide 85

Slide 85 text

@codeJENNerator 0.22 • No Def • Unnecessary Safe Navigation Operator

Slide 86

Slide 86 text

@codeJENNerator 0.23 • Nested For Loop

Slide 87

Slide 87 text

@codeJENNerator 0.25 • No Tab Character • Trailing Comma

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

@codeJENNerator Rules Worth Talking About

Slide 90

Slide 90 text

@codeJENNerator File Ends Without NewLine

Slide 91

Slide 91 text

@codeJENNerator I don’t like all of the Codenarc Rules! img src: https://flic.kr/p/rehEf5

Slide 92

Slide 92 text

@codeJENNerator Dry • DuplicateListLiteral • DuplicateMapLiteral • DuplicateNumberLiteral • DuplicateStringLiteral

Slide 93

Slide 93 text

@codeJENNerator Could Be Elvis Lots of false positives

Slide 94

Slide 94 text

@codeJENNerator JUnit Ruleset Doesn’t work well with Spock

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

@codeJENNerator Good in Theory

Slide 99

Slide 99 text

@codeJENNerator Good in Theory • Unnecessary Return

Slide 100

Slide 100 text

@codeJENNerator Good in Theory • Unnecessary Return • Line Length

Slide 101

Slide 101 text

@codeJENNerator Debatable

Slide 102

Slide 102 text

@codeJENNerator Debatable • Unnecessary Groovy String

Slide 103

Slide 103 text

@codeJENNerator Debatable • Unnecessary Groovy String • Unnecessary Getter

Slide 104

Slide 104 text

@codeJENNerator Debatable

Slide 105

Slide 105 text

@codeJENNerator Debatable • Misordered Static Imports

Slide 106

Slide 106 text

@codeJENNerator Debatable • Misordered Static Imports • No Wildcard Imports

Slide 107

Slide 107 text

@codeJENNerator Still Deciding

Slide 108

Slide 108 text

@codeJENNerator Still Deciding • Complexity Metrics

Slide 109

Slide 109 text

@codeJENNerator WARNING! • Enhanced Ruleset does not work with the gradle codenarc plugin • https://objectpartners.com/2016/03/16/resolving- codenarc-compilation-warnings/

Slide 110

Slide 110 text

@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)
 }
 }
 }
 }
 }

Slide 111

Slide 111 text

@codeJENNerator Contribute • http://codenarc.sourceforge.net/codenarc- developer-guide.html • https://github.com/CodeNarc/CodeNarc

Slide 112

Slide 112 text

@codeJENNerator Read the docs for more on.. • Rule Specifics • Ant Task • Command Line

Slide 113

Slide 113 text

@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

Slide 114

Slide 114 text

@codeJENNerator Conclusion

Slide 115

Slide 115 text

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