Effective ways of enforcing coding standards



Effective ways of enforcing coding standards

0 1


pres-enforcingstandards

Slides for a talk that explores the main challenges in adopting coding standards and suggests effective ways of solving them.

On Github dpashkevich / pres-enforcingstandards

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
- Agree and document in one place - Place we can refer to - Maintain

Why?

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

Why have CS?

  • Less time spent thinking about how things should be written (at a low level!)
  • Easier to read and modify code that you’re not familiar with (newcomers, people switching teams, yourself in several months/years)

What?

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

What things can be covered in standards?

The reality

Conventions are hard to follow

Manually...

Conventions are hard to follow

Why?

  • We forget
  • Own habits
  • Existing code
  • Too much work
  • We forget, hard to memorize (coding standards can be dozens of pages long - ex. isobar)
  • We have our own habits
  • Existing code can give a bad example
  • Too much work! (e.g. require alphabetizing CSS properties)

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

We have at least two options here...

Tools to the rescue!

- Tools help bring down the cost - But you have to use them efficiently!!!

JSHint: Bare CLI not very useful

- Manually running a command in the terminal is not nearly as helpful or efficient as getting real-time feedback in your editor.

Tools rule #1

Run automatically, get feedback early

- code quality tool must run automatically, don't have to remember to run it - Real-time feedback early on will let you catch errors before you make more of them - // jshint as a good example - these concepts should be applied to each tool you try to use

Too much feedback?

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
}
					
- filter out the noise (stuff we don't care about) - adapt to our agreed upon coding styles - try to express as much of the convention as possible through config Still an excuse: `there will always be exceptions!`

Make exceptions

- There will always be exceptions - You don't have to see the same warnings again and again - With this, reaching 0 linter warnings becomes possible!

Tools rule #3

Shared configuration!

- Check `.jshintrc` into your repo(s) so that everybody is on the same page - keep up to date - have changes propagate to everyone automatically, no announcements

Whitespace consistency

.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
					
- A spec to help enforce whitespace consistency across the team - Cool thing: you don't have to worry about whitespace settings yourself, even when you copy-paste code

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

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)
- Part of vcs workflow conventions: git config - gitattributes `* text=auto` (end-of-line normalization) - Common config: saves everybody time - Branching model: teams go extra mile

Armed with tools, now what?

- Go berserk and try to change the entire code base at once?

Adoption strategy

Write NEW code properly Refactor the parts you work on Preserve localized standards - No excuse not to write new code properly! - Rules can be overridden for subprojects

Code reviews: Speak up if it smells!

Code reviews: speak up if you see a "code smell", don't be shy

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

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

THANKS!