How not to skip invalid code in the repository

Why is it necessary


When more than one person works in your team, one way or another, everyone is faced with the problem of different coding styles for each team member. Someone writes brackets for blocks if...else, someone does not. When a project becomes larger, it is more difficult to read such a code and even harder to conduct a code review.


So that the code review and other team meetings do not turn into a discussion of tab vs spaces with elevated tones, it is better to configure the repository so that the project itself does not allow writing code that is invalid and non-standard for the team.


On the one hand, the use of different coding styles may seem to be tasteful, unworthy of attention. Well, June does not wrap a single line of code after the condition if, but someone writes, so what? If you leave the code from under the June pen “as is”, then it can become a “time bomb”: that line of code ifcan be deleted after that, and then the next line will fall under the condition. Of course, this situation is usually caught in a code review, but it happens that this potential bug passes the test, and here are two main reasons:


  1. We are all people, and people are wrong.
  2. People are social, which means they won’t want to enter into a “conflict” with the styles. And here two options are possible:
    • “Better fix it myself,” the reviewer thinks, and corrects the code.
    • The inspector breaks down on the June and expresses his doubts about its adequacy and the necessity of existence.

How can we ensure that everyone writes in accordance with the team style? To beat hands on a code review each time demotivates both the author of the code and the inspector himself. Fortunately, this problem excites the minds of more than one programmer for more than a year, and now we have many tools at our disposal.


The purpose of this article is to tell others and myself about the future of how I set up the project repository so that it can protect itself from invalid code in terms of team standards.


What we have


As an example, take a demo project whose code will be posted on GitHub. Since I am developing on .NET Core, the project will be written on it. What I will use:


  • .NET Core 3.1
  • Angular 8+
  • Github account
  • Travis ci

Travis-CI. , .



— , master branch.


" " Gitlab Azure DevOps, Github — Travis CI.



. . , , :


  • . develop master , (maintainer).
  • . CICD , .
  • Repository is a king. gitflow, .
  • Fail fast. , .
  • Git pre-commits hoocks. CI , - .

? -, master develop . , , , "" . " ". , .



solution- (*.sln) , - .NET . , , nuget- .


stylecop .NET Core. , solution- ( gist.github.com):


  1. Directory.build.props — .
  2. standard.ruleset — .
  3. stylecop.json — .

, .



- . : - , . . :


#  
ng lint

#    ,    html-
ng build --prod

#  
ng test

. , (Chrome / Chromium), CI-. , npm- puppeteer , .


, , :


  1. "test-headless-ci-only": "ng test --browsers ChromiumNoSandbox" scripts packages.json:

"scripts": {
    "ng": "ng",
    "start": "ng serve -o",
    "build": "ng build",
    "build-stage": "ng build --configuration=staging",
    "build-prod": "ng build --prod",
    "test": "ng test",
    "test-headless-ci-only": "ng test --browsers ChromiumNoSandbox",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },

  1. npm install puppeteer karma.conf.js :

const process = require("process");
process.env.CHROME_BIN = require("puppeteer").executablePath();

module.exports = function(config) {
  ...
};

  1. karma.conf.js customLaunchers:

config.set({
....,
customLaunchers: {
      ChromiumNoSandbox: {
        base: "ChromeHeadless",
        flags: [
          "--no-sandbox",
          "--headless",
          "--disable-gpu",
          "--disable-translate",
          "--disable-extensions"
        ]
      }
    },
    singleRun: true
});

npm run est-headless-ci-only.



- , . prettierrc, . . prettierrc , :


  1. prettier pretty-quick :

npm install -g prettier
npm install -g pretty-quick

  1. .prettierrc -:

{
    "useTabs": false,
    "printWidth": 120,
    "tabWidth": 2,
    "singleQuote": true,
    "trailingComma": "none",
    "semi": true
}

  1. prettier- .prettierignore -:

package.json
package-lock.json
tslint.json
tsconfig.json
browserslist
.gitkeep
favicon.ico
tsconfig.lib.json
tsconfig.app.json
tsconfig.spec.json
karma.conf.js
protractor.conf.js
ng-package.json
*.html

" " pretty-quick --staged.


-


CI/CD — , . , . . , -, .


husky. , :


  1. husky

npm install -g husky

  1. husk package.json :

"devDependencies": {
  ...
},
"husky": {
    "hooks": {
      "pre-commit": "pretty-quick --staged",
      "pre-push": "ng lint && ng test --browsers ChromiumNoSandbox"
    }
  }

: , , "".



After the steps described in the article are taken, I get a project that "protects itself" from invalid code. It’s clear that you can’t save the product from bugs with a single syntax and style guide, but even these minor things help to achieve better code quality and allow you to discuss architectural solutions for code reviews rather than formatting issues.


All Articles