ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ืื ื• ืžืฉืชืžืฉื™ื ื‘ืคืœื˜ืคื•ืจืžื” ื‘ืื•ืคืŸ ืคืขื™ืœ ื‘ืขื‘ื•ื“ืชื ื• soundQube ืœืฉืžื•ืจ ืขืœ ืื™ื›ื•ืช ืงื•ื“ ื‘ืจืžื” ื’ื‘ื•ื”ื”. ื‘ืขืช ืฉื™ืœื•ื‘ ืื—ื“ ืžื”ืคืจื•ื™ืงื˜ื™ื ืฉื ื›ืชื‘ื• ื‘ VueJs+Typescript, ื”ืชืขื•ืจืจื• ื‘ืขื™ื•ืช. ืœื›ืŸ, ืื ื™ ืจื•ืฆื” ืœืกืคืจ ืœื›ื ื‘ื™ืชืจ ืคื™ืจื•ื˜ ื›ื™ืฆื“ ื”ืฆืœื—ื ื• ืœืคืชื•ืจ ืื•ืชื.

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ื‘ืžืืžืจ ื–ื” ื ื“ื‘ืจ, ื›ืคื™ ืฉื›ืชื‘ืชื™ ืœืžืขืœื”, ืขืœ ืคืœื˜ืคื•ืจืžืช SonarQube. ืงืฆืช ืชื™ืื•ืจื™ื” - ืžื” ื–ื” ื‘ื›ืœืœ, ืœืžื™ ืฉืฉื•ืžืข ืขืœ ื–ื” ื‘ืคืขื ื”ืจืืฉื•ื ื”:

soundQube (ืœึฐืฉืึถืขึธื‘ึทืจ ืกื•ึนื ึธืจ) ื”ื™ื ืคืœื˜ืคื•ืจืžืช ืงื•ื“ ืคืชื•ื— ืœื‘ื“ื™ืงื” ืจืฆื™ืคื” ื•ืœืžื“ื™ื“ืช ืื™ื›ื•ืช ืงื•ื“.
ืชื•ืžืš ื‘ื ื™ืชื•ื— ืงื•ื“ ื•ื–ื™ื”ื•ื™ ืฉื’ื™ืื•ืช ืœืคื™ ื”ื›ืœืœื™ื ืฉืœ ืชืงื ื™ ื”ืชื›ื ื•ืช MISRA C, MISRA C++, MITER/CWE ื•-CERT Secure Coding Standards. ื”ื•ื ื™ื›ื•ืœ ื’ื ืœื–ื”ื•ืช ืฉื’ื™ืื•ืช ืžืจืฉื™ืžื•ืช ืฉื’ื™ืื•ืช ื”ืชื›ื ื•ืช ื”ืžื•ื‘ื™ืœื•ืช ืฉืœ OWASP 10 ื•-CWE/SANS Top 25.
ืœืžืจื•ืช ื”ืขื•ื‘ื“ื” ืฉื”ืคืœื˜ืคื•ืจืžื” ืžืฉืชืžืฉืช ื‘ื›ืœื™ื ืžื•ื›ื ื™ื ืฉื•ื ื™ื, SonarQube ืžืฆืžืฆืžืช ืืช ื”ืชื•ืฆืื•ืช ืœืœื•ื— ืžื—ื•ื•ื ื™ื ืื—ื“, ืฉื•ืžืจืช ื”ื™ืกื˜ื•ืจื™ื” ืฉืœ ืจื™ืฆื•ืช ื•ื‘ื›ืš ืžืืคืฉืจืช ืœืš ืœืจืื•ืช ืืช ื”ืžื’ืžื” ื”ื›ืœืœื™ืช ืฉืœ ืฉื™ื ื•ื™ื™ื ื‘ืื™ื›ื•ืช ื”ืชื•ื›ื ื” ื‘ืžื”ืœืš ื”ืคื™ืชื•ื—.

ืคืจื˜ื™ื ื ื•ืกืคื™ื ื ื™ืชืŸ ืœืžืฆื•ื ื‘ ื”ืืชืจ ื”ืจืฉืžื™

ืžืกืคืจ ืจื‘ ืฉืœ ืฉืคื•ืช ืชื›ื ื•ืช ื ืชืžื›ื•ืช. ืื ืœืฉืคื•ื˜ ืœืคื™ ื”ืžื™ื“ืข ืžื”ืงื™ืฉื•ืจ ืœืžืขืœื”, ืžื“ื•ื‘ืจ ื‘ื™ื•ืชืจ ืž-25 ืฉืคื•ืช. ื›ื“ื™ ืœืชืžื•ืš ื‘ืฉืคื” ืžืกื•ื™ืžืช, ืขืœื™ืš ืœื”ืชืงื™ืŸ ืืช ื”ืคืœืื’ื™ืŸ ื”ืžืชืื™ื. ื’ืจืกืช ื”ืงื”ื™ืœื” ื›ื•ืœืœืช ืชื•ืกืฃ ืœืขื‘ื•ื“ื” ืื™ืชื• Javascript (ื›ื•ืœืœ ื˜ื™ืคื•ืกื™ื), ืœืžืจื•ืช ืฉื”ื•ื•ื™ืงื™ ืื•ืžืจ ืืช ื”ื”ื™ืคืš. ืžึตืึธื—ื•ึนืจ Javascript ืชืฉื•ื‘ื•ืช ืœืคืœืื’ื™ืŸ SonarJS, ืขื‘ื•ืจ Typescript SonarTS ื‘ื”ืชืืžื”.

ื”ืœืงื•ื— ื”ืจืฉืžื™ ืžืฉืžืฉ ืœืฉืœื™ื—ืช ืžื™ื“ืข ื›ื™ืกื•ื™ sonarqube-scanner, ืืฉืจ, ื‘ืืžืฆืขื•ืช ื”ื”ื’ื“ืจื•ืช ืž config-ืงื•ื‘ืฅ, ืฉื•ืœื— ื ืชื•ื ื™ื ืืœื” ืœืฉืจืช soundQube ืœื’ื™ื‘ื•ืฉ ื•ื”ืฆื˜ื‘ืจื•ืช ื ื•ืกืคืช.

ืขื‘ื•ืจ Javascript ื™ืฉ ืžืขื˜ืคืช npm. ืื– ื‘ื•ืื• ื ืชื—ื™ืœ ื‘ื™ื™ืฉื•ื ืฆืขื“ ืื—ืจ ืฆืขื“ soundQube ะฒ Vueืคืจื•ื™ืงื˜ ื‘ืืžืฆืขื•ืช ื›ืชื‘ ื›ืชื™ื‘ื”.

