Code style and

violence

Code style?

Why, in the world,
do I need
this?

— Not that it is necessary. 
 While you work alone.

— But as soon as the team begins to grow …

… and more …

… and even more …

… and more …

… and …

… and at some point it becomes obvious
 that you need rules.

What kind of rules do we need?

  • Scripts (ECMA X, TypeScript, Kotlin, etc. )
  • Styles (CSS, PostCSS, Sass, Less, Stylus, etc.)
  • Flow(git flow, github flow, gitlab flow, etc.)

— We need cover scripts, styles and flow

The flow includes

  • process
  • branch naming
  • commit message standard

How
should
I choose
code style?

It should be maintained by
someone else

— Because we don't want to build a better world, we want to build an app, get our money, then buy a rifle and … but where was I?

And
it should be trandy!

— Because it increase your team mates value as developers and thas it would be easier to implement

Anything
else?

No

— It does not metter if you use space or tabs: your text editor can handle any of them. Only thing is matter — code uniformity.

Airbnb JavaScript Style Guide

QRCODE with link to Airbnb js style guide

https://github.com/airbnb/javascript

Airbnb CSS Style Guide

QRCODE with link to Airbnb js style guide

https://github.com/airbnb/css

Standard JavaScript Style Guide

QRCODE with link to Airbnb js style guide

https://github.com/standard/standard

A successful Git branching model

QRCODE with link to original gitflow article

https://goo.gl/GDaF

GitHub
branching model

QRCODE with link to original gitflow article

https://githubflow.github.io/

GitLab
branching model

QRCODE with link to original gitflow article

https://goo.gl/Z0w1nQ

And that's it?

— Yes! Your teammates from Delhi are already running to implement code style you have selected. They struggle for it.

— Actually no, they don't. Nobody want your code style.

I am an artist!
Don't restrict me!

— You need to preset, check, automatize and force code style, otherwise there would be none. 

$ vi .editorconfig
[*]
indent_style = space
indent_size = 2
tab_width = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
$ sudo npm i -g eslint
$ npm i -D eslint
$ eslint --init
$ vi .eslintrc
// .eslintrc
{
  "extends": "airbnb",
  "plugins": [
    "react",
    "jsx-a11y",
    "import"
  ]
}
$ npm info 
    "eslint-config-airbnb@latest" 
    peerDependencies

{ eslint: '^3.19.0 || ^4.3.0',
  'eslint-plugin-jsx-a11y': '^5.1.1',
  'eslint-plugin-import': '^2.7.0',
  'eslint-plugin-react': '^7.1.0' }
$ npm i -D eslint-plugin-react@latest
$ npm i -D eslint-plugin-import@latest
$ npm i -D eslint-plugin-jsx-a11y@latest
$ npm i -D eslint-config-airbnb@latest
// .eslintrc
{
  "parser": "babel-eslint",
  "extends": "airbnb",
  "plugins": [
    "react",
    "jsx-a11y",
    "import"
  ]
}
// .eslintrc
{
  "parser": "babel-eslint",
  "extends": "airbnb",
  "plugins": [
    "react",
    "jsx-a11y",
    "import"
  ],
  "env": {
    "browser": true,
    "es6": true,
  },
}
$ npm i -D babel-eslint@latest
$ eslint ./source
    --color 
    --format stylish
$ eslint ./source
    --color 
    --format stylish
    --fix
// package.json
{ // …
  "scripts": {
    "lint:js": "eslint ./source 
                  --color 
                  --format stylish 
                  --fix"
  }
}
$ npm run lint:js

So,
should I run it after each change?

— To see problems on the fly you should configure your editor

Nice, but
what if i'll ignore linter
errors all together

— Then I should, obviously, use…

Hook

#!/bin/bash
# .git/hooks/pre-commit
if !(npm run lint:js --silent) then
  exit 1;
fi

Source Control
Integrations

QRCODE with link

http://bit.ly/2w5y30Q

Do you
belive that I will create pre-commit all by
myself?

Am I my own worst enemy? And It's tricky!

You can't store hooks with a repo you know.

$ npm i -D lint-staged
$ npm i -D husky
// package.json
{ // …
  "scripts": { // …
    "precommit": "lint-staged"
  },
  "lint-staged": { // …
    "*.{js,jsx}": "eslint"
  }
}

How much will it leave from my code?

— Nothing!

$ npm i -D -E prettier
// .prettierrc
{
  "parser": "babylon",
  "useTabs": false,
  "tabWidth": 2,
  "singleQuote": true,
  "semi": true,
  "printWidth": 100,
  "trailingComma": "all",
  "bracketSpacing": true,
  "jsxBracketSameLine": true,
  "proseWrap": false,
}

