Effective ways of enforcing coding standards

by Dmitry Pashkevich

About Me

Dmitry Pashkevich

  • Internet citizen
  • Passionate about web apps
  • Love great user experience
  • Engineer at Lucid Software

Lucid Software

We're hiring!
www.golucid.co

Agenda

Coding Standards

  • Importance
  • Challenges
  • Tools
  • Strategy

Gotta have coding standards!

  • Agree upon
  • Document
  • Refer to
  • Maintain

Why?

  • Consistency
  • Avoid some errors
  • Less thinking
  • Easier to read

What?

  • Language conventions (HTML, CSS, JS, Scala, SQL...)
  • Filesystem layout
  • Version control workflow

The reality

Conventions are hard to follow

Manually...

Conventions are hard to follow

Why?

  • We forget
  • Own habits
  • Existing code
  • Too much work

Every guideline should cost less to implement than the benefit it brings

Every guideline should cost less to implement than the benefit it brings

So what do we do?

  • Not follow a guideline
  • Bring down its cost

Tools to the rescue!

Tim Allen with a hammer

JSHint: Bare CLI not very useful

Command line output of JSHint

Tools rule #1

Run automatically, get feedback early

Inline JSHint linting in ST

Too much feedback?

Too much linter warnings!

Tools rule #2

Configurable


{
    "asi"     : true,   // suppress warnings about semicolons
    "curly"   : true,   // always put curly braces around blocks
    "eqeqeq"  : false,  // allow non-strict comparisons
    "latedef" : true,   // prohibits using a variable before definition
    "eqnull"  : true,   // alllow == null
    "newcap"  : true,   // capitalize constructor names
    "camelcase": true,  // enforce camelCase or UPPER_CASE
    "expr"    : true,   // suppress warning "Expected an assignment..."
    "gcl"     : true,   // compat with Google Closure Linter
    "immed"   : false,  // don't be bothered by IIF syntax
    "sub"     : true,   // don't complain about [] vs dot notation
    "unused"  : "vars",  // warn about unused variables
    "maxlen"  : 120,    // maximum length of a line
    "maxerr"  : 1000
}
					

Make exceptions

An example of overriding JSHint rules with inline directives

Tools rule #3

Shared configuration!

Config files in project root

Whitespace consistency

Doge loves whitespace

.editorconfig


# top-most EditorConfig file
root = true

# defaults for all files
[*]
charset = utf-8
indent_style = tab
indent_size = 4
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true

[*.scala]
indent_style = space
indent_size = 2
					

Handling whitespace changes


git diff -w
git blame -w
git merge -Xignore-space-change
git rebase --ignore-space-change
					

Keep commits clean

Put whitespace changes on a separate commit

Ignore whitespace and stage selected regions in git-cola

git configuration

  • .gitignore
  • .gitattributes: * text=auto
    (use only for new repos)
  • Common configuration
    
    # do a rebase on git pull
    git config --global branch.autosetuprebase always
    # push only current branch to upstream by default
    git config --global push.default upstream
    							
  • Hooks (e.g. prevent committing debug code)
  • Workflow scripts and aliases (e.g. git flow)

Armed with tools, now what?

Rambo armed and dangerous

Adoption strategy

  1. Write NEW code properly
  2. Refactor the parts you work on
  3. Preserve localized standards

Code reviews: Speak up if it smells!

something smells fishy, and it certainly isn't fish

Enforcing standards: pseudocode


    while(!codingStandards.followed) {
        reason = programmer.whyNot();
        if(reason.isAcceptable) {
            codingStandards.patch(reason);
        } else {
            programmer.forceComply(codingStandards);
        }
    }
					

General rule

  • Make code readable and clear
  • ...like it's written by one person
  • Leave the code better than it was

Action items

  1. Install necessary linters
  2. Install .editorconfig plugin
  3. Check in linter configs (branch: dotfiles)
  4. Write compliant code

THANKS!