ื›ื“ื™ ืœืคืจื•ืก ืืช ื”ืฉืจืช soundQube ื‘ื•ืื• ื ื ืฆืœ ื”ื“ื•ืงืจ-ื”ืœื—ื ื”.

sonar.yaml:

version: '1'
    services:
        simplesample-sonar:
            image: sonarqube:lts
            ports:
                - 9001:9000
                - 9092:9092
            network_mode: bridge

ืœึฐื”ึทืฉืึดื™ืง:

docker-compose -f sonar.yml up

ืœืื—ืจ ืžื›ืŸ soundQube ื™ื”ื™ื” ื–ืžื™ืŸ ื‘: http://localhost:9001 .

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube
ืื™ืŸ ื‘ื• ืขื“ื™ื™ืŸ ืคืจื•ื™ืงื˜ื™ื ื•ื–ื” ื”ื•ื’ืŸ. ืื ื—ื ื• ื ืชืงืŸ ืืช ื”ืžืฆื‘ ื”ื–ื”. ืœืงื—ืชื™ ืืช ื”ืคืจื•ื™ืงื˜ ื”ืจืฉืžื™ ืœื“ื•ื’ืžื” VueJS+TS+Jest. ื‘ื•ืื• ื ื›ื•ืคืฃ ืืช ื–ื” ื›ืœืคื™ ืขืฆืžื ื•:

git clone https://github.com/vuejs/vue-test-utils-typescript-example.git

ืจืืฉื™ืช ืขืœื™ื ื• ืœื”ืชืงื™ืŸ ืืช ื”ืœืงื•ื— soundQube, ืฉื ืงืจื ืกื•ื ืจ-ืกื•ืจืงืขื‘ื•ืจ Npm ื™ืฉ ืขื˜ื™ืคื”:

yarn add sonarqube-scanner

ื•ืžื™ื“ ื”ื•ืกืฃ ืืช ื”ืคืงื•ื“ื” ืœ ืกืงืจื™ืคื˜ื™ื ืœืขื‘ื•ื“ ืขื ื–ื”.

package.json:

{
 โ€ฆ 
   scripts: {
      ...
      "sonar": "sonar-scanner"
      ...
   },
 โ€ฆ
}

ืœืื—ืจ ืžื›ืŸ, ื›ื“ื™ ืฉื”ืกื•ืจืง ื™ืขื‘ื•ื“, ืขืœื™ืš ืœื”ื’ื“ื™ืจ ืืช ื”ื’ื“ืจื•ืช ื”ืคืจื•ื™ืงื˜ ื‘ืงื•ื‘ืฅ ืžื™ื•ื—ื“. ื‘ื•ืื• ื ืชื—ื™ืœ ืขื ื”ื™ืกื•ื“ื•ืช.

sonar-project.properties:

sonar.host.url=http://localhost:9001

sonar.projectKey=test-project-vuejs-ts
sonar.projectName=Test Application (VueJS+TS)

sonar.sources=src
# sonar.tests=
sonar.test.inclusions=src/**/*tests*/**
sonar.sourceEncoding=UTF-8

  • sonar.host.url - ื›ืชื•ื‘ืช ืกื•ึนื ึธืจ'ื;
  • sonar.projectKey - ืžื–ื”ื” ืคืจื•ื™ืงื˜ ื™ื™ื—ื•ื“ื™ ื‘ืฉืจืช ืกื•ึนื ึธืจ'ื;
  • sonar.projectName โ€“ ืฉืžื•, ื ื™ืชืŸ ืœืฉื ื•ืช ืื•ืชื• ื‘ื›ืœ ืขืช, ืžื›ื™ื•ื•ืŸ ืฉื”ืคืจื•ื™ืงื˜ ืžื–ื•ื”ื” ืขืœ ื™ื“ื™ ืžืคืชื— ืคืจื•ื™ืงื˜;
  • sonar.sources - ืชื™ืงื™ื™ื” ืขื ืžืงื•ืจื•ืช, ื‘ื“ืจืš ื›ืœืœ ื–ื” src, ืื‘ืœ ื™ื›ื•ืœ ืœื”ื™ื•ืช ื›ืœ ื“ื‘ืจ. ืชื™ืงื™ื™ื” ื–ื• ืžื•ื’ื“ืจืช ื‘ื™ื—ืก ืœืชื™ืงื™ื™ืช ื”ืฉื•ืจืฉ, ืฉื”ื™ื ื”ืชื™ืงื™ื” ืฉืžืžื ื” ืžื•ืคืขืœ ื”ืกื•ืจืง;
  • sonar.tests โ€“ ืคืจืžื˜ืจ ืฉื”ื•ืœืš ื‘ืžืงื‘ื™ืœ ืœืคืจืžื˜ืจ ื”ืงื•ื“ื. ื–ื•ื”ื™ ื”ืชื™ืงื™ื” ืฉื‘ื” ืžืžื•ืงืžื•ืช ื”ื‘ื“ื™ืงื•ืช. ื‘ืคืจื•ื™ืงื˜ ื–ื” ืื™ืŸ ืชื™ืงื™ื” ื›ื–ื•, ื•ื”ื‘ื“ื™ืงื” ืžืžื•ืงืžืช ืœื™ื“ ื”ืจื›ื™ื‘ ื”ื ื‘ื“ืง ื‘ืชื™ืงื™ื™ื” 'ืžื‘ื—ืŸ', ืื– ื ืชืขืœื ืžืžื ื• ืœืขืช ืขืชื” ื•ื ืฉืชืžืฉ ื‘ืคืจืžื˜ืจ ื”ื‘ื;
  • ืชื›ืœื™ืœื™ื.sonar.test - ื ืชื™ื‘ ืœื‘ื“ื™ืงื•ืช ื‘ืืžืฆืขื•ืช ืžืกื™ื›ื”, ืขืฉื•ื™ื™ื ืœื”ื™ื•ืช ืžืกืคืจ ืืœืžื ื˜ื™ื ื”ืžื•ืคืจื“ื™ื ื‘ืคืกื™ืงื™ื;
  • sonar.sourceEncoding - ืงื™ื“ื•ื“ ืขื‘ื•ืจ ืงื‘ืฆื™ ืžืงื•ืจ.

ืœืงืจืืช ื”ื”ืฉืงื” ื”ืจืืฉื•ื ื” ืฉืœ ื”ืกื•ืจืง ื”ื›ืœ ืžื•ื›ืŸ, ืžืœื‘ื“ ื”ืคืขื•ืœื” ื”ืขื™ืงืจื™ืช ื”ืงื•ื“ืžืช: ื”ืคืขืœืช ืžื ื•ืข ื”ื‘ื“ื™ืงื” ืขืฆืžื•, ื›ื“ื™ ืฉื™ื•ื›ืœ ืœื”ืคื™ืง ืžื™ื“ืข ืขืœ ื”ื›ื™ืกื•ื™, ืฉื‘ื• ื™ืฉืชืžืฉ ื”ืกื•ืจืง ืœืื—ืจ ืžื›ืŸ.

ืื‘ืœ ื›ื“ื™ ืœืขืฉื•ืช ื–ืืช, ืขืœื™ืš ืœื”ื’ื“ื™ืจ ืืช ืžื ื•ืข ื”ื‘ื“ื™ืงื” ื›ื“ื™ ืœื™ืฆื•ืจ ืžื™ื“ืข ื–ื”. ื‘ืคืจื•ื™ืงื˜ ื–ื”, ืžื ื•ืข ื”ื‘ื“ื™ืงื” ื”ื•ื ื™ืฉ. ื•ื”ื”ื’ื“ืจื•ืช ืฉืœื• ื ืžืฆืื•ืช ื‘ื—ืœืง ื”ืžืชืื™ื ืฉืœ ื”ืงื•ื‘ืฅ package.json.

ื‘ื•ืื• ื ื•ืกื™ืฃ ืืช ื”ื”ื’ื“ืจื•ืช ื”ืืœื”:

"collectCoverage": true,
"collectCoverageFrom": [
      "src/**/*",
      "!src/main.ts",
      "!src/App.vue",
      "!src/**/*.d.*",
      "!src/**/*__tests__*"
],

