Praktyczna Java. SonarQube

By 19 June 2016 Praktyczna Java

Po ostat­nim wpisie o Check­style, nie sposób nie wspom­nieć o innym narzędz­iu — Sonar­Qube. Zaprasza­my na kole­jną por­cję infor­ma­cji o staty­cznej anal­izie kodu oraz o tym, jak może Ci pomóc w codzi­en­nej pracy.

SonarQube vs Checkstyle

Choć oba narzędzia bazu­ją na tym samym pode­jś­ciu — staty­cznej anal­izie kodu (tj. anal­izie kodu źródłowego bez kom­pi­lowa­nia go i uruchami­a­nia) — są między nimi znaczące różnice. Przede wszys­tkim Check­style jest bib­lioteką — możli­wą do uru­chomienia ‘w locie’ w trak­cie budowa­nia pro­jek­tu, ale nie prze­chowu­jącą żad­nych infor­ma­cji w cza­sie. Sonar­Qube jest bardziej sys­te­mem — wyma­ga insta­lacji zan­im będziemy mogli go uży­wać, ale zapew­nia jed­nocześnie kom­plet infor­ma­cji (nie tylko o prob­lemach, ale także o zmi­anach — przykład­owo: jakie prob­le­my się pojaw­iły / jakie zostały rozwiązane od ostat­niej zmi­any). Infor­ma­c­je te prze­chowu­je w lokalnej bazie danych, z podzi­ałem na pro­jek­ty. Sonar­Qube pozwala także na anal­izę pro­jek­tu jako całoś­ci, na co nie pozwala sam Check­style — może np. znaleźć martwy kod, który nigdy nie jest wywoły­wany lub inne prob­le­my, które wys­tępu­ją na przestrzeni kilku klas/pakietów.

W tym miejs­cu warto wspom­nieć, że Sonar­Qube może korzys­tać z reguł Check­style (w rzeczy­wis­toś­ci Check­style jest uruchami­any jako narzędzie przez Sonar­Qube). To bard­zo wygodne rozwiązanie jeśli chodzi o ciągłą inte­grację — np. w połacze­niu z Jenk­in­sem czy innym podob­nym systemem.

Pod­sumowu­jąc — żadne z narzędzi nie zastępu­je drugiego, ale świet­nie się uzupełniają :)

Instalacja SonarQube

Sonar­Qube jest stwor­zony w Javie i jako taki moż­na go uru­chomić na dowol­nym ser­w­erze aplikacji (także na ser­w­erze Tom­cat). Do dzi­ała­nia wyma­gana jest także baza danych, gdzie prze­chowywane są wszys­tkie infor­ma­c­je. Szczegółowy porad­nik krok po kroku zna­jdziesz w doku­men­tacji.

Insta­lacji możesz także dokon­ać na lokalnym kom­put­erze, musisz tylko pamię­tać, aby uru­chomić ser­w­er za każdym razem, kiedy planu­jesz go użyć.

Tutaj dodatkowa uwa­ga — ponieważ komu­nikac­ja z ser­w­erem odby­wa się za pośred­nictwem sieci, warto wcześniej pomyśleć jak planu­jesz korzys­tać z Sonar­Qube — jeśli tylko do devel­op­men­tu, lokalny kom­put­er będzie lep­szym rozwiązaniem niż ser­w­er w chmurze; jeśli jed­nak będzie głównie wyko­rzysty­wany przez narzędzie CI (np. Jenk­in­sa), lep­szym rozwiązaniem będzie insta­lac­ja na tym samym serwerze.

Korzystanie z SonarQube

Korzys­tanie z Sonar­Qube jest możli­we na kil­ka sposobów — aby gro­madz­ić statysty­ki i trendy może­my uruchami­ać anal­izę z poziomu kon­soli lub naszego środowiska CI. Może­my także sko­rzys­tać z wty­cz­ki do Mave­na jako formy wery­fikacji lub zin­te­grować go z Eclipse — zarówno lokalnie jak i korzys­ta­jąc z ‘cen­tral­nych’ reguł dla projektu.

Uruchamianie z konsoli

Najbardziej pod­sta­wową opcją jest uruchami­an­ie anal­izy z poziomu kon­soli — wymo­giem jest, że na danym ser­w­erze musi zna­j­dować się kod źródłowy pro­jek­tu, który chce­my anal­i­zować (nie musi to być jed­nak ser­w­er, na którym dzi­ała ‘ser­werowa’ część Sonar­Qube — może­my połączyć się z nią zdalnie).

Aby ten sposób anal­izy zadzi­ałał, konieczne jest utworze­nie pliku sonar-project.properties, w którym określamy id pro­jek­tu (musi być unikalny dla danego ser­w­era), nazwę wyświ­et­laną pro­jek­tu (może być dowol­na) oraz dodatkowe para­me­try takie jak lokaliza­cję plików z kodem, kodowanie źródeł itp. Przykład­owy min­i­mal­isty­czny plik może wyglą­dać następująco:

sonar.projectKey=my:project
sonar.projectName=Mój projekt
sonar.projectVersion=1.0
sonar.sources=./src/main/java

Następ­nie wystar­czy w kat­a­logu głównym wywołać komendę sonar-scan­ner (uprzed­nio oczy­wiś­cie instalu­jąc Sonar­Qube), dzię­ki czemu kod zostanie przeanal­i­zowany, a wyni­ki anal­izy będą dostęp­ne na ser­w­erze oraz za pomocą API.

