áá»áœááºá¯ááºááá¯á·ááá¯ááºáááºážááœáẠááááºáá±á¬ááºážááᯠáááºááŒáœá áœá¬á¡áá¯á¶ážááŒá¯áá«áááºá SonarQube áá¯ááºá¡áááºá¡ááœá±ážááᯠááŒáá·áºáá¬ážáá±á¬á¡ááá·áºááœáẠááááºážááááºážáááºá áá±ážáá¬ážáá²á· ááá±á¬áá»ááºááœá±áá²á áá áºáá¯ááᯠáá±á«ááºážá ááºážááá¯ááºáᬠVueJs+ á á¬á á®á á¬ááá¯ááºá ááŒá¿áá¬ááœá± áá±á«áºáá¬áááºá ááá¯á·ááŒá±á¬áá·áº áááºážááá¯á·ááᯠáááºááá¯á·ááŒá±ááŸááºážááááºááᯠá¡áá±ážá áááºááŒá±á¬ááŒááá¯áá«áááºá
á€áá±á¬ááºážáá«ážááœááºáá»áœááºá¯ááºááá¯á·á¡áááºááœááºáá±ážáá²á·ááá·áºá¡ááá¯ááºáž SonarQube ááááºáá±á¬ááºážá¡ááŒá±á¬ááºážááŒá±á¬áá«áááºá áá®á¡áá¯áá®á¡áááºážááẠ- áá±áá¯áá»á¡á¬ážááŒáá·áº áááºážá¡ááŒá±á¬ááºážááᯠááááá¯á¶ážá¡ááŒááẠááŒá¬ážáááá°áá»á¬ážá¡ááœááºá
SonarQube (áá±á¬ááºáž Sonar) ááẠá ááºáááºáááŒááºá á áºáá±ážááŒááºážááŸáá·áº áá¯ááºá¡áááºá¡ááœá±ážááá¯ááºážáá¬ááŒááºážá¡ááœáẠopen source platform áá áºáá¯ááŒá áºáááºá
MISRA Cá MISRA C++á MITER/CWE ááŸáá·áº CERT Secure Coding Standards áááá¯ááááºážáááºážá á¶áá»áááºá á¶ááœáŸááºážáá»á¬ážááŸáá·áºá¡áá® áá¯ááºááœá²ááŒááºážá áááºááŒá¬ááŒááºážááŸáá·áº á¡ááŸá¬ážá¡ááœááºážááŸá¬ááœá±ááŒááºážááá¯á·ááᯠáá¶á·ááá¯ážáá±ážáá«áááºá áááºážááẠOWASP ááááºáááºáž 10 ááŸáá·áº CWE/SANS ááááºáááºáž áááá¯ááááºážáááºážá¡ááŸá¬áž 25 áá¯á á¬áááºážá០á¡ááŸá¬ážáá»á¬ážááᯠá¡ááá¡ááŸááºááŒá¯ááá¯ááºáááºá
ááááºáá±á¬ááºážááẠá¡áááºááá·áºáá¯ááºáá¬ážáá±á¬ áááááá¬áá»áá¯ážá á¯á¶ááᯠá¡áá¯á¶ážááŒá¯áá¬ážáá±á¬áºáááºáž SonarQube ááẠááááºáá»á¬ážááᯠáááºááŸáºáá¯ááºáá áºáá¯áááºážááá¯á· áá»áŸá±á¬á·áá»áá±ážáᬠáááºáááºááŸá¯ááŸááºáááºážááᯠááááºážááááºážáᬠááœá¶á·ááŒáá¯ážááá¯ážáááºááŸá¯áá¬áá¡ááœááºáž áá±á¬á·ááºáá²á¡áááºá¡ááœá±ážááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážá áá±áá¯áá»áááºážááŒá±á¬ááºážááᯠááŒááºááá¯ááºá á±áááºááŒá áºáááºá
á¡áá±ážá
áááºá¡áá»ááºá¡áááºáá»á¬ážááᯠááœáẠááŒáá·áºááŸá¯ááá¯ááºáá«áááºá
áááá¯ááááºážáááºážáá¬áá¬á áá¬áž á¡áá»á¬ážá¡ááŒá¬ážááᯠáá¶á·ááá¯ážáá±ážáááºá á¡áááºáá±á¬áºááŒáá« ááá·áºááºá០á¡áá»ááºá¡áááºáá»á¬ážááᯠááŒáá·áºááŒá®ážá áááºážááá¯á·ááẠáá¬áá¬á áá¬áž 25 áá»áá¯ážáá»á±á¬áºááŸááááºá áá®ážááŒá¬ážáá¬áá¬á áá¬ážáá áºáá¯ááᯠáá¶á·ááá¯ážáááºá ááá·áºáá»á±á¬áºáá±á¬ plugin ááᯠááá·áºááœááºážááá«áááºá ááœááºááŒá°ááá®áá¬ážááŸááºážááœáẠá¡áá¯ááºáá¯ááºááẠááááºá¡ááºáá áºáᯠáá«áááºáááºá Javascript ááᯠ(typesÑript á¡áá«á¡áááº) áá®áá®á ááá·áºáá»ááºáááºáᯠááá¯áá±á¬áºáááºážá áá±á¬ááºááœáẠJavascript ááᯠplugin á¡ááŒá±áá»á¬áž SonarJSTypescript á¡ááœáẠSonarTS á¡áá®ážáá®ážá
á¡áá»á¯á¶ážáááºáá±á¬ á¡áá»ááºá¡áááºáá»á¬ážááᯠáá±ážááá¯á·ááẠááá¬ážááẠáá¯á¶ážá áœá²áá°ááᯠá¡áá¯á¶ážááŒá¯áááºá sonarqube-á áááºáá¬, which, setting from ááá¯á¡áá¯á¶ážááŒá¯ááŒááºážá config ááá¯-fileá á€áá±áá¬ááᯠáá¬áá¬ááá¯á· ááá¯á·áá±ážáááºá SonarQube áá±á¬ááºááẠá á¯á ááºážááŸá¯ááŸáá·áº á á¯á ááºážááŸá¯á¡ááœááºá
á¡ááœáẠJavascript ááᯠááŒá
áº
áá¬áá¬ááᯠá¡áá¯á¶ážáá»ááẠSonarQube á¡ááœáá·áºáá±á¬ááºážáá°ááŒáá«á áá¯á· docker-compose.
sonar.yaml:
version: '1'
services:
simplesample-sonar:
image: sonarqube:lts
ports:
- 9001:9000
- 9092:9092
network_mode: bridge
áá áºááœáŸááºááŒááºáž-
docker-compose -f sonar.yml up
ááá¯áá±á¬áẠSonarQube ááœááºáááŸáááá¯ááºáááá·áºáááº-
ááá±á¬áá»ááºááœá± áááŸááá±ážááá¯á· ááá¬ážáá»áŸááááºá áá®á¡ááŒá±á¡áá±ááᯠááŒááºáá±ážáááºá ááá¬ážáááºááá°áá¬ááá±á¬áá»ááºááᯠáá°áá²á·áááºá VueJS+TS+Jest. á¡á²áá«ááᯠáá»áœááºáá±á¬áºááá¯á·áá® ááá¯ááºážááœáŸááºááá¯ááºááŒáá¡á±á¬ááºá
git clone https://github.com/vuejs/vue-test-utils-typescript-example.git
á¡áááºáá¯á¶áž client ááᯠinstall áá¯ááºááá«áááºá SonarQubeáá¯áá±á«áºáááºá ááá¯áá¬-á áááºáá¬á¡ááœáẠnpm wrapper ááŸááá«áááº
yarn add sonarqube-scanner
ááŒá®ážáá¬áá²á· áá»ááºáá»ááºáž command ááá¯ááá·áºááá¯ááºáá«á script áá»á¬áž áááºážááŸáá·áºá¡áá°á¡áá¯ááºáá¯ááºáááºá
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'A;
- sonar.projectKey - áá¬áá¬áá±á«áºááœáẠáá°ážááŒá¬ážáá±á¬ ááá±á¬áá»ááºá¡ááŸááºá¡áá¬áž Sonar'A;
- sonar.projectName - ááá±á¬áá»ááºááá¯áááºááŸááºáá¬ážáá±á¬ááŒá±á¬áá·áºáááºážáá¡áááºááá¯á¡áá»áááºáááœá±ážááŒá±á¬ááºážáá²ááá¯ááºáááºá ááá±á¬áá»ááºáá®áž;
- sonar.sources â áá»á¬ážáá±á¬á¡á¬ážááŒáá·áº á€á¡áá¬ááẠá¡áááºážá¡ááŒá áºáá»á¬ážáá«ááŸááá±á¬ ááá¯ááºááœá² srcáá«áá±ááá·áº áá¬áááá¯ááŒá áºááá¯ááºáá«áááºá á€ááá¯ááºááœá²ááᯠá áááºáá¬ááœáá·áºáá¬ážááá·áº ááá¯ááºááœá²ááŒá áºááá·áº root ááá¯áá«ááŸáá·áº áááºá ááºáááºááŸááºáá¬ážáááºá
- sonar.tests - ááááºáá áºáá¯ááŸáá·áº ááŸááºááœá²áá±áá±á¬ áá±á¬ááºáá áºáá¯á á€áááºááŸá¬ á ááºážáááºááŸá¯áá»á¬áž áááºááŸááᬠááá¯ááºááœá²ááŒá áºáááºá á€ááá±á¬áá»ááºááœááºá ááá¯áá²á·ááá¯á·áá±á¬ááá¯ááºááœá²áááŸááá«á ááŸáá·áº á á áºáá±ážááŸá¯ááẠááá¯áá«ááœáẠá ááºážáááºáá±ááá·áº á¡á áááºá¡ááá¯ááºážááá±ážááœáẠáááºááŸááááºáá ááºážáááº'á ááá¯á·ááŒá±á¬áá·áº áá»áœááºá¯ááºááá¯á·ááẠáááºážááᯠááá¯áá±á¬áá±á¬ááẠáá»á áºáá»á°ááŸá¯ááŒá®áž áá±á¬áẠparameter ááᯠá¡áá¯á¶ážááŒá¯áá«áááºá
- sonar.test.inclusions - áá»ááºááŸá¬áá¯á¶ážááᯠá¡áá¯á¶ážááŒá¯á á ááºážáááºááŸá¯áá»á¬ážá¡ááœáẠáááºážááŒá±á¬ááºážá áá±á¬áºáá¬ááŒáá·áº ááœá²ááŒá¬ážáá±á¬áºááŒáá¬ážáá±á¬ á¡á áááºá¡ááá¯ááºážáá»á¬ážá áœá¬ ááŸáááá¯ááºáááº;
- sonar.sourceEncoding - á¡áááºážá¡ááŒá áºááá¯ááºáá»á¬ážá¡ááœáẠáá¯ááºáá¯ááºááŒááºážá
á áááºáá¬ááᯠááááá¯á¶áž ááœáŸáá·áºáááºááŒááºážá¡ááœááºá á¡ááá ááŸá±á·áá¯ááºáá±á¬ááºáá»ááºááŸááœá²á áá»ááºá¡áá¬á¡á¬ážáá¯á¶ážááẠá¡áááºááá·áºááŒá áºáá±áá«ááŒá®- á ááºážáááºá¡ááºáá»ááºááᯠá áááºááŒááºážááŒáá·áºá áá±á¬ááºááá¯ááºážááœáẠá áááºáá¬ááᯠá¡áá¯á¶ážááŒá¯ááá·áº ááœáŸááºážááŒá¯á¶ááŸá¯ááá¯ááºáᬠá¡áá»ááºá¡áááºáá»á¬ážááᯠáá¯ááºáá±ážááá¯ááºá á±áááºá
áá«áá±ááá·áº áá«ááá¯áá¯ááºááá¯á·á áá®á¡áá»ááºá¡áááºááá¯áá¯ááºáá±ážááá¯á·á¡ááœáẠá ááºážáááºá¡ááºáá»ááºááᯠconfigure áá¯ááºááá¯á·ááá¯á¡ááºáá«áááºá á€ááá±á¬áá»ááºááœáẠá¡ááºáá»ááºá ááºážáááºááŸá¯ ááŒá¯áá¯ááºáááºá ááŸá. áááºážááááºáááºáá»á¬ážááẠááá¯ááºááááºááá¯ááºáá¬ááá¹áááœááºááŸááááºá ááŒááºá áœá¬áá¯áá¬áž.
á€áááºáááºáá»á¬ážááᯠááá·áºááŒáá«á áá¯á·á
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*",
"!src/main.ts",
"!src/App.vue",
"!src/**/*.d.*",
"!src/**/*__tests__*"
],
ááá¯ááá¯áááºááŸá¬á áááºážááá¯ááœá²á·á ááºážááá·áºá¡áá±á«áºá¡ááŒá±áá¶á ááœáŸááºážááŒá¯á¶ááŸá¯ááŸáá·áºá¡áááºážá¡ááŒá Ạ(ááŒáœááºážáá»ááºááŸáá·áºá¡áá°) ááá¯ááœááºáá»ááºáááºááá¯á¡ááºááŸá¯á¡ááœááºáá»áœááºá¯ááºááá¯á·ááá¯ááºááá¯ááºá¡áá¶ááá¯áááºááŸááºáá¬ážáááºá
áá² á ááºážáááºááŒáá·áºáá¡á±á¬ááºá
yarn test
á¡á±á¬ááºáá«ááá¯á·ááᯠááœá±á·ááá«áááº-
á¡ááŒá±á¬ááºážáááºážááŸá¬ á¡á áááºá¡ááá¯ááºážááá¯ááºááá¯ááºá áá¯ááºáááŸááá±á¬ááŒá±á¬áá·áºááŒá áºáááºá áá«ááá¯ááŒááºáá¡á±á¬ááºá
HelloWorld.vue-
...
methods: {
calc(n) {
return n + 1;
}
},
mounted() {
this.msg1 = this.msg + this.calc(1);
},
...
ááœáŸááºážááŒá¯á¶ááœááºáá»ááºááẠáá¯á¶áá±á¬ááºáááºááŒá áºáááºá
á ááºážáááºááŸá¯ááᯠááŒááºáááºá áááºááŒá®ážáá±á¬ááºá áá»áœááºá¯ááºááá¯á·ááẠá€á¡áá¬ááᯠáá±áá»á¬á á±áá«áááº-
áá»ááºááŸá¬ááŒááºáá±á«áºááœáẠáá»áœááºá¯ááºááá¯á·ááẠá¡áá»á¯á¶ážáááºááŸá¯ááá¯ááºáᬠá¡áá»ááºá¡áááºááᯠááŒááºááœá±á·ááááºááŒá áºááŒá®ážá ááá±á¬áá»ááºááá¯ááºááœá²ááœáẠááá¯ááºááœá²áá áºáá¯ááᯠáááºáá®ážáááºááŒá áºáááºá ááœáŸááºážááŒá¯á¶ á ááºážáááºááœáŸááºážááŒá¯á¶ááááºážá¡áá»ááºá¡áááºááŸáá·áºá¡áá° universal format áá²á· LCOV (LTP GCOV ááá¯ážáá»á²á·ááŸá¯).
Gcov áá¯ááºá¡áá»á¯á¶ážáááºááŸá¯ááᯠá á áºáá±ážááẠá¡ááá²á·ááŒáá·áºáá±ááá·áº á¡áá¯á¶ážáááºááŸá¯áá áºáá¯ááŒá áºáááºá Gcov ááẠáááá¯ááááºáá áºáá¯ááŸá áá¯ááºááŒááºáá»ááºáá áºáá¯á á®á¡ááœáẠáááá»áá±á¬áá¯ááºáá±á¬ááºááŸá¯á¡áá±á¡ááœááºááᯠáá¯ááºáá±ážááŒá®áž á¡áááºážá¡ááŒá áºáá¯ááºááœáẠááŸááºáá»ááºáá»á¬ážááᯠááá·áºááœááºážááá¯ááºá á±áá«áááºá Gcov ááẠGCC áááºáá±á·áá»áºá áá áºá áááºáá áºááá¯ááºážá¡ááŒá Ạá á¶á¡áá¯á¶ážááŒá¯ááŸá¯áá áºáá¯á¡ááŒá Ạáá¬áá«áááºá
Lcov - gcov á¡ááœáẠááááºáá Ạá¡ááºáá¬áá±á·á áºá áááºážááẠá¡áááºážá¡ááŒá áºááá¯ááºáá»á¬ážá áœá¬á¡ááœáẠgcov ááá¯ááºáá»á¬ážááᯠá á¯á ááºážááŒá®áž áá¯ááºááŸáá·áº ááœáŸááºážááŒá¯á¶á¡áá»ááºá¡áááºáá»á¬ážáá«ááŸááá±á¬ HTML á á¬áá»ááºááŸá¬á¡á á¯á¶ááᯠáá¯ááºáá¯ááºáá±ážáá«áááºá áááºážááœáŸááºááŸá¯ááá¯ááá¯ááœááºáá°á á±ááẠá á¬áá»ááºááŸá¬áá»á¬ážááá¯áááºáž áá¯ááºáá¯ááºáá¬ážáá«áááºá Lcov ááẠááŒáá¯ážáá»á¬ážá áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááŸáá·áº á¡ááá¯ááºážá¡áááºáá»á¬ážááᯠááœáŸááºážááŒá¯á¶áá±ážáááºá
á
á
áºáá±ážááŸá¯áá»á¬áž ááŒá®ážáá«á á¡áá»á¯á¶ážáááºáá±á¬ á¡áá»ááºá¡áááºáá»á¬ážááᯠááœá±á·ááŸáááááºááŒá
áºáá«áááºá ááœáŸááºážááŒá¯á¶/lcov.info.
ááŒá±á¬ááá¯á·ááá¯áááºá Sonar'áááºááááá¯ááºááá²á ááá¯á·ááŒá±á¬áá·áºá áááºážá configuration file ááœáẠá¡á±á¬ááºáá«á
á¬ááŒá±á¬ááºážáá»á¬ážááᯠááá·áºááŒáá«á
áá¯á·á ááá¯á·áá±á¬áº á¡áá»ááºáá
áºáá»ááºááŸááá«áááº- ááá±á¬áá»ááºáá»á¬ážááẠááá¯ááºááœá²ááœáẠáá¬áá¬á
áá¬ážáá»áá¯ážá
á¯á¶ááŸáááá¯ááºáááºá src áááá¯ááááºážáááºážáá¬áá¬á
áá¬ážáá»á¬ážá
áœá¬á¡ááœáẠáááºážááŒá
áºáá¯ááºáá»á¬ážááŸáááŒá®áž áá
áºáᯠááá¯á·ááá¯áẠáá
áºáá¯ááŸáá·áº áááºááœááºááŸá¯ááŸááá¬á áá
áºááẠááááºá¡ááºáá
áºáᯠááá¯á·ááá¯áẠá¡ááŒá¬ážááááºá¡ááºá¡áá¯á¶ážááŒá¯ááŸá¯ááᯠáááºážá extension ááŒáá·áº áá¯á¶ážááŒááºáááºá ááŸáá·áº ááœáŸááºážááŒá¯á¶á¡áá»ááºá¡áááºáá»á¬ážááᯠááá°áá®áá±á¬ áááá¯ááááºážáááºážáá¬áá¬á
áá¬ážáá»á¬ážá¡ááœáẠááá°áá®áá±á¬áá±áá¬áá»á¬ážááœáẠááááºážáááºážáá¬ážááá¯ááºáááºá ááá¯á·ááŒá±á¬áá·áº áá¬áá¬á
áá¬ážáá
áºáá¯á
á®ááœáẠáááºážááá¯á
áááºáááºááŸááºáááºá¡ááœáẠáááºážáááá¯ááºááá¯ááºááá¹áááŸááááºá áá»áœááºá¯ááºááá¯á·áááá±á¬áá»ááºááá¯á¡áá¯á¶ážááŒá¯áááºá áááºáááºážá
á¬á
á±á¬ááºááá¯á·ááŒá±á¬áá·áº áááºážá¡ááœááºáᬠáááºáááºááá¹ááá
áºáᯠááá¯á¡ááºáááº-
sonar-project.properties:
sonar.typescript.coveragePlugin=lcov
sonar.typescript.lcov.reportPaths=coverage/lcov.info
á áááºáá¬ááᯠááááá¯á¶áž á áááºááŒááºážá¡ááœáẠá¡áá¬á¡á¬ážáá¯á¶áž á¡áááºááá·áºááŒá áºáá±áá«ááŒá®á ááá±á¬áá»ááºááá¯áᬠáááááŒá¯á á±áá»ááºáá«áááºá Sonaráá±ážáá¬ážáá±á¬ ááá±á¬áá»ááºáá áºáá¯á¡ááœáẠá áááºáá¬ááᯠáááºááááá¯á¶ážáá¯ááºáá±á¬ááºáá±á¬á¡áá« e ááᯠá¡ááá¯á¡áá»á±á¬áẠáááºáá®ážáá«áááºá áá±á¬ááºááá¯ááºážá¡áá»áááºáá»á¬ážááœááºá á¡áá»áááºááŸáá·áºá¡áá»áŸ ááá±á¬áá»ááºáá«áá¬áá®áá¬áá»á¬ážááœáẠá¡ááŒá±á¬ááºážá¡áá²áá»á¬ážá ááá¯ááºážááá áºáá»á¬ážááᯠááŒááºááœá±á·ááá¯ááºááẠá¡áá»ááºá¡áááºáá»á¬ážááᯠá á¯áá±á¬ááºážáá«áááºá
áá®áá±á¬á· á á±á¬á á±á¬á áááºáá®ážáá¬ážáá²á· command ááᯠáá¯á¶ážááŒáá·áºáá¡á±á¬áẠááŒááºá áœá¬áá¯áá¬áž:
yarn run sonar
ááŸááºáá»ááº: parameter ááá¯áááºážáááºáá¯á¶ážááá¯ááºáááºá -X ááá¯ááá¯á¡áá±ážá áááºá¡áá»ááºá¡áááºáá»á¬ážá¡ááœááº
á áááºáá¬ááᯠááááá¯á¶ážá¡ááŒááẠá áááºá¡áá¯á¶ážááŒá¯áá«áá á áááºáá¬á binary ááᯠáŠážá áœá¬ áá±á«ááºážáá¯ááºáá¯ááºáá«áááºá áááºážáááºá áááºááŒá®ážáá¬áá¬ááá¯á áááºááºáááºáá«á Sonarááá·áºááœááºážáá¬ážáá±á¬ ááááºá¡ááºáá»á¬ážá¡ááœáẠ'a ááẠáá¶á·ááá¯ážáá±ážáá¬ážáá±á¬ áá¬áá¬á áá¬ážááᯠááœááºáá»ááºáá±ážáááºá áááºážá áá¯ááºáá±á¬ááºáá»ááºá¡ááœáẠá¡ááŒá¬ážáá±á¬ áá±á¬ááºáá»á¬áž á¡áá»áá¯ážáá»áá¯ážááá¯áááºáž áááºáá±á¬ááºáá¬ážáá«áááºá á¡áááºá¡ááœá±ážáááá¯ááá¯ááºáá»á¬ážá á¡áááºáááºáá±á¬á ááºážáá»ááºážáá»á¬ážá áááºááá áºáá»á¬ážááá¯ááŸá±á¬ááºááŸá¯á áá¬áá¬á ááºážáá»ááºážáá»á¬áž.
ááŸááºáá»ááº: áá»áœááºá¯ááºááá¯á·ááẠá€áá±á¬ááºážáá«ážááá±á¬ááºá¡ááœááºážááœáẠáááºážááá¯á·á¡áá±á«áºááœáẠá¡áá±ážá áááºáá±áááºááá¯ááºáá±á¬áºáááºáž ááá¬ážáááºá¡áááºážá¡ááŒá áºáá»á¬ážááᯠáááºá¡ááŒá²áááºááœááºááá¯ááºáá«áááºá
ááá¯á·áá±á¬áẠááá¯áá«ááœá²ááŒááºážá áááºááŒá¬ááŸá¯ á áááºáááºá src áááºážááá¯á·á¡á¬ážáá¯á¶ážá¡ááœáẠá¡áááºážá¡ááŒá áºááá¯ááºáá»á¬áž áááŸáááá¯ááºááŸá¯á¡ááœáẠ(áááá»áá±á¬áá áºáá¯á¡á¬áž á¡ááá¡áááºážáá±á¬áºááŒáá¬ážááŒááºážáááŸááá«á) áááºážááá¯á·ááá±á¬ááºáááºááœá² á¡ááœáŸááºážááááºážáá»á¬ážááŒáá·áº áá¶á·ááá¯ážáá±ážáá¬ážáá±á¬ áá¬áá¬á áá¬ážá
á€áá±á¬ááºážáá«ážááœáẠáá»áœááºá¯ááºááá¯á·á¡á¬áá¯á¶á áá¯ááºááŒááºážáááŸááá±á¬ á¡ááŒá¬ážáá±á¬ ááœá²ááŒááºážá áááºááŒá¬ááŸá¯áá»á¬áž (á¥ááá¬á lintingá áá¯ááºááœá¬ážááŸá¯ááᯠááŸá¬ááœá±ááœá±á·ááŸáááŒááºážá áááº) áá²á·ááá¯á·áá±á¬ á¡áá»áá¯ážáá»áá¯ážáá±á¬ ááœá²ááŒááºážá áááºááŒá¬ááŸá¯áá»á¬áž ááœááºáá±á«áºáá¬áá«áááºá
á áááºáá¬á á¡áá¯ááºá¡áá¯á¶ážááœááºá á á¯áá±á¬ááºážáá¬ážáá±á¬ á¡áá»ááºá¡áááºá¡á¬ážáá¯á¶ážááᯠá á¯á ááºážá ááááºážáááºážááŒá®áž áá¬áá¬ááá¯á· áá±ážááá¯á·áááºá
áááºážááŒá®ážáá±á¬ááºá áááºá¡ááºáá¬áá±á·á áºááœáẠááŒá áºáá»ááºáá²á·áááºáá»á¬ážááᯠáá»áœááºá¯ááºááá¯á· ááŒááºááœá±á·ááá¯ááºáááº-
áá»áœááºá¯ááºááá¯á·ááŒááºááá¯ááºáááºá¡ááá¯ááºážá áá áºá á¯á¶áá áºáá¯áá¯ááºáá±á¬ááºááŒá®ážáááºááŸáá·áºááẠááœáŸááºážááŒá¯á¶ááŸá¯á¡áá»áá¯á·ááᯠááŒááá±á¬áºáááºáž áá»áœááºá¯ááºááá¯á·ááŸáá·áº áááá¯ááºáá®áá«á ááŸá- á¡á á®áááºáá¶á á¬á
á¡ááŒá±ááŸá¬ááŒáá·áºáá¡á±á¬ááºá ááá±á¬áá»ááºááᯠááá¯ááá¯á¡áá±ážá áááºááŒáá·áºáá¡á±á¬ááºá ááœáŸááºážááŒá¯á¶ááŸá¯áááºááá¯ážááᯠááá áºááŸáááºááŒá®áž á¡áá±ážá áááºááá¯ááºá¡á á®áááºáá¶á á¬áá áºáá¯ááá¯á· âááŒááºááœá¬ážáááºâ
á€áá±áá¬ááœááºá áááºáá á áºáá±ážáá¬ážáá±á¬ááá¯ááºá¡ááŒááºá HelloWorld.vueááá¯ááºáá áºáá¯áááºážááŸááá«áááºá main.tsááœáŸááºážááŒá¯á¶áá¯á¶áá áºáá¯áá¯á¶ážááᯠáá»ááºá á®ážá á±áá±á¬á áá«áá±ááá·áº á¡áá»á¯á¶ážáááºááŸá¯ ááœááºáá»ááºááŸá¯ááá± áááºááᯠáááºáá¯ááºááá¯ááºáá¬áá²á áá¯ááºáá²á·á á¡á¬ážáá¯á¶ážááŸááºáá«áááºá áá«áá±ááá·áº á¡ááá·áºááŸá¬ááŸááá«áááºá ááŸáááá¯á·áá±á¬áº á áááºáá¬á áááºážááᯠá¡ááœáŸááºážááŒá¯áá¬ážáá±á¬ááŒá±á¬áá·áº áááºážá ááœááºáá»ááºááŸá¯áá»á¬ážááœáẠá¡áá¯á¶ážáááºáá²á·áááºá
áá«ááᯠááŒááºáá¡á±á¬ááºá
sonar-project.properties:
...
sonar.exclusions=src/main.ts
...
ááŸááºážáááºážáá»ááºáá áºáᯠááŒá¯áá¯ááºááá¯áááº- á€ááá·áºáááºáá±á¬ááºá¡ááœááºáž áááºááŸááºáá¬ážááá·áº ááá¯ááºááœá²áá»á¬ážá¡ááŒááºá ááá·áºáááºáá±á¬ááºá¡ááœááºáž áá±á¬áºááŒáá¬ážáá±á¬ ááá¯ááºááœá²áá»á¬ážá¡á¬ážáá¯á¶ážááá¯áááºáž áá±á«ááºážááá·áºáá¬ážáááºá sonar.test.inclusions.
á áááºáá¬ááᯠá áááºááŒá®ážáá±á¬ááºá áá»áœááºá¯ááºááá¯á·ááẠááŸááºáááºáá±á¬ á¡áá»ááºá¡áááºááᯠááœá±á·ááááº-
áá±á¬ááºá¡áá»ááºááᯠááŒáá·áºáá¡á±á¬ááº- á¡áááºá¡ááœá±ážáááá¯ááá¯ááºáá»á¬áž. á¡áááºáááŒá±á¬áá²á·áá²á· á¡áá±á¬ááºá¡áá¶á·á¡ááŒá±á¬ááºážáá«á Sonar'om áá áºáá»áááºáááºážááŸá¬áá¬áá¬á áá¬ážáá»á¬ážá áœá¬á áá«á áá»áá±á¬áºááá¯á· ááŒááºáá±ááᬠá¡ááá¡áá»áá«áá²á áá«áá±ááá·áº áá«ááá¯á·áá²á· ááá±á¬áá»ááºááᯠáá±ážáá¬ážáá¬ááᯠáá«ááá¯á·áááááºá TSááá¯á·ááŒá±á¬áá·áº áááá¯á¡ááºáá±á¬ ááŒááºááŸááºááŸá¯áá»á¬ážááŸáá·áº á á áºáá±ážááŸá¯áá»á¬ážááŒáá·áº á áááºáá¬ááᯠá¡áááºááŒá±á¬áá·áº áááºážáá»ááºá á±ááááºážá configuration file ááœáẠáá±á¬ááºááẠparameter áá áºáá¯ááá·áºááŒááºážááŒáá·áº ááœá²ááŒááºážá áááºááŒá¬ááŸá¯á¡ááœáẠáá¬áá¬á áá¬ážááᯠáááºááŸááºáá«áááºá Sonar'A:
sonar-project.properties:
...
sonar.language=ts
...
á áááºáá¬ááᯠááŒááºááœáá·áºááŒá®áž ááááºááᯠááŒáá·áºááŒáá«á áá¯á·á
ááœáŸááºážááŒá¯á¶ááŸá¯ áá¯á¶ážááááŸááá±á¬á·áá«á
Scanner ááŸááºáááºážááᯠááŒáá·áºáá»áŸáẠá¡á±á¬ááºáá«á á¬ááŒá±á¬ááºážááᯠááœá±á·ááá¯ááºáá«áááºá
ááá¯ááá¯áááºááŸá¬á áá»áœááºá¯ááºááá¯á·á ááá±á¬áá»ááºááá¯ááºáá»á¬ážááᯠááá¯ážááá¯ážááŸááºážááŸááºáž ááœáŸááºážááá¬ážáá«á
á¡ááŒá±á¡áá±ááŸá¬ á¡á±á¬ááºáá«á¡ááá¯ááºážááŒá áºáááº- ááá¬ážááẠáá±á¬ááºáá¶áá¬ážáááºá VueJs plugin ááœááºááŸááááºá SonarJSáááºáá°á áá¬áááºááŸááá²á Javascript ááá¯.
ááá¯á·áá±á¬áº á€áá¶á·ááá¯ážááŸá¯ááẠplugin ááœááºáááŸááá«á SonarTS á¡ááœáẠTSbug tracker ááœááºááá¬ážáááºáááºááŸááºááá¯ááœáá·áºáá¬ážááá·áºá¡ááŒá±á¬ááºáž Sonar'A:
á€á¡áá»ááºááᯠá¡áááºááŒá¯ááá·áº SonarQube developer áá»á¬ážá០ááá¯ááºá á¬ážááŸááºáá áºáŠážáá¶á០á¡ááŒá±á¡áá»áá¯á·ááŒá áºáááºá
áá«áá±ááá·áº á¡áá¬á¡á¬ážáá¯á¶ážá áá«ááá¯á·á¡ááœáẠá¡áá¯ááºáá¯ááºáááºá áááºážááá·áºááœááºáááºá áá¯ááºáááºá áááºážáááºážá
ááºážááŒáá·áºáá¡á±á¬áẠ"áááºáá¬".
áá¶á·ááá¯ážááŸá¯ááŸáááẠ.vue- ááá¯ááºáá»á¬áž Sonar'á¡áá¯á áá«ááᯠáá°ááá¯á·ááᯠá
ááºážá
á¬ážááŒáá·áºáá¡á±á¬ááºááá¯á· ááŒá±á¬ááŒáá·áºáá¡á±á¬áẠáááºáááºážá
á¬á
á±á¬ááº.
ááá·áºáááºáá»ááºáá áºáᯠááá·áºááŒáá«á áá¯á·á
sonar-project.properties:
...
sonar.typescript.file.suffixes=.ts,.tsx,.vue
...
á áááºáá¬ááᯠá áááºááá¯ááºáá¡á±á¬ááºá
áá² áá«ááá¯áááºáá±á¬á· á¡áá¬á¡á¬ážáá¯á¶ážáᬠáá¯á¶ááŸááºááŒááºááŒá áºáá±áá«ááŒá®á áá áºáá¯áááºážáá±á¬ áááá¯ááá¯ááºá¡ááœááºáá² ááŒá áºáá«áááºá áááºáááºážá á¬á á±á¬ááº. ááá¯ááá¯áááºááŸá¬ áá»áœááºá¯ááºááá¯á·ááẠááŒá¿áá¬ááᯠáá°áá®ááŒá±ááŸááºážááá¯ááºáá²á·áááºá VueJs+TS á¡ááœáẠSonarQube.
áá®á·áááºááá¯ááŒá®áž ááœáŸááºážááŒá¯á¶á¡áá»ááºá¡áááºááᯠáááºážáááºážáá±á¬áẠááá¯ážáááºá¡á±á¬áẠááŒáá¯ážá á¬ážááŒáá«á áá¯á·á
ááá¯á¡áá»áááºá¡áá áá»áœááºá¯ááºááá¯á· áá¯ááºáá±á¬ááºáá²á·áá±á¬ á¡áá¬áá»á¬áž-
- ááá±á¬áá»ááºááœáẠááá·áºáá¬ážáááºá Sonar- á áááºáá¬;
- áááºáá±á¬ááºááẠááŸá ááœáŸááºážááŒá¯á¶ááááºážá¡áá»ááºá¡áááºáá¯ááºáá¯ááºáááº;
- ááŒááºáááºáá¬ážáááºá Sonar- á áááºáá¬;
- áá¶á·ááá¯ážááŸá¯ááŒá¿áá¬ááá¯ááŒá±ááŸááºážáá²á·áááºá .vue-files + áááºáááºážá á¬á á±á¬ááº.
á ááºážáááºááœáŸááºážááŒá¯á¶ááŸá¯á¡ááŒááºá á¥ááá¬á áá¯ááºááœá¬ážááŒááºážááŸáá·áº ááá±á¬áá»ááºá áá¯ááºááŸá¯ááºááœá±ážááŸá¯ááŸáá·áº áááºá ááºáá±á¬ ááááºážááááºážáá»á¬áž ááœááºáá»ááºáá¬ááœáẠáá«áááºááá·áº áá¯ááºá¡áááºá¡ááœá±ážá¡ááœáẠá¡ááŒá¬ážá áááºáááºá á¬ážááœááºáá±á¬ááºážáá±á¬ á¡áá¯á¶ážáááºáá±á¬ á á¶áááºááŸááºáá»ááºáá»á¬ážáááºáž ááŸááá±ážáááºá
áááºááŸáá¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááœáẠplugin ááŸáá·áºá¡áá¯ááºáá¯ááºáááºá TS (SonarTS) á¡áá¯ááºáááŒá áºáá«á CPD (Copy Paste Detector) áá¯ááºááá¯ááºážáá»á¬ážááᯠáá±ááœááºáá«á .vue- ááá¯ááºáá»á¬ážá
áá¯ááºááœá¬ážááŒááºážá áá±á«ááºážá ááºááŸá¯á¡ááŒá±á¡áá±ááᯠáááºáá®ážáááºá á¡á áááºá¡ááá¯ááºážááá¯ááºááᯠá¡ááŒá¬ážá¡áááºáá áºáá¯ááŒáá·áº áááá¹áá°ááœá¬ážááŒá®áž áá¯ááºááá¯á·áááºáž ááá·áºáá«á main.ts dummy áá¯ááºáá±á¬ááºáá»ááºááᯠá¡ááŒá¬ážá¡áááºáá áºáá¯ááŒáá·áº ááœá¬ážáá«á áá¯á¶áá°ááœá¬ážááŒááºážááŸááááŸá á á áºáá±ážááẠ.vueááŸááºá· .ts - ááá¯ááºáá»á¬ážá
main.ts:
...
function name(params:string): void {
console.log(params);
}
...
áááºážááá¯áá¯ááºáá±á¬ááºáááºá configuration line ááᯠáá¬áá®ááŸááºáá»ááºáá±ážááẠááá¯á¡ááºáááº-
sonar-project.properties:
...
sonar.exclusions=src/main.ts
...
á ááºážáááºááŒááºážááŸáá·áºá¡áá° á áááºáá¬ááᯠááŒááºáááºá áááºááŒáá«á áá¯á·á
yarn test && yarn run sonar
áá¯ááºáá«áááºá áá»áœááºá¯ááºááá¯á·áá²á· ááœáŸááºážááŒá¯á¶ááŸá¯ áá»ááœá¬ážáááá·áºáááºá áá«áá±ááá·áº á¡áᯠáá»áœááºáá±á¬áºááá¯á· á¡á²áá«ááᯠá áááºááááºá á¬ážáá±á¬á·áá°ážá
áá¯ááºáá»ááºážáá»á¬ážááœá¬ážááŒááºážá á ááºážáááºážáá»ááºáá»á¬ážá¡áá áá»áœááºá¯ááºááá¯á· ááœá±á·ááááá·áºáááº-
á á áºáá±ážááẠáá»áœááºá¯ááºááá¯á· á¡áá¯á¶ážááŒá¯áá«áááºá CPD-á¡áá¯á¶ážáááºááŸá¯ - jscpd:
npx jscpd src
áá¯ááºááá¯ááºážáá»á¬ážá¡ááœááº
áááºážááᯠá¡áá¬ááẠááááºá¡ááºáá¬ážááŸááºážáá»á¬ážááœáẠááŒá±ááŸááºážááá¯ááºáááºááŒá áºáááºá SonarJS(TS). áááºážááá¯á·ááẠဠplugins ááŸá áºáá¯ááᯠáá áºáá¯áááºážá¡ááŒá áºááá¯á· áááŒááºážááŒááºáž áá±á«ááºážá ááºážááẠá áááºáá±ááŒá® ááŒá áºááŒá±á¬ááºáž áá»áœááºá¯áẠáááááŒá¯á á±ááá¯áá«áááºá SonarJSáá«áááºáá¬ááŸááºáááºá
ááᯠáá»áœááºá¯ááºááẠááœáŸááºážááŒá¯á¶á¡áá»ááºá¡áááºáá»á¬ážááᯠááá¯ážáááºá á±ááá·áº ááœá±ážáá»ááºááŸá¯ááᯠá ááºážá á¬ážáá»ááºáá«áááºá
ááá¯á¡áá»áááºá¡áá ááá±á¬áá»ááºáá áºáá¯áá¯á¶ážá¡ááœááºááŸáá·áº á¡áá°ážáááŒáá·áº ááá¯ááºáá»á¬ážá¡ááœáẠáá¬ááá¯ááºááŸá¯ááºážáááºááŸááºáá»ááºáá»á¬ážááŒáá·áº á ááºážáááºááŸá¯ááœáŸááºážááŒá¯á¶ááŸá¯ááᯠáá»áœááºá¯ááºááá¯á·ááœá±á·ááŒááºááá¯ááºáá«áááºá ááá¯á·áá±á¬áº ááá¬áá¡ááŒá±á¬ááºáž á¡áá»ááºá¡áááºáá»á¬ážááŒáá·áº á€ááœáŸááºááááºážááᯠáá»á²á·ááœááºááẠááŒá áºááá¯ááºáááºá áá°áá áºááá±á¬áá»ááºá¡ááœáẠá ááºážáááºááŸá¯áá»á¬ážá¡ááŒáẠááá¯ááºáá»á¬ážá áááºá ááºááŸá¯á
áááºááá¯ááºáá²á· á
á¬ááŒáá·áºááá¯ááºááŸááááºá ááŸá- á¡á
á®áááºáá¶á
á¬ááᯠformat á¡ááŒá
áºááŒá±á¬ááºážáá«á Sonar'A:
áá±áá¯áá»á
ááºážáááºáá±áᬠ-
áá»áœááºá¯ááºááá¯á·áááá±á¬áá»ááºááœáẠá€á á¬ááŒáá·áºááá¯ááºááᯠááá·áºááœááºážááŒáá«á áá¯á·á
yarn add jest-sonar-reporter
áááºážááᯠconfiguration ááœááºááá·áºáá«á ááŸá:
package.json-
âŠ
"testResultsProcessor": "jest-sonar-reporter"
âŠ
áá² á ááºážáááºááŒáá·áºáá¡á±á¬ááºá
yarn test
ááá¯á·áá±á¬áẠááá±á¬áá»ááºá á¡ááŒá áºááœáẠááá¯ááºáá áºáᯠáááºáá®ážáá«áááºá test-report.xml.
áááºážááᯠconfiguration ááœááºá¡áá¯á¶ážááŒá¯ááŒáá«á áá¯á· Sonar'A:
sonar-project.properties:
âŠ
sonar.testExecutionReportPaths=test-report.xml
âŠ
ááŒá®ážáá»áŸáẠá áááºáá¬ááᯠááŒááºáááºá áááºáá«á
yarn run sonar
á¡ááºáá¬áá±á·á áºááŸá¬ áá¬ááœá±ááŒá±á¬ááºážáá²ááœá¬ážáá² ááŒáá·áºáá¡á±á¬áẠSonar'A:
ááŒá®ážáá±á¬á· áá¬á០áááŒá±á¬ááºážáá²áá«áá°ážá á¡ááŸááºááŸá¬ Sonar ááẠJest á¡á á®áááºáá¶á á¬ááœáẠáá±á¬áºááŒáá¬ážáá±á¬ ááá¯ááºáá»á¬ážááᯠááá¯ááºáá»á¬ážá¡ááŒá Ạááá·áºááœááºážá ááºážá á¬ážááŒááºážáááŸááá±á áá°áá áº- á ááºážáááºááŸá¯áá»á¬ážá á€á¡ááŒá±á¡áá±ááᯠááŒá¯ááŒááºáááºá¡ááœááºá áá»áœááºá¯ááºááá¯á·ááẠááœá²á·á ááºážááŸá¯áá±á¬ááºááᯠá¡áá¯á¶ážááŒá¯áá«áááºá Sonar sonar.testsá ááºážáááºááŸá¯áá»á¬ážááŒáá·áº ááá¯ááºááœá²áá»á¬ážááᯠáá»áœááºá¯ááºááá¯á· á¡ááá¡áááºáž ááœáŸááºááŒáá±ážááẠ(ááᯠáá»áœááºá¯ááºááá¯á·ááœáẠáá áºáá¯áᬠááŸááááº)á
sonar-project.properties:
âŠ
sonar.tests=src/components/__tests__
âŠ
á áááºáá¬ááᯠááŒááºáááºá áááºááŒáá«á áá¯á·á
yarn run sonar
á¡ááºáá¬áá±á·á áºááŸá¬ áá¬ááœá±ááŒá±á¬ááºážáá²ááœá¬ážáá² ááŒáá·áºáá¡á±á¬ááºá
ááᯠáá»áœááºá¯ááºááá¯á·á á¡áá±á¡ááœááºááᯠááœá±á·ááŒááºáááŒá®ááŒá áºáááºá áá°áá áº-tests ááŸáá·áº á¡ááœááºážááá¯ááºážááá¯ááŸáááºááŒááºážááŒáá·áº áá¡á±á¬ááºááŒááºáá«áá ááá±á¬áá»ááºááá¯ááºáá»á¬ážááŒá¬ážááœáẠá€áá¶áá«ááºáááŒáá·áºáá»ááºááŸá¯ááᯠáá»áœááºá¯ááºááá¯á·ááœá±á·ááŒááºááá¯ááºáááº-
áá±á¬ááºáá»ááº
ááá¯á·ááŒá±á¬áá·áº á ááºáááºáááŒáẠááœá²ááŒááºážá áááºááŒá¬ááẠáááááá¬áá áºáá¯ááᯠáá»áœááºá¯ááºááá¯á· ááŒáá·áºááŸá¯áá²á·áááºá SonarQube. áá±ážáá¬ážáá²á· ááá±á¬áá»ááºáá áºáá¯áá²ááᯠá¡á±á¬ááºááŒááºá áœá¬ áá±á«ááºážá ááºážááá¯ááºáá«áááºá VueJs+TS. ááá¯ááºáááºáá®ááŸá¯ááá¯ááºáᬠááŒá¿áá¬á¡áá»áá¯á·ááᯠááŒá±ááŸááºážáá²á·áááºá á ááºážáááºááŸá¯ á¡áá»á¯á¶ážáááºááŸá¯ ááœáŸááºááááºážá á¡áá»ááºá¡ááẠá¡ááŒá±á¬ááºážá¡áá¬ááᯠáá»áœááºá¯ááºááá¯á· ááá¯ážááŒáŸáá·áºáá¬ážáá«áááºá á€áá±á¬ááºážáá«ážááœááºá áá»áœááºá¯ááºááá¯á·ááẠáá¯ááºá¡áááºá¡ááœá±ážá¡ááœáẠá á¶áááºááŸááºáá»ááºáá»á¬ážáá²á០áá áºáá¯ááá¯áᬠá á áºáá±ážáá²á·ááẠ(á¡áááá¡áá»ááºáá»á¬ážáá²á០áá áºáᯠááŒá áºááá¯ááºáááº)á SonarQube áá±ážáááºážááŸá¯á ááºážáááºááŒááºážá¡áá«á¡ááẠá¡ááŒá¬ážáá±á¬ á¡áááºá¡ááœá±ážáááºááŸááºáá»ááºáá»á¬ážááᯠáá¶á·ááá¯ážáá±ážáááºá ááá¯á·áá±á¬áº á€á¡ááºá¹áá«áááºáá»á¬ážá¡á¬ážáá¯á¶ážááᯠá¡ááŒáá·áºá¡áááááá¯ááºáá«á á¡ááá¯ááºážá¡ááá¯ááºáž- áá¬ážááŸááºážáá»á¬ážá á áááºáááºá á¬ážá áá¬áá±á¬ááºážááŒá®áž á¡áá¯á¶ážáááºáá±á¬á¡ááºá¹áá«áááºáá»á¬ážáá²á០áá áºáá¯ááŸá¬ áá±á«ááºážá ááºážááŒááºážááŒá áºáá«áááºá SonarQube GitLab ááŸáá·áº BitBucket áá²á·ááá¯á·áá±á¬ áá¯ááºááá¯ááŸá±á¬ááºááŸá¯ á á®áá¶ááá·áºááœá²ááŸá¯á áá áºá¡áá»áá¯ážáá»áá¯ážááŒáá·áºá áá¬ážáá®ážááẠmerge pull(merge) áá±á¬ááºážááá¯áá»ááº'a ááẠá¡áá»á¯á¶ážáááºááŸá¯ áá»áááºážááœá¬ážáá±á¬á¡áá« repository á áááºááá¬áááœá²ááá¯á·á áá«áá±ááá·áº áá«á áá¯á¶ážáááœá²ááŒá¬ážáá²á· áá±á¬ááºážáá«ážáá áºáá¯ááºá¡ááœáẠáá¬ááºáááºážáá áºáá¯ááºáá«á
PS: áá¯ááºáá¯á¶á
á¶ááŒáá·áº áá±á¬ááºážáá«ážááœáẠáá±á¬áºááŒáá¬ážááá·áº á¡áá¬á¡á¬ážáá¯á¶ážááᯠáááŸáááá¯ááºáá«áááºá
á
á¬áááºážááœááºážá¡áá¯á¶ážááŒá¯áá°áá»á¬ážáᬠá
á
áºáááºážááœáẠáá«áááºááá¯ááºáá«áááºá
ááẠSonarQube ááááºáá±á¬ááºážááᯠá¡áá¯á¶ážááŒá¯áá«ááá¬ážá
-
26,3%áá¯ááºáááº5
-
15,8%áá¶áá«áẠááá
-
15,8%áá®ááááºáá±á¬ááºážá¡ááŒá±á¬ááºáž ááŒá¬ážááŒá®áž á
-
10,5%áá®ááááºáá±á¬ááºážá¡ááŒá±á¬ááºáž ááŒá¬ážáá°ážááŒá®áž ááá¯á¶ážáá»ááºáá°ážá
-
0,0%ááá°áá®áá²á· platform0 ááᯠáá¯á¶ážáá±áá«áááºá
-
31,6%áá°á·á¡ááŒá±á¬ááºážááᯠááááá¯á¶ážááŒá¬ážáá°ážáᬠá
á¡áá¯á¶ážááŒá¯áá° ááá áŠáž áá²áá±ážáá²á·áááºá á¡áá¯á¶ážááŒá¯áá° 19 áŠáž ááŒá¬ážáá±áá²á·áá«áááºá
source: www.habr.com