ื›ืœื•ืžืจ, ืื ื—ื ื• ืžื’ื“ื™ืจื™ื ืืช ื”ื“ื’ืœ ืขืฆืžื• ืœืฆื•ืจืš ื—ื™ืฉื•ื‘ ื”ื›ื™ืกื•ื™ ื•ืืช ื”ืžืงื•ืจ (ืœืฆื“ ื—ืจื™ื’ื™ื) ืฉืขืœ ื‘ืกื™ืกื• ื™ื•ื•ืฆืจ.

ืขื›ืฉื™ื• ื‘ื•ืื• ื ืจื™ืฅ ืืช ื”ื‘ื“ื™ืงื”:

yarn test

ื ืจืื” ืืช ื”ื“ื‘ืจื™ื ื”ื‘ืื™ื:

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ื”ืกื™ื‘ื” ื”ื™ื ืฉืื™ืŸ ืงื•ื“ ื‘ืจื›ื™ื‘ ืขืฆืžื•. ื‘ื•ื ื ืชืงืŸ ืืช ื–ื”.

HelloWorld.vue:

...
methods: {
    calc(n) {
      return n + 1;
    }
  },
mounted() {
  this.msg1 = this.msg + this.calc(1);
},
...

ื–ื” ื™ืกืคื™ืง ื›ื“ื™ ืœื—ืฉื‘ ืืช ื”ื›ื™ืกื•ื™.

ืœืื—ืจ ื”ืคืขืœื” ืžื—ื“ืฉ ืฉืœ ื”ื‘ื“ื™ืงื”, ื ื•ื•ื“ื ื–ืืช:

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ืขืœ ื”ืžืกืš ืื ื• ืืžื•ืจื™ื ืœืจืื•ืช ืžื™ื“ืข ืขืœ ื”ื›ื™ืกื•ื™, ื•ืชื™ื•ื•ืฆืจ ืชื™ืงื™ื” ื‘ืชื™ืงื™ื™ืช ื”ืคืจื•ื™ืงื˜ ื›ื™ืกื•ื™ ืขื ืžื™ื“ืข ื›ื™ืกื•ื™ ืžื‘ื—ืŸ ื‘ืคื•ืจืžื˜ ืื•ื ื™ื‘ืจืกืœื™ LCOV (ืชื•ืกืฃ LTP GCOV).

Gcov ื”ื•ื ื›ืœื™ ืขื–ืจ ื”ืžื•ืคืฅ ื‘ืื•ืคืŸ ื—ื•ืคืฉื™ ืœื‘ื—ื™ื ืช ื›ื™ืกื•ื™ ืงื•ื“. Gcov ืžื™ื™ืฆืจ ืืช ื”ืžืกืคืจ ื”ืžื“ื•ื™ืง ืฉืœ ื‘ื™ืฆื•ืขื™ื ืขื‘ื•ืจ ื›ืœ ืžืฉืคื˜ ื‘ืชื•ื›ื ื™ืช ื•ืžืืคืฉืจ ืœืš ืœื”ื•ืกื™ืฃ ื”ืขืจื•ืช ืœืงื•ื“ ื”ืžืงื•ืจ. Gcov ืžื’ื™ืข ื›ืฉื™ืจื•ืช ืกื˜ื ื“ืจื˜ื™ ื›ื—ืœืง ืžื—ื‘ื™ืœืช GCC.
Lcov - ืžืžืฉืง ื’ืจืคื™ ืขื‘ื•ืจ gcov. ื”ื•ื ืžืจื›ื™ื‘ ืงื‘ืฆื™ gcov ืœืงื•ื‘ืฆื™ ืžืงื•ืจ ืžืจื•ื‘ื™ื ื•ืžื™ื™ืฆืจ ืงื‘ื•ืฆื” ืฉืœ ื“ืคื™ HTML ืขื ืงื•ื“ ื•ืžื™ื“ืข ื›ื™ืกื•ื™. ื“ืคื™ื ื ื•ืฆืจื™ื ื’ื ื›ื“ื™ ืœื”ืงืœ ืขืœ ื”ื ื™ื•ื•ื˜. Lcov ืชื•ืžืš ื‘ื›ื™ืกื•ื™ ืฉืœ ืžื—ืจื•ื–ื•ืช, ืคื•ื ืงืฆื™ื•ืช ื•ืขื ืคื™ื.

