SavÄ darbÄ mÄs aktÄ«vi izmantojam platformu SonarQube kvalitÄtes saglabÄÅ”anai augstÄ lÄ«menÄ«. IntegrÄjot kÄdu no projektiem, kas tika rakstÄ«ts uz VueJs+Typescript, radÄs problÄmas. TÄdÄļ vÄlÄtos sÄ«kÄk pastÄstÄ«t par to, kÄ izdevÄs tÄs atrisinÄt.

Å ajÄ rakstÄ bÅ«s runa, kÄ jau minÄju iepriekÅ”, par platformu SonarQube. Nedaudz teorijas ā kas tas Ä«sti ir tiem, kas par to dzird pirmo reizi:
SonarQube (buvusÄ« Sonar) ā atvÄrtÄ koda platforma nepÄrtrauktai analÄ«zei (angļu val. continuous inspection) un koda kvalitÄtes mÄrīŔanai.
Atbalsta koda analÄ«zi un kļūdu meklÄÅ”anu, pamatojoties uz programmÄÅ”anas standartu MISRA C, MISRA C++, MITRE/CWE un CERT Secure Coding Standards. TÄpat spÄj atpazÄ«t kļūdas no sarakstiem OWASP Top-10 un CWE/SANS Top-25 programmÄÅ”anas kļūdÄm.
Lai arÄ« platforma izmanto dažÄdus gatavus rÄ«kus, SonarQube apvieno rezultÄtus vienÄ informÄcijas panelÄ« (angļu val. dashboard), vedot skriptu vÄsturi un ļaujot redzÄt kopÄjo tendenci programmatÅ«ras kvalitÄtes izmaiÅÄm izstrÄdes laikÄ.
VairÄk var uzzinÄt
Atbalsta lielu skaitu programmÄÅ”anas valodu. SaskaÅÄ ar informÄciju no iepriekÅ” minÄtÄ linka ā tas ir vairÄk nekÄ 25 valodas. Lai atbalstÄ«tu konkrÄtu valodu, nepiecieÅ”ams uzstÄdÄ«t attiecÄ«go paplaÅ”inÄjumu. Kopienas versijÄ ietilpst paplaÅ”inÄjums darbam ar Javascript (ieskaitot typesŃript), lai gan viki ir rakstÄ«ts pretÄji. Par Javascript atbild paplaÅ”inÄjums SonarJS, par Typescript SonarTS atbilstoÅ”i.
Lai nosÅ«tÄ«tu informÄciju par segumu, tiek izmantots oficiÄlais klients sonarqube-scanner, kurÅ”, izmantojot iestatÄ«jumus no config-faila, nosÅ«ta Å”os datus uz serveri SonarQube turpmÄkai konsolidÄcijai un agregÄcijai.
Lai Javascript ir TÄtad, sÄksim soli pa solim Ä«stenoÅ”anu SonarQube par Vue-projektam, kurÅ” izmanto Typescript.
Lai izveidotu serveri SonarQube izmantosim docker-compose.
sonar.yaml:
version: '1'
services:
simplesample-sonar:
image: sonarqube:lts
ports:
- 9001:9000
- 9092:9092
network_mode: bridgePalaiŔana:
docker-compose -f sonar.yml upPÄc tam SonarQube bÅ«s pieejams adresÄ ā .