Peł­na doku­men­tac­ja uruchami­a­nia z poziomu konsoli

Integracja z Mavenem

Drugą opcją jest inte­grac­ja za pośred­nictwem Mave­na — z prak­ty­cznego punk­tu widzenia dzi­ała ona podob­nie do wywoła­nia z kon­soli — różnicą jest jed­nak to, że może­my pow­iązać anal­izę z pro­ce­sem budowa­nia, dzię­ki czemu nie musimy pamię­tać o dodatkowych komen­dach. Co więcej — może­my też skon­fig­urować go ‘glob­al­nie’ dla całego naszego kom­put­era, dzię­ki czemu zawsze wywołanie mvn sonar:sonar spowodu­je anal­izę bieżącego pro­jek­tu. Oczy­wiś­cie także w tym wypad­ku wyma­gany jest opisany wyżej plik .prop­er­ties. Pod­sta­wowa kon­fig­u­rac­ja sprowadza się do doda­nia następu­jącego frag­men­tu do pliku settings.xml (zna­jdziesz go w kat­a­logu MAVEN_HOME, zwyk­le jest to kat­a­log o nazwie .m2 umieszc­zony w kat­a­logu domowym użytkownika):

<settings>
    <pluginGroups>
        <pluginGroup>org.sonarsource.scanner.maven</pluginGroup>
    </pluginGroups>
    <profiles>
        <profile>
            <id>sonar</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <sonar.host.url>http://myserver:9000</sonar.host.url>
            </properties>
        </profile>
    </profiles>
</settings>

Powyższa kon­fig­u­rac­ja nie jest stricte wyma­gana — plu­g­in sonar zadzi­ała także bez niej, o ile wszys­tkie para­me­try są domyślne (tzn. ser­w­er dzi­ała lokalnie i nie są wyma­gane login lub hasło do jego użycia).

Doku­men­tac­ja na tem­at inte­gracji z Mavenem

Integracja z Jenkinsem

Jed­nym z najwygod­niejszych sposobów inte­gracji jest pow­iązanie z Jenk­in­sem (lub innym środowiskiem CI). W ten sposób za każdym razem, kiedy będziemy budowali kole­jne zmi­any w pro­jek­cie, zostanie wyko­nana anal­iza — jej wyni­ki będą dostęp­ne w pan­elu Sonar­Qube (oraz za pośred­nictwem API).

Inte­grac­ja sprowadza się do kon­fig­u­racji stosownego plug­inu w Jenk­in­sie — szczegółowy opis wraz ze screena­mi zna­jdziesz w konfiguracji.

Doku­men­tac­ja doty­czą­ca inte­gracji z Jenkinsem
Wpis na blogu pro­gramisty opisu­ją­cy sposób integracji

Integracja z Eclipsem (lub innym IDE)

Czwartym sposobem na inte­grac­je jest uży­cie plug­inu do naszego IDE — np. Eclipse. Ten sposób inte­gracji jest wyjątkowy, ponieważ nie wyma­ga insta­lacji ser­w­era. Jeśli potrze­bu­jesz feed­backu w trak­cie pisa­nia kodu, ale nie zależy Ci na statystykach w cza­sie czy tren­dach, to może być bard­zo przy­dat­na cecha ;) Plu­g­in ten posi­a­da dwie opc­je — domyśl­nie korzys­ta z ‘lokalnych’ ustaw­ień i nie wyma­ga komu­nikacji z ser­w­erem. Może­my także skon­fig­urować połącze­nie, dzię­ki czemu reguły anal­izy pobier­ane są z ser­w­era dla tego konkret­nego pro­jek­tu — jest to świetne rozwiązanie w więk­szych projektach.

Inte­grac­ja sprowadza się podob­nie jak w przy­pad­ku Jenk­in­sa do insta­lacji plug­inu — jest szy­b­ka i bezprob­le­mowa, dokład­ny opis wraz ze screena­mi i wyjaśnie­niem poszczegól­nych opcji zna­jdziesz w dokumentacji:

Strona plug­inu do Eclipse z opisem konfiguracji

Inne IDE

Oczy­wiś­cie poza Eclipse możli­wa jest także inte­grac­ja z inny­mi IDE — np. Intel­liJ IDEA. Więcej infor­ma­cji, także o kon­fig­u­racji, zna­jdziesz na stron­ie Sonar Lint.

Podsumowanie

Sonar­Qube, mimo że wyma­ga nieco więcej kon­fig­u­racji niż np. Check­style, zde­cy­dowanie jest bard­zo wartoś­ciowym narzędziem — szczegól­nie w kon­tekś­cie obser­wowa­nia trendów w pro­jek­cie i stosownego reagowa­nia (jeśli np. ilość długu tech­nicznego rośnie wraz z akty­wnym roz­wo­jem pro­jek­tu, być może warto poświę­cić jeden sprint na jego eliminację?).

Podob­nie jak w przy­pad­ku Check­style, najwięk­szą wartość uzyskasz sto­su­jąc go w pro­jek­cie, w którym pracu­je więcej osób, ale także dla Twoich pry­wat­nych pro­jek­tów może on przynieść wiele korzyś­ci. Warto spróbować — całość jest Open Source na licencji GPL3 (ist­nieje możli­wość wykupi­enia płat­nego sup­por­tu, dodatkowych mod­ułów do innych języków itp)