ืœืื—ืจ ื”ืฉืœืžืช ื”ื‘ื“ื™ืงื•ืช, ืžื™ื“ืข ื”ื›ื™ืกื•ื™ ื™ืžืฆื ื‘ coverage/lcov.info.
ืื ื—ื ื• ืฆืจื™ื›ื™ื ืœื•ืžืจ ืกื•ึนื ึธืจ'ืžืื™ืคื” ืื ื™ ื™ื›ื•ืœ ืœื”ืฉื™ื’ ืืช ื–ื”? ืœื›ืŸ, ื‘ื•ืื• ื ื•ืกื™ืฃ ืืช ื”ืฉื•ืจื•ืช ื”ื‘ืื•ืช ืœืงื•ื‘ืฅ ื”ืชืฆื•ืจื” ืฉืœื•. ืื‘ืœ ื™ืฉ ื ืงื•ื“ื” ืื—ืช: ืคืจื•ื™ืงื˜ื™ื ื™ื›ื•ืœื™ื ืœื”ื™ื•ืช ืจื‘ ืœืฉื•ื ื™ื™ื, ื›ืœื•ืžืจ ื‘ืชื™ืงื™ื™ื” src ื™ืฉื ื ืงื•ื“ื™ ืžืงื•ืจ ืœืžืกืคืจ ืฉืคื•ืช ืชื›ื ื•ืช ื•ื”ืฉืชื™ื™ื›ื•ืช ืœืื—ืช ืื• ืื—ืจืช, ื•ื‘ืชืžื•ืจื”, ื”ืฉื™ืžื•ืฉ ื‘ืชื•ืกืฃ ืžืกื•ื™ื ื ืงื‘ืข ืขืœ ืคื™ ื”ื”ืจื—ื‘ื” ืฉืœื•. ื•ื ื™ืชืŸ ืœืื—ืกืŸ ืžื™ื“ืข ื›ื™ืกื•ื™ ื‘ืžืงื•ืžื•ืช ืฉื•ื ื™ื ืขื‘ื•ืจ ืฉืคื•ืช ืชื›ื ื•ืช ืฉื•ื ื•ืช, ื›ืš ืฉืœื›ืœ ืฉืคื” ื™ืฉ ืกืขื™ืฃ ืžืฉืœื” ืœื”ื’ื“ืจื” ื–ื•. ื”ืคืจื•ื™ืงื˜ ืฉืœื ื• ืžืฉืชืžืฉ ื›ืชื‘ ื›ืชื™ื‘ื”, ืื– ืื ื—ื ื• ืฆืจื™ื›ื™ื ืกืขื™ืฃ ื”ื’ื“ืจื•ืช ืจืง ื‘ืฉื‘ื™ืœ ื–ื”:

sonar-project.properties:

sonar.typescript.coveragePlugin=lcov
sonar.typescript.lcov.reportPaths=coverage/lcov.info

ื”ื›ืœ ืžื•ื›ืŸ ืœืงืจืืช ื”ื”ืฉืงื” ื”ืจืืฉื•ื ื” ืฉืœ ื”ืกื•ืจืง. ืื ื™ ืจื•ืฆื” ืœืฆื™ื™ืŸ ืฉื”ืคืจื•ื™ืงื˜ ื”ื•ื ืกื•ึนื ึธืจ'e ื ื•ืฆืจ ื‘ืื•ืคืŸ ืื•ื˜ื•ืžื˜ื™ ื‘ืคืขื ื”ืจืืฉื•ื ื” ืฉืืชื” ืžืคืขื™ืœ ืืช ื”ืกื•ืจืง ืขื‘ื•ืจ ืคืจื•ื™ืงื˜ ื ืชื•ืŸ. ื‘ื–ืžื ื™ื ื”ื‘ืื™ื ื™ืฆื˜ื‘ืจ ืžื™ื“ืข ืขืœ ืžื ืช ืœืจืื•ืช ืืช ื”ื“ื™ื ืžื™ืงื” ืฉืœ ืฉื™ื ื•ื™ื™ื ื‘ืคืจืžื˜ืจื™ื ืฉืœ ื”ืคืจื•ื™ืงื˜ ืœืื•ืจืš ื–ืžืŸ.

ืื– ื‘ื•ืื• ื ืฉืชืžืฉ ื‘ืคืงื•ื“ื” ืฉื ื•ืฆืจื” ืงื•ื“ื ืœื›ืŸ package.json:

yarn run sonar 

ื”ืขืจื”: ืืชื” ื™ื›ื•ืœ ื’ื ืœื”ืฉืชืžืฉ ื‘ืคืจืžื˜ืจ -X ืœืจื™ืฉื•ื ืžืคื•ืจื˜ ื™ื•ืชืจ.

ืื ื”ืกื•ืจืง ื”ื•ืฉืง ื‘ืคืขื ื”ืจืืฉื•ื ื”, ื”ืงื•ื‘ืฅ ื”ื‘ื™ื ืืจื™ ืฉืœ ื”ืกื•ืจืง ืขืฆืžื• ื™ื•ืจื™ื“ ืชื—ื™ืœื”. ืœืื—ืจ ืžื›ืŸ ื”ื•ื ืžืชื—ื™ืœ ื•ืžืชื—ื™ืœ ืœืกืจื•ืง ืืช ื”ืฉืจืช ืกื•ึนื ึธืจ'a ืขื‘ื•ืจ ืชื•ืกืคื™ื ืžื•ืชืงื ื™ื, ื•ื‘ื›ืš ืžื—ืฉื‘ ืืช ื”ืฉืคื” ื”ื ืชืžื›ืช. ื ื˜ืขื ื™ื ื’ื ืคืจืžื˜ืจื™ื ืฉื•ื ื™ื ืื—ืจื™ื ืœืคืขื•ืœืชื•: ืคืจื•ืคื™ืœื™ ืื™ื›ื•ืช, ื›ืœืœื™ื ืคืขื™ืœื™ื, ืžืื’ืจ ืžื“ื“ื™ื, ื›ืœืœื™ ืฉืจืช.

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ื”ืขืจื”: ืœื ื ืชืขื›ื‘ ืขืœื™ื”ื ื‘ืคื™ืจื•ื˜ ื‘ืžืกื’ืจืช ืžืืžืจ ื–ื”, ืืš ืชืžื™ื“ ืชื•ื›ืœ ืœืคื ื•ืช ืœืžืงื•ืจื•ืช ืจืฉืžื™ื™ื.