PaÅ”laik tajÄ nav projektu, un tas ir taisnÄ«ba. MÄs labosim Å”o situÄciju. Par pamatu es ÅÄmu oficiÄlo projekta piemÄru VueJS+TS+Jest.NoklonÄsim to pie sevis:
git clone https://github.com/vuejs/vue-test-utils-typescript-example.gitVispirms mums jÄuzstÄda klients, SonarQubekas tiek saukts sonar-scanner, lai npm ir apvalks:
yarn add sonarqube-scannerUn tūlīt pievienosim komandu scripts darbam ar to.
package.json:
{
ā¦
scripts: {
...
"sonar": "sonar-scanner"
...
},
ā¦
}TÄlÄk, lai strÄdÄtu ar skaneru, ir nepiecieÅ”ams norÄdÄ«t projekta iestatÄ«jumus speciÄlÄ failÄ. SÄksim ar pamatiem.
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 ā adrese Sonarāa;
- sonar.projectKey ā unikÄls projekta identifikators serverÄ« Sonarāa;
- sonar.projectName ā tÄ nosaukums, ko var mainÄ«t jebkurÄ brÄ«dÄ«, jo projekta identifikÄcija notiek pÄc projectKey;
- sonar.sources ā mape ar avotiem, parasti tas ir src, bet var bÅ«t jebkas. Å Ä« mape tiek noteikta attiecÄ«bÄ pret saknes mapÄ, no kuras tiek palaists skaneris;
- sonar.tests ā parametrs, kas iet kopÄ ar iepriekÅ”Äjo. TÄ ir mape, kur atrodas testi. Å ajÄ projektÄ Å”Ädas mapes nav, un tests atrodas blakus pÄrbaudÄmajam komponentam mapÄ ātestā, tÄpÄc mÄs to pagaidÄm ignorÄsim un izmantosim nÄkamo parametru;
- sonar.test.inclusions ā ceļŔ testiem, izmantojot masku, var bÅ«t vairÄki elementi, uzskaitÄ«ti ar komatu;
- sonar.sourceEncoding ā kodÄjums avota failiem.
Pirmajai skanera palaiÅ”anai viss ir gatavs, izÅemot galveno iepriekÅ”Äjo darbÄ«bu: paÅ”a testÄÅ”anas dzinÄja palaiÅ”anu, lai tas Ä£enerÄtu informÄciju par pÄrklÄjumu, ko vÄlÄk izmantos skaneris.
Bet tam nepiecieÅ”ams konfigurÄt testÄÅ”anas dzinÄju Ŕīs informÄcijas Ä£enerÄÅ”anai. Å ajÄ projektÄ testÄÅ”anas dzinÄjs ir Jest. Un tÄ iestatÄ«jumi atrodas atbilstoÅ”ajÄ faila sadaÄ¼Ä package.json.
Pievienosim Ŕos iestatījumus:
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*",
"!src/main.ts",
"!src/App.vue",
"!src/**/*.d.*",
"!src/**/*__tests__*"
],TÄtad, mÄs nosakÄm paÅ”u karogu nepiecieÅ”amÄ«bai aprÄÄ·inÄt pÄrklÄjumu un avotu (kopÄ ar izÅÄmumiem), uz kuru pamata tas tiks Ä£enerÄts.
Tagad palaidīsim testu:
yarn testMÄs redzÄsim sekojoÅ”o:

Iemesls ir tajÄ, ka paÅ”Ä komponentÄ kÄ tÄdam nav koda. Labosim to.
HelloWorld.vue:
...
methods: {
calc(n) {
return n + 1;
}
},
mounted() {
this.msg1 = this.msg + this.calc(1);
},
...TÄ bÅ«s pietiekami, lai aprÄÄ·inÄtu pÄrklÄjumu.
PÄc testu atkÄrtotas palaiÅ”anas pÄrliecinÄsimies par to:

EkrÄnÄ mums jÄredz informÄcija par pÄrklÄjumu, un projekta mapÄ tiks izveidota mape coverage ar informÄciju par testÄÅ”anas pÄrklÄjumiem vispÄrÄ«gÄ formÄtÄ LCOV (LTP GCOV paplaÅ”inÄjums).
Gcov ā brÄ«vi izplatÄma palÄ«grÄ«ka, lai izpÄtÄ«tu koda pÄrklÄjumu. Gcov Ä£enerÄ precÄ«zu izpildÄ«jumu skaitu katram operatoram programmÄ un ļauj pievienot anotÄcijas avota kodam. Gcov ir iekļauts kÄ standarta rÄ«ks GCC paketÄ.
Lcov ā grafiskais interfeiss gcov. Tas apkopo gcov failus no vairÄkiem avota failiem un izveido komplektu HTML lapu ar kodu un pÄrklÄjuma informÄciju. TÄpat tiek Ä£enerÄtas lapas navigÄcijas atviegloÅ”anai. Lcov atbalsta rindu, funkciju un novirzīŔanu pÄrklÄjumu.
PÄc testu izpildes informÄcija par pÄrklÄjumu tiks atrasta coverage/lcov.info.
Mums jÄnorÄda Sonarno kurienes to iegÅ«t. TÄpÄc pievienosim Å”Ädas rindas tÄ konfigurÄcijas failÄ. Bet ir viens moments: projekti var bÅ«t daudzvalodÄ«gi, tas ir, mappÄ src atrodas avoti vairÄku programmÄÅ”anas valodu un piederÄ«ba pie kÄdas no tÄm, un lÄ«dz ar to izmantotÄ spraudÅa izvÄle tiek noteikta pÄc tÄ paplaÅ”inÄjuma. InformÄcija par pÄrklÄjumu var bÅ«t glabÄta dažÄdÄs vietÄs dažÄdÄm programmÄÅ”anas valodÄm, tÄpÄc katrai PV nepiecieÅ”ama sava iestatÄ«jumu sadaļa. Mums projektÄ tiek izmantots Typescript, tÄpÄc mums nepiecieÅ”ama iestatÄ«jumu sadaļa tieÅ”i tai:
sonar-project.properties:
sonar.typescript.coveragePlugin=lcov
sonar.typescript.lcov.reportPaths=coverage/lcov.infoViss ir gatavs pirmÄ skenera palaiÅ”anai. VÄlos atzÄ«mÄt, ka projekts Sonartiks izveidots automÄtiski, palaižot skeneri Å”im projektam pirmo reizi. NÄkamajÄs reizÄs informÄcija jau tiks uzkrÄta, lai redzÄtu parametru izmaiÅu dinamiku laika gaitÄ.
TÄtad, izmantosim iepriekÅ” izveidoto komandu package.json:
yarn run sonar PiezÄ«me: varat arÄ« izmantot parametru -X lai iegÅ«tu detalizÄtÄku žurnÄlu.
Ja skeneris tikko tika palaists pirmo reizi, vispirms tiks lejupielÄdÄts paÅ”a skenera binÄrais fails. PÄc tam tas tiek palaists un sÄk skanÄt serveri SonarattiecÄ«bÄ uz instalÄtajiem spraudÅiem, tÄdÄjÄdi aprÄÄ·inot atbalstÄ«tÄs PV. TÄpat tiek lejupielÄdÄti citi dažÄdi parametri tÄ darbÄ«bai: quality profiles, active rules, metrics repository, server rules.