// package.json
{ 
  "scripts": { 
    "format": "prettier 
                  --config .prettierrc
                  --write 'src/**/*.{js,jsx}'"
  }, 
}
$ npm i -D eslint-plugin-prettier
// .eslintrc
{
  "plugins": [
    "prettier",
  ],
  "rules": {
    "prettier/prettier": "error"
  },
}
$ npm i -D eslint-config-prettier
// .eslintrc
{
  "extends": [
    "airbnb", 
    "prettier", 
    "prettier/react"
  ],
}

▉▉▉▉

What about styles?

$ sudo npm i -g stylelint
$ npm i -D stylelint
$ npm i -D stylelint-config-standard
$ vi .stylelintrc
{
  "syntax": "less",
  "extends": "stylelint-config-standard",
  "rules": {
    // …
  }
}

Airbnb Stylelint Config PR

QRCODE with link

http://bit.ly/2zTHQHN

Airbnb Stylelint Config #1

QRCODE with link

http://bit.ly/2vwQmsD

Airbnb Stylelint Config #2

QRCODE with link

http://bit.ly/2wGfVMU

stylelint ./src/**/*.less 
            --syntax less 
            --color 
            --formatter verbose
stylelint ./src/**/*.less 
            --syntax less 
            --color 
            --formatter verbose
            --fix
// package.json
{ // …
  "scripts": {
    "lint:less": "stylelint ./src/**/*.less 
                            --syntax less 
                            --color 
                            --formatter verbose
                            --fix"
  }
}
$ npm run lint:less

But you will not use hooks, right?

— I definitely will.

// package.json
{ // …
  "scripts": { // …
    "precommit": "lint-staged"
  },
  "lint-staged": { // …
    "*.less": "stylelint"
  }
}

▉▉▉ ▉▉ ▉
▉▉▉▉▉

▉▉▉▉▉▉▉

What
about flow?

— More hooks…

vi ./hooks/commit-msg
chmod 0755 ./hooks/commit-msg
#!/bin/bash
MESSAGE=`cat "$1"`;
if (![[ "$MESSAGE" =~ ^[A-Z]+-[0-9]+\ -\ .*$ ]]) 
  && [ "$MESSAGE" != "merge" ]; 
  then 
    echo "Wrong commit message format."; 
    exit 1;
fi
if [[ "$MESSAGE" =~ ([а-яА-Я]+) ]]; then 
  echo "Don't use russian for commit message."; 
  exit 2;
fi
if (![[ "$MESSAGE" =~ ^[A-Z]+-[0-9]+\ -\ .{5,}$ ]]) 
  && [ "$MESSAGE" != "merge" ]; then 
    echo "Commit message is too short, 
          try to be more descriptive."; 
    exit 3;
fi
// package.json
{ // …
  "scripts": { // …
    "commitmsg": "./hooks/commit-msg ${GIT_PARAMS}"
  },
  // …
}
npm init
npm i -S command-line-args
// index.js
#! /usr/bin/env node
// index.js
#! /usr/bin/env node
const fs = require('fs');
const filePath = process.argv[2];
if (!fs.existsSync(filePath)) {
  console.log('Can not read commit message');
  process.exit(1);
}
const message = fs.readFileSync(filePath);
const commandLineArgs = require('command-line-args');
const optionDefinitions = [{ 
  name: 'regexp', 
  alias: 'r', 
  type: String, 
  defaultValue: '^[A-Z]+-[0-9]+\s-\s[\W\w\s]{5,}[\s]*$' },
];
const cli = commandLineArgs(optionDefinitions);
const commonRegexp = new RegExp(
  cli.regexp, 
  'ig'
);
if (!commonRegexp.test(message)) {
  console.log("Wrong commit message format");
  process.exit(3);
}
process.exit(0);
// package.json
"name": "my-message-hook",
"main": "index.js",
"bin": {"commit-msg": "index.js"},
"scripts": {
  "release": "npm version patch && 
              git push --tags && 
              npm publish --access public"
}
npm i -S my-message-hook
// package.json
"scripts": {
  "commitmsg": "commit-msg  
                  ${GIT_PARAMS} 
                  -r MyRegExp"
},

But are hooks enought?

— No

▉▉▉▉,
whats next?

Just want
to let you know that we made a voodoo doll
of you

Anton Nemtsev

skype: ravencry

QRCODE cо ссылкой на доклад

http://bit.ly/2AVZquZ