ืœืื—ืจ ืžื›ืŸ, ื ื™ืชื•ื— ื”ืชื™ืงื™ื•ืช ืžืชื—ื™ืœ src ืœื–ืžื™ื ื•ืช ืฉืœ ืงื‘ืฆื™ ืžืงื•ืจ ืขื‘ื•ืจ ื›ืœ ื”ืฉืคื” ื”ื ืชืžื›ืช (ืื ืœื ืฆื•ื™ืŸ ื‘ืžืคื•ืจืฉ) ืขื ื”ื•ืกืคืชื ืœืื™ื ื“ืงืก.

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ื‘ื”ืžืฉืš ืžื’ื™ืขื™ื ื ื™ืชื•ื—ื™ื ืฉื•ื ื™ื ืื—ืจื™ื, ืฉืœื ื ืชืžืงื“ ื‘ื”ื ื‘ืžืืžืจ ื–ื” (ืœื“ื•ื’ืžื”, ื›ื’ื•ืŸ ืจื˜ื™ื™ื”, ื–ื™ื”ื•ื™ ืฉื›ืคื•ืœ ืงื•ื“ ื•ื›ื•').

ื‘ืกื•ืฃ ืขื‘ื•ื“ืช ื”ืกื•ืจืง, ื›ืœ ื”ืžื™ื“ืข ืฉื ืืกืฃ ื ืืกืฃ, ืžืื•ื—ืกืŸ ื‘ืืจื›ื™ื•ืŸ ื•ื ืฉืœื— ืœืฉืจืช.

ืื—ืจื™ ื–ื”, ืื ื—ื ื• ื›ื‘ืจ ื™ื›ื•ืœื™ื ืœืจืื•ืช ืžื” ืงืจื” ื‘ืžืžืฉืง ื”ืื™ื ื˜ืจื ื˜:

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ื›ืคื™ ืฉืื ื• ื™ื›ื•ืœื™ื ืœืจืื•ืช, ืžืฉื”ื• ืขื‘ื“, ื•ืืคื™ืœื• ืžืจืื” ืกื•ื’ ืฉืœ ืกื™ืงื•ืจ, ืื‘ืœ ื–ื” ืœื ืชื•ืื ืืช ืฉืœื ื• ื™ืฉ-ืœื”ื’ื™ืฉ ืชืœื•ื ื”.

ื‘ื•ื ื ื‘ื™ืŸ ืืช ื–ื”. ื‘ื•ืื• ื ืกืชื›ืœ ืขืœ ื”ืคืจื•ื™ืงื˜ ื‘ื™ืชืจ ืคื™ืจื•ื˜, ื ืœื—ืฅ ืขืœ ืขืจืš ื”ื›ื™ืกื•ื™ ื•"ื ื›ื ืก" ืœื“ื•ื— ืงื•ื‘ืฅ ืžืคื•ืจื˜:

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ื›ืืŸ ืื ื• ืจื•ืื™ื, ื‘ื ื•ืกืฃ ืœืชื™ืง ื”ืจืืฉื™, ื”ื ื‘ื“ืง HelloWorld.vue, ื™ืฉ ื’ื ืงื•ื‘ืฅ main.ts, ืžื” ืฉืžืงืœืงืœ ืืช ื›ืœ ืชืžื•ื ืช ื”ืกื™ืงื•ืจ. ืื‘ืœ ืื™ืš ื–ื” ืฉื”ื—ืจื’ื ื• ืืช ื–ื” ืžื—ื™ืฉื•ื‘ ื”ื›ื™ืกื•ื™. ื›ืŸ, ื”ื›ืœ ื ื›ื•ืŸ, ืื‘ืœ ื–ื” ื”ื™ื” ื‘ืจืžื” ื™ืฉ, ืื‘ืœ ื”ืกื•ืจืง ืื™ื ื“ืงืก ืื•ืชื•, ืื– ื–ื” ื”ื’ื™ืข ื‘ืกื•ืคื• ืฉืœ ื“ื‘ืจ ืœื—ื™ืฉื•ื‘ื™ื ืฉืœื•.

ื‘ื•ื ื ืชืงืŸ ืืช ื–ื”:

sonar-project.properties:

...
sonar.exclusions=src/main.ts
...

ื‘ืจืฆื•ื ื™ ืœื”ื‘ื”ื™ืจ: ื‘ื ื•ืกืฃ ืœืชื™ืงื™ื•ืช ื”ืžืฆื•ื™ื ื•ืช ื‘ืคืจืžื˜ืจ ื–ื”, ืžืชื•ื•ืกืคื•ืช ื’ื ื›ืœ ื”ืชื™ืงื™ื•ืช ื”ืžืคื•ืจื˜ื•ืช ื‘ืคืจืžื˜ืจ ืชื›ืœื™ืœื™ื.sonar.test.

ืœืื—ืจ ื”ืคืขืœืช ื”ืกื•ืจืง, ืื ื• ืจื•ืื™ื ืืช ื”ืžื™ื“ืข ื”ื ื›ื•ืŸ:

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ื‘ื•ืื• ื ืกืชื›ืœ ืขืœ ื”ื ืงื•ื“ื” ื”ื‘ืื” - ืคืจื•ืคื™ืœื™ ืื™ื›ื•ืช. ื“ื™ื‘ืจืชื™ ืœืžืขืœื” ืขืœ ืชืžื™ื›ื” ืกื•ึนื ึธืจืžื›ืžื” ืฉืคื•ืช ื‘ื• ื–ืžื ื™ืช. ื–ื” ื‘ื“ื™ื•ืง ืžื” ืฉืื ื—ื ื• ืจื•ืื™ื. ืื‘ืœ ืื ื—ื ื• ื™ื•ื“ืขื™ื ืฉื”ืคืจื•ื™ืงื˜ ืฉืœื ื• ื›ืชื•ื‘ TS, ืื– ืœืžื” ืœืืžืฅ ืืช ื”ืกื•ืจืง ืขื ืžื ื™ืคื•ืœืฆื™ื•ืช ื•ื‘ื“ื™ืงื•ืช ืžื™ื•ืชืจื•ืช. ื ื’ื“ื™ืจ ืืช ื”ืฉืคื” ืœื ื™ืชื•ื— ืขืœ ื™ื“ื™ ื”ื•ืกืคืช ืคืจืžื˜ืจ ืื—ื“ ื ื•ืกืฃ ืœืงื•ื‘ืฅ ื”ืชืฆื•ืจื” ืกื•ึนื ึธืจ'ื:

sonar-project.properties:

...
sonar.language=ts
...

ื‘ื•ื ื ืจื™ืฅ ืฉื•ื‘ ืืช ื”ืกื•ืจืง ื•ื ืจืื” ืืช ื”ืชื•ืฆืื”:

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ื”ื›ื™ืกื•ื™ ื ืขืœื ืœื—ืœื•ื˜ื™ืŸ.

ืื ื ืกืชื›ืœ ื‘ื™ื•ืžืŸ ื”ืกื•ืจืง, ื ื•ื›ืœ ืœืจืื•ืช ืืช ื”ืฉื•ืจื” ื”ื‘ืื”:

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ื›ืœื•ืžืจ, ืงื‘ืฆื™ ื”ืคืจื•ื™ืงื˜ ืฉืœื ื• ืคืฉื•ื˜ ืœื ื ื•ืกืคื• ืœืื™ื ื“ืงืก.

ื”ืžืฆื‘ ื”ื•ื ื›ื“ืœืงืžืŸ: ื ืชืžืš ืจืฉืžื™ืช VueJs ื ืžืฆื ื‘ืชื•ืกืฃ SonarJSืขืœ ืžื™ ืื—ืจืื™ Javascript.

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ืื‘ืœ ื”ืชืžื™ื›ื” ื”ื–ื• ืœื ื ืžืฆืืช ื‘ืชื•ืกืฃ SonarTS ืขื‘ื•ืจ TS, ืœื’ื‘ื™ื• ื ืคืชื— ื›ืจื˜ื™ืก ืจืฉืžื™ ื‘ืžืขืงื‘ ืื—ืจ ื‘ืื’ื™ื ืกื•ึนื ึธืจ'ื:

  1. https://jira.sonarsource.com/browse/MMF-1441
  2. https://github.com/SonarSource/SonarJS/issues/1281

ื”ื ื” ื›ืžื” ืชืฉื•ื‘ื•ืช ืžืื—ื“ ื”ื ืฆื™ื’ื™ื ืžืžืคืชื—ื™ SonarQube, ื”ืžืืฉืจื•ืช ืขื•ื‘ื“ื” ื–ื•.

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ืื‘ืœ ื”ื›ืœ ืขื‘ื“ ืœื ื•, ืืชื” ืžืชื ื’ื“. ื›ืŸ, ื‘ื•ื ื ื ืกื” ืืช ื–ื” ืงืฆืช "ื’ึทืจื–ึถืŸ".
ืื ื™ืฉ ืชืžื™ื›ื” .vue-ืงื‘ืฆื™ื ืกื•ึนื ึธืจ'ืื•ื™, ืื– ื‘ื•ื ื ื ืกื” ืœื”ื’ื™ื“ ืœื• ืœื”ืชื™ื™ื—ืก ืืœื™ื”ื ื›ืืœ ื›ืชื‘ ื›ืชื™ื‘ื”.

ื‘ื•ืื• ื ื•ืกื™ืฃ ืคืจืžื˜ืจ:

sonar-project.properties:

...
sonar.typescript.file.suffixes=.ts,.tsx,.vue
...

ื‘ื•ืื• ื ืคืขื™ืœ ืืช ื”ืกื•ืจืง:

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ื•ื”ืจื™, ื”ื›ืœ ื—ื–ืจ ืœืงื“ืžื•ืชื•, ื•ืขื ืคืจื•ืคื™ืœ ืื—ื“ ื‘ืœื‘ื“ ืขื‘ื•ืจ ื›ืชื‘ ื›ืชื™ื‘ื”. ื›ืœื•ืžืจ, ื”ืฆืœื—ื ื• ืœืคืชื•ืจ ืืช ื”ื‘ืขื™ื” ื‘ืชืžื™ื›ื” VueJs+TS ืขื‘ื•ืจ soundQube.

ื‘ื•ืื• ื ื ืกื” ืœืœื›ืช ืจื—ื•ืง ื™ื•ืชืจ ื•ืœืฉืคืจ ืžืขื˜ ืืช ืžื™ื“ืข ื”ื›ื™ืกื•ื™.

ืžื” ืขืฉื™ื ื• ืขื“ ื›ื”:

  • ื ื•ืกืฃ ืœืคืจื•ื™ืงื˜ ืกื•ึนื ึธืจ-ืกื•ึนืจึตืง;
  • ืœื”ื›ื™ืŸ ื™ืฉ ืœื”ืคืงืช ืžื™ื“ืข ื›ื™ืกื•ื™;
  • ืžื•ื’ื“ืจ ืกื•ึนื ึธืจ-ืกื•ึนืจึตืง;
  • ืคืชืจ ืืช ื‘ืขื™ื™ืช ื”ืชืžื™ื›ื” .vue-ืงื‘ืฆื™ื + ื›ืชื‘ ื›ืชื™ื‘ื”.

ื‘ื ื•ืกืฃ ืœื›ื™ืกื•ื™ ื”ื‘ื“ื™ืงื”, ื™ืฉื ื ืงืจื™ื˜ืจื™ื•ื ื™ื ืฉื™ืžื•ืฉื™ื™ื ื ื•ืกืคื™ื ื•ืžืขื ื™ื™ื ื™ื ืœืื™ื›ื•ืช ื”ืงื•ื“, ืœืžืฉืœ ืฉื›ืคื•ืœ ืงื•ื“ ื•ืžืกืคืจ ื”ืฉื•ืจื•ืช (ื”ืžืขื•ืจื‘ื•ืช ื‘ื—ื™ืฉื•ื‘ ืžืงื“ืžื™ื ื”ืงืฉื•ืจื™ื ืœืžื•ืจื›ื‘ื•ืช ื”ืงื•ื“) ืฉืœ ื”ืคืจื•ื™ืงื˜.

ื‘ื™ื™ืฉื•ื ื”ื ื•ื›ื—ื™ ืฉืœ ื”ืชื•ืกืฃ ืœืขื‘ื•ื“ื” ืขื TS (SonarTS) ืœื ื™ืขื‘ื•ื“ CPD (ื’ืœืื™ ื”ืขืชืงื” ื”ื“ื‘ืง) ื•ืกืคื™ืจืช ืฉื•ืจื•ืช ืงื•ื“ .vue-ืงื‘ืฆื™ื.

ื›ื“ื™ ืœื™ืฆื•ืจ ืžืฆื‘ ืกื™ื ืชื˜ื™ ืฉืœ ืฉื›ืคื•ืœ ืงื•ื“, ืคืฉื•ื˜ ืฉื›ืคืœ ืืช ืงื•ื‘ืฅ ื”ืจื›ื™ื‘ ื‘ืฉื ืื—ืจ ื•ื’ื ื”ื•ืกืฃ ืื•ืชื• ืœืงื•ื“ main.ts ืคื•ื ืงืฆื™ื™ืช ื“ืžื” ื•ืฉื›ืคืœ ืื•ืชื” ื‘ืฉื ืื—ืจ. ื›ื“ื™ ืœื‘ื“ื•ืง ืฉื›ืคื•ืœ ื›ืžื• ื‘ .vue, ื• ื‘ .ts -ืงื‘ืฆื™ื.

main.ts:

...
function name(params:string): void {
  console.log(params);
}
...

ื›ื“ื™ ืœืขืฉื•ืช ื–ืืช, ืขืœื™ืš ืœื”ืขื™ืจ ื‘ืื•ืคืŸ ื–ืžื ื™ ืืช ืฉื•ืจืช ื”ืชืฆื•ืจื”:

sonar-project.properties:

...
sonar.exclusions=src/main.ts
...

ื‘ื•ืื• ื ืคืขื™ืœ ืžื—ื“ืฉ ืืช ื”ืกื•ืจืง ื™ื—ื“ ืขื ื‘ื“ื™ืงื”:

yarn test && yarn run sonar

ื›ืžื•ื‘ืŸ ืฉื”ืกื™ืงื•ืจ ืฉืœื ื• ื™ื™ืคื•ืœ, ืื‘ืœ ืขื›ืฉื™ื• ื–ื” ืœื ืžืขื ื™ื™ืŸ ืื•ืชื ื•.

ื‘ืžื•ื ื—ื™ื ืฉืœ ืฉื›ืคื•ืœ ืฉื•ืจื•ืช ืงื•ื“, ื ืจืื”:

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ื›ื“ื™ ืœื‘ื“ื•ืง ื ืฉืชืžืฉ ืžื—ื™ืจ ืœืืœืฃ ื”ื•ืคืขื•ืช-ืชื•ืขืœืช - jscpd:

npx jscpd src

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ืขื‘ื•ืจ ืฉื•ืจื•ืช ืงื•ื“:

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ืื•ืœื™ ื–ื” ื™ื™ืคืชืจ ื‘ื’ืจืกืื•ืช ืชื•ืกืคื™ื ืขืชื™ื“ื™ื•ืช SonarJS(TS). ืื ื™ ืจื•ืฆื” ืœืฆื™ื™ืŸ ืฉื”ื ืžืชื—ื™ืœื™ื ื‘ื”ื“ืจื’ื” ืœืžื–ื’ ืืช ืฉื ื™ ื”ืชื•ืกืคื™ื ื”ืœืœื• ืœืื—ื“ SonarJS, ืฉืœื“ืขืชื™ ื”ื•ื ื ื›ื•ืŸ.

ืขื›ืฉื™ื• ืจืฆื™ืชื™ ืœืฉืงื•ืœ ืืช ื”ืืคืฉืจื•ืช ืœืฉืคืจ ืืช ืžื™ื“ืข ื”ื›ื™ืกื•ื™.

ืขื“ ื›ื” ืื ื• ื™ื›ื•ืœื™ื ืœืจืื•ืช ื›ื™ืกื•ื™ ืžื‘ื—ืŸ ื‘ืื—ื•ื–ื™ื ืขื‘ื•ืจ ื”ืคืจื•ื™ืงื˜ ื›ื•ืœื•, ื•ื‘ืคืจื˜ ืขื‘ื•ืจ ืงื‘ืฆื™ื. ืื‘ืœ ืืคืฉืจ ืœื”ืจื—ื™ื‘ ืืช ื”ืžื—ื•ื•ืŸ ื”ื–ื” ืขื ืžื™ื“ืข ืขืœ ื”ื›ืžื•ืช ื™ื—ื™ื“ื”-ื‘ื“ื™ืงื•ืช ืœืคืจื•ื™ืงื˜, ื›ืžื• ื’ื ื‘ื”ืงืฉืจ ืฉืœ ืงื‘ืฆื™ื.

ื™ืฉ ืกืคืจื™ื™ื” ืฉื™ื›ื•ืœื” ื™ืฉ-ื”ืžืจ ืืช ื”ื“ื•ื— ืœืคื•ืจืžื˜ ืขื‘ื•ืจ ืกื•ึนื ึธืจ'ื:
ื ืชื•ื ื™ ื‘ื“ื™ืงื” ื’ื ืจื™ื™ื - https://docs.sonarqube.org/display/SONAR/Generic+Test+Data.

ื‘ื•ืื• ื ืชืงื™ืŸ ืืช ื”ืกืคืจื™ื™ื” ื”ื–ื• ื‘ืคืจื•ื™ืงื˜ ืฉืœื ื•:

yarn add jest-sonar-reporter

ื•ื”ื•ืกื™ืคื• ืื•ืชื• ืœืชืฆื•ืจื” ื™ืฉ:

package.json:

โ€ฆ
"testResultsProcessor": "jest-sonar-reporter"
โ€ฆ

ืขื›ืฉื™ื• ื‘ื•ืื• ื ืจื™ืฅ ืืช ื”ื‘ื“ื™ืงื”:

yarn test

ืœืื—ืจ ืžื›ืŸ ื™ื™ื•ื•ืฆืจ ืงื•ื‘ืฅ ื‘ืฉื•ืจืฉ ื”ืคืจื•ื™ืงื˜ test-report.xml.

ื‘ื•ืื• ื ืฉืชืžืฉ ื‘ื• ื‘ืชืฆื•ืจื” ืกื•ึนื ึธืจ'ื:

sonar-project.properties:

โ€ฆ
sonar.testExecutionReportPaths=test-report.xml
โ€ฆ

ื•ื”ืคืขืœ ืžื—ื“ืฉ ืืช ื”ืกื•ืจืง:

yarn run sonar

ื‘ื•ื ื ืจืื” ืžื” ื”ืฉืชื ื” ื‘ืžืžืฉืง ืกื•ึนื ึธืจ'ื:

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ื•ืฉื•ื ื“ื‘ืจ ืœื ื”ืฉืชื ื”. ื”ืขื•ื‘ื“ื” ื”ื™ื ืฉืกื•ื ืืจ ืœื ืžื—ืฉื™ื‘ ืืช ื”ืงื‘ืฆื™ื ื”ืžืชื•ืืจื™ื ื‘ื“ื•"ื— Jest ื›ืงื‘ืฆื™ื ื™ื—ื™ื“ื”-ื‘ื“ื™ืงื•ืช. ืขืœ ืžื ืช ืœืชืงืŸ ืžืฆื‘ ื–ื”, ืื ื• ืžืฉืชืžืฉื™ื ื‘ืคืจืžื˜ืจ ื”ืชืฆื•ืจื” ืกื•ึนื ึธืจ sonar.tests, ืฉื‘ื” ื ืฆื™ื™ืŸ ื‘ืžืคื•ืจืฉ ืืช ื”ืชื™ืงื™ื•ืช ืขื ื‘ื“ื™ืงื•ืช (ื™ืฉ ืœื ื• ืจืง ืื—ืช ื‘ื™ื ืชื™ื™ื):

sonar-project.properties:

โ€ฆ
sonar.tests=src/components/__tests__
โ€ฆ

ื‘ื•ืื• ื ืคืขื™ืœ ืžื—ื“ืฉ ืืช ื”ืกื•ืจืง:

yarn run sonar

ื‘ื•ื ื ืจืื” ืžื” ื”ืฉืชื ื” ื‘ืžืžืฉืง:

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ืขื›ืฉื™ื• ืจืื™ื ื• ืืช ื”ืžืกืคืจ ืฉืœื ื• ื™ื—ื™ื“ื”-ื‘ื“ื™ืงื•ืช ื•ืœืื—ืจ ืฉื ื›ืฉืœื• ืขืœ ื™ื“ื™ ืœื—ื™ืฆื” ื‘ืคื ื™ื, ื ื•ื›ืœ ืœืจืื•ืช ืืช ื”ืชืคืœื’ื•ืช ื”ืžืกืคืจ ื”ื–ื” ื‘ื™ืŸ ืงื‘ืฆื™ ื”ืคืจื•ื™ืงื˜:

ืฉื™ืœื•ื‘ ืคืจื•ื™ืงื˜ VueJS+TS ืขื SonarQube

ืžืกืงื ื”

ืื–, ื”ืกืชื›ืœื ื• ืขืœ ื›ืœื™ ืœื ื™ืชื•ื— ืจืฆื™ืฃ soundQube. ืฉื™ืœื‘ื ื• ื‘ื• ื‘ื”ืฆืœื—ื” ืคืจื•ื™ืงื˜ ืฉื ื›ืชื‘ ื‘ื• VueJs+TS. ืชื•ืงืŸ ื›ืžื” ื‘ืขื™ื•ืช ืชืื™ืžื•ืช. ื”ื’ื“ืœื ื• ืืช ืชื•ื›ืŸ ื”ืžื™ื“ืข ืฉืœ ืžื—ื•ื•ืŸ ื›ื™ืกื•ื™ ื”ื‘ื“ื™ืงื”. ื‘ืžืืžืจ ื–ื” ื‘ื“ืงื ื• ืจืง ืื—ื“ ืžืงืจื™ื˜ืจื™ื•ื ื™ ืื™ื›ื•ืช ื”ืงื•ื“ (ืื•ืœื™ ืื—ื“ ื”ืžืจื›ื–ื™ื™ื ืฉื‘ื”ื), ืื‘ืœ soundQube ืชื•ืžืš ื‘ืงืจื™ื˜ืจื™ื•ื ื™ ืื™ื›ื•ืช ืื—ืจื™ื, ื›ื•ืœืœ ื‘ื“ื™ืงื•ืช ื‘ื˜ื™ื—ื•ืช. ืื‘ืœ ืœื ื›ืœ ื”ืชื›ื•ื ื•ืช ื”ืœืœื• ื–ืžื™ื ื•ืช ื‘ืžืœื•ืืŸ ื‘ ืงื”ื™ืœื”-ื’ืจืกืื•ืช. ืื—ืช ื”ืชื›ื•ื ื•ืช ื”ืžืขื ื™ื™ื ื•ืช ื•ื”ืฉื™ืžื•ืฉื™ื•ืช ื”ื™ื ืื™ื ื˜ื’ืจืฆื™ื” soundQube ืขื ืžืขืจื›ื•ืช ืฉื•ื ื•ืช ืœื ื™ื”ื•ืœ ืžืื’ืจ ืงื•ื“, ื›ื’ื•ืŸ GitLab ื•-BitBucket. ืœืžื ื•ืข ืžื™ื–ื•ื’ ื‘ืงืฉืช ืžืฉื™ื›ื” (ืžื™ื–ื•ื’).'ื ืœืกื ื™ืฃ ื”ืจืืฉื™ ืฉืœ ื”ืžืื’ืจ ื›ืืฉืจ ื”ื›ื™ืกื•ื™ ื™ืจื“. ืื‘ืœ ื–ื” ืกื™ืคื•ืจ ืœืžืืžืจ ืื—ืจ ืœื’ืžืจื™.

ื .ื‘.: ื›ืœ ื”ืžืชื•ืืจ ื‘ืžืืžืจ ื‘ืฆื•ืจื” ืฉืœ ืงื•ื“ ื–ืžื™ืŸ ื‘ ื”ืžื–ืœื’ ืฉืœื™.

ืจืง ืžืฉืชืžืฉื™ื ืจืฉื•ืžื™ื ื™ื›ื•ืœื™ื ืœื”ืฉืชืชืฃ ื‘ืกืงืจ. ืœื”ืชื—ื‘ืจื‘ื‘ืงืฉื”.

ื”ืื ืืชื” ืžืฉืชืžืฉ ื‘ืคืœื˜ืคื•ืจืžืช SonarQube:

  • 26,3%ื›ืŸ5

  • 15,8%ืžืกืคืจ 3

  • 15,8%ืฉืžืขืชื™ ืขืœ ื”ืคืœื˜ืคื•ืจืžื” ื”ื–ื• ื•ืื ื™ ืจื•ืฆื” ืœื”ืฉืชืžืฉ ื‘3

  • 10,5%ืฉืžืขืชื™ ืขืœ ื”ืคืœื˜ืคื•ืจืžื” ื”ื–ื• ื•ืื ื™ ืœื ืจื•ืฆื” ืœื”ืฉืชืžืฉ ื‘2

  • 0,0%ืื ื™ ืžืฉืชืžืฉ ื‘ืคืœื˜ืคื•ืจืžื” ืื—ืจืช0

  • 31,6%ืคืขื ืจืืฉื•ื ื” ืฉืฉืžืขืชื™ ืขืœื™ื”6

19 ืžืฉืชืžืฉื™ื ื”ืฆื‘ื™ืขื•. 3 ืžืฉืชืžืฉื™ื ื ืžื ืขื•.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”