PiezÄ«me: par to sÄ«ki nepÄrtrauksim Å”ajÄ rakstÄ, bet vienmÄr varat vÄrsties pie oficiÄlajiem avotiem.
TÄlÄk sÄkas mapes analÄ«ze src par visu atbalstÄ«to programmÄÅ”anas valodu (ja nav skaidri norÄdÄ«ta kÄda konkrÄta) sÄkotnÄjo failu pieejamÄ«bas pÄrbaude ar to turpmÄku indeksÄciju.

TÄlÄk seko dažÄdi citi analÄ«zes veidi, uz kuriem Å”ajÄ rakstÄ nenonÄkam (piemÄram, tÄdi kÄ: linting, koda dublÄÅ”anÄs noteikÅ”ana u. c.).
Skeneru darbu noslÄdzot, notiek apkopotÄs informÄcijas agregÄcija, arhivÄÅ”ana un nosÅ«tīŔana uz serveri.
PÄc tam mÄs varam apskatÄ«t, kas ir iznÄcis tÄ«mekļa interfeisÄ:

KÄ redzam, kas ir iznÄcis, un tas pat rÄda kaut kÄdu pÄrklÄjumu, bet tas neatbilst mÅ«su Jest-ziÅojumam.
IeskatÄ«simies tuvÄk. ApskatÄ«sim projektu sÄ«kÄk, noklikŔķinÄsim uz pÄrklÄjuma vÄrtÄ«bas un "iekritÄ«sim" detalizÄtajÄ ziÅojumÄ par failiem:

Å eit mÄs redzam, ka papildus galvenajam pÄtÄ«tajam failam HelloWorld.vue, klÄtesoÅ”s ir arÄ« fails main.ts, kurÅ” arÄ« bojÄ visu pÄrklÄjuma ainu. Bet kÄ tad tÄ, mÄs to izslÄdzÄm no pÄrklÄjuma aprÄÄ·ina. JÄ, viss ir pareizi, bet tas notika lÄ«menÄ« Jest, taÄu skeneris to ir indeksÄjis, tÄpÄc tas iekļuvis tÄ aprÄÄ·inos.
Labosim to:
sonar-project.properties:
...
sonar.exclusions=src/main.ts
...VÄlos izdarÄ«t precizÄjumu: papildus tÄm mapÄm, kas norÄdÄ«tas Å”ajÄ parametrÄ, tiek pievienotas arÄ« visas mapes, kuras uzskaitÄ«tas parameterÄ sonar.test.inclusions.
PÄc skenera palaiÅ”anas redzam jau korektu informÄciju:


ApskatÄ«sim nÄkamo jautÄjumu ā KvalitÄtes profili. Es iepriekÅ” minÄju par vairÄku programmÄÅ”anas valodu atbalstu. SonarTo mÄs tieÅ”i novÄrojam. Bet mÄs zinÄm, ka projekts ir uzrakstÄ«ts TS, kÄpÄc tad lieki apgrÅ«tinÄt skeneri ar nevajadzÄ«gÄm manipulÄcijÄm un pÄrbaudÄm. AnalÄ«zes valodu norÄdÄ«sim, pievienojot vÄl vienu parametru konfigurÄcijas failÄ Sonar:
sonar-project.properties:
...
sonar.language=ts
...Atkal palaidÄ«sim skeneri un apskatÄ«sim rezultÄtu:

PÄrklÄjums ir pilnÄ«bÄ zudis.
Ja aplÅ«kosim skenera žurnÄlu, tad varam redzÄt sekojoÅ”o rindu:
![]()
TÄtad, mÅ«su projekta faili vienkÄrÅ”i netika indeksÄti.
SituÄcija ir Å”Äda: oficiÄlais atbalsts VueJs ir pieejams spraudnÄ« SonarJS, kas atbild par Javascript.

Bet Ŕī atbalsta nav spraudnÄ« SonarTS lai TS, par ko ir izveidots oficiÄls biļete kļūdu izsekoÅ”anas sistÄmÄ Sonar:
Å eit ir daži atbildes no viena no SonarQube izstrÄdÄtÄjiem, kas apstiprina Å”o faktu.


Bet mums taÄu viss bija kÄrtÄ«bÄ, uzsÄksiet jÅ«s. JÄ, tÄ ir, mÄÄ£inÄsim nedaudz "uzhakat".
Ja ir atbalsts .vue-failiem Sonartad tad, tadÄ, lÅ«dzu, mÄÄ£inÄsim pateikt viÅam, lai viÅÅ” tos apsver kÄ Typescript.
Pievienosim parametru:
sonar-project.properties:
...
sonar.typescript.file.suffixes=.ts,.tsx,.vue
...Palaižam skaneri:

Un, voilĆ , viss ir atgriezies pie ierastÄ, un ar vienu profilu tikai Typescript. Tas nozÄ«mÄ, ka izdevÄs atrisinÄt problÄmu ar atbalstu VueJs+TS lai SonarQube.
MÄÄ£inÄsim iet tÄlÄk un nedaudz uzlabot informÄciju par segumu.
Ko mÄs esam izdarÄ«juÅ”i lÄ«dz Å”im:
- pievienojÄm projektam Sonar-skaneri;
- konfigurÄjÄm Jest seguma informÄcijas Ä£enerÄÅ”anai;
- konfigurÄjÄm Sonar-skaneri;
- atrisinÄjÄm atbalsta problÄmu .vue-failiem + Typescript.
Bez testu seguma ir citi interesanti kvalitÄtes kritÄriji, piemÄram, kodu dublÄÅ”anÄs un rindu skaits (piedalÄs koeficientu, kas saistÄ«ti ar koda sarežģītÄ«bu, aprÄÄ·inÄÅ”anÄ) projektÄ.
PaÅ”reizÄjÄ spraudÅa realizÄcijÄ, lai strÄdÄtu ar TS (SonarTS) nedarbosies CPD (Copy Paste Detector) un koda rindu skaitīŔana .vue-failiem.
Lai izveidotu sintÄtisku situÄciju dublÄÅ”anÄs gadÄ«jumÄ, vienkÄrÅ”i dublÄsim komponenta failu ar citu nosaukumu, arÄ« pievienosim kodam main.ts tukÅ”u funkciju un dublÄsim to ar citu nosaukumu. Lai pÄrbaudÄ«tu dublÄÅ”anos, kÄ .vue, tÄ arÄ« .ts -failiem.
main.ts:
...
function name(params:string): void {
console.log(params);
}
...Tam nepiecieÅ”ams uz laiku noÅemt konfigurÄcijas rindu:
sonar-project.properties:
...
sonar.exclusions=src/main.ts
...PÄrstartÄsim skaneri kopÄ ar testÄÅ”anu:
yarn test && yarn run sonarMÄs, protams, zaudÄsim segumu, bet Å”obrid tas mÅ«s neuztrauc.
DublÄjoÅ”o koda rindu skatÄ«jumÄ redzÄsim:

PÄrbaudei izmantosim CPD-rÄ«ku ā jscpd:
npx jscpd src
Par koda rindÄm:

VisticamÄk, tas tiks atrisinÄts nÄkotnes spraudÅu versijÄs SonarJS(TS). VÄlos norÄdÄ«t, ka viÅi pakÄpeniski sÄk apvienot Å”os divus spraudÅus vienÄ SonarJS, kas, manuprÄt, ir pareizi.
Tagad vÄlÄtos apskatÄ«t iespÄju uzlabot seguma informÄciju.
PaÅ”laik mÄs redzam testu segumu procentos visÄ projektÄ un pÄc failiem specifiski. Bet ir iespÄja paplaÅ”inÄt Å”o rÄdÄ«tÄju ar informÄciju par unit-testiem projektÄ, kÄ arÄ« failu griezumÄ.
Ir bibliotÄka, kas spÄj Jest-ziÅojumu konvertÄt formÄtÄ, kas piemÄrots Sonar:
generic test data ā .
UzstÄdÄ«sim Å”o bibliotÄku savÄ projektÄ:
yarn add jest-sonar-reporterUn pievienosim to konfigurÄcijai Jest:
package.json:
ā¦
"testResultsProcessor": "jest-sonar-reporter"
ā¦Tagad veiksim testu:
yarn testPÄc tam projekta saknÄ tiks izveidots fails test-report.xml.
IeslÄgsim to konfigurÄcijÄ Sonar:
sonar-project.properties:
ā¦
sonar.testExecutionReportPaths=test-report.xml
ā¦Un pÄrstartÄsim skaneri:
yarn run sonarApskatÄ«sim, kas mainÄ«jies interfeisÄ Sonar:

Un nekas nav mainÄ«jies. ProblÄma ir tÄ, ka Sonar neuzskata failus, kas aprakstÄ«ti Jest ziÅojumÄ, par failiem unit-testiem. Lai novÄrstu Å”o situÄciju, izmantosim konfigurÄcijas parametru Sonar sonar.tests, kurÄ skaidri norÄdÄ«sim testu mapes (paÅ”laik mums ir tikai viena):
sonar-project.properties:
ā¦
sonar.tests=src/components/__tests__
ā¦PÄrstartÄsim skeneri:
yarn run sonarApskatÄ«sim, kas mainÄ«jies interfeisÄ:

Tagad mÄs redzam mÅ«su unit-testu skaitu un, noklikŔķinot, varam aplÅ«kot tÄ sadalÄ«jumu projekta failos:

SecinÄjums
TÄtad, mÄs izskatÄ«jÄm rÄ«ku nepÄrtrauktai analÄ«zei SonarQube. VeiksmÄ«gi integrÄjÄm tajÄ projektu, kas rakstÄ«ts VueJs+TS. AtrisinÄjÄm dažas saderÄ«bas problÄmas. PalielinÄjÄm informÄcijas sniegÅ”anas kvalitÄti par testÄÅ”anas segumu. Å ajÄ rakstÄ mÄs apskatÄ«jÄm tikai vienu no programmatÅ«ras kvalitÄtes kritÄrijiem (iespÄjams, vienu no galvenajiem), bet SonarQube atbalsta arÄ« citus kvalitÄtes kritÄrijus, tostarp droŔības testÄÅ”anu. TaÄu ne visas Ŕīs iespÄjas pilnÄ«bÄ pieejamas community-versijÄ. Viens no interesantÄkajiem un noderÄ«gÄkajiem risinÄjumiem ir integrÄcijas SonarQube ar dažÄdÄm koda versiju kontroles sistÄmÄm, piemÄram, tÄdÄm kÄ GitLab un BitBucket. Lai novÄrstu merge pull(merge) requestuz galveno repozitorija zaru, ja segÅ”anÄs samazinÄs. TaÄu Ŕī ir jau pavisam cita raksta stÄsts.
PS: Viss, kas rakstÄ«ts Å”ajÄ rakstÄ kodÄ, ir pieejams manÄ .
Tikai reÄ£istrÄtie lietotÄji var piedalÄ«ties aptaujÄ. , lÅ«dzu.
Vai Jūs izmantojat SonarQube platformu:
26,3%JÄ5
15,8%NÄ3
15,8%Es esmu dzirdÄjis par Å”o platformu un vÄlos to izmantot3
10,5%Es esmu dzirdÄjis par Å”o platformu un nevÄlos to izmantot2
0,0%Es izmantoju citu platformu0
31,6%Es pirmo reizi dzirdu par to6
19 lietotÄji balsoja. 3 lietotÄji atturÄjÄs.
Avots: habr.com
