Насколько сложно начать работу с проектом Gradle и проанализировать его с помощью SonarQube на местном уровне?
Ингредиенты:
SonarQube (ранее Sonar) — это платформа с открытым исходным кодом для непрерывного контроля качества кода.
Gradle — это система автоматизации сборки с открытым исходным кодом.
Docker позволяет упаковать приложение со всеми его зависимостями в стандартизированный модуль для разработки программного обеспечения.
«Насколько это легко?» был вопрос, который у меня возник после того, как я решил переформатировать свою компанию HP EliteBook с Windows в полноценный Linux Mint .
Итак, я уже поиграл с Docker, и IMHO, это работает намного приятнее в Linux, поэтому я подумал, что пришло время поиграть с ним еще немного и, возможно, получится проанализировать проект с помощью SonarQube без особых хлопот .
Итак, насколько это легко?
Шаг 1 — Получение SonarQube с Docker
Первое, что я отправился на поиски, был образ Docker, в котором уже есть SonarQube. Это будущее IMHO: запуск любых компонентов, которые вам нужны, внутри контейнера.
По крайней мере, для целей разработки и тестирования это большой выигрыш: не важно, какая ОС или личная рабочая среда, образ такой, какой он есть, и пока вы можете запускать Docker, вы будете «точно» знать, что будет работать.
Сейчас нет времени на создание образа, просто пригласите кого- нибудь, кто уже поделился им в собственной компании или на DockerHub.
Docker Hub — это каноническая платформа для публикации и использования образов контейнеров Docker.
Просто искал «сонар».
243 хранилища на данный момент. Были 2, которые привлекли мое внимание:
-
sonarqube— который является официальным. Имеет 165 звезд и 243 тысячи тяг . -
orangesignal/sonarкоторый имеет 2 звезды и 378 тяг -
tpires/sonar-serverкоторый имеет 18 звезд и 94 тысячи тяг.
Хотя номера №1 и №3, кажется, имеют более высокую комбинацию звезд / orangesignal/sonar , я orangesignal/sonar потому что он использовал Docker Compose .
Docker Compose
На странице DockerHub orangesignal / sonar есть ссылка на репозиторий GitHub. Клонировал это:
|
1
|
git clone https://github.com/orangesignal/docker-sonarqube.git |
Макет каталога:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
tvinke@picard ~ $ cd docker-sonarqube/tvinke@picard ~/docker-sonarqube $ tree.├── 3.6│ ├── docker-entrypoint.sh│ └── Dockerfile├── 3.7│ ├── docker-entrypoint.sh│ └── Dockerfile├── 4.0│ ├── docker-entrypoint.sh│ └── Dockerfile├── 4.1│ ├── docker-entrypoint.sh│ └── Dockerfile├── 4.2│ ├── docker-entrypoint.sh│ └── Dockerfile├── 4.3│ ├── docker-entrypoint.sh│ └── Dockerfile├── 4.4│ ├── docker-entrypoint.sh│ └── Dockerfile├── 4.5│ ├── docker-entrypoint.sh│ └── Dockerfile├── 5.0│ ├── docker-entrypoint.sh│ └── Dockerfile├── 5.1│ ├── docker-entrypoint.sh│ └── Dockerfile├── docker-build.bash├── docker-compose.yml├── example│ ├── docker-compose.yml│ ├── docker-entrypoint.sh│ ├── Dockerfile│ └── nginx-conf.d│ └── default.conf├── LICENSE├── README.md├── remove_all_stopped_containers.bash└── remove_all_untagged_images.bash12 directories, 30 files |
Различные версии SonarQube (на самом деле Dockerfiles ) и интересный docker-compose.yml содержащий «композицию».
docker-compose.yml
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
db: image: postgres:9 hostname: pgsql-01 ports: - 5432:5432 environment: - POSTGRES_DB=sonar - POSTGRES_USER=sonar - POSTGRES_PASSWORD=sonarsonar: image: orangesignal/sonar:latest hostname: sonar-01 links: - db ports: - 9000:9000 environment: - SONAR_JDBC_URL=jdbc:postgresql://pgsql-01:5432/sonar - SONAR_JDBC_USERNAME=sonar - SONAR_JDBC_PASSWORD=sonar |
Вместо H2 или MySQL говорится, что нужно использовать базу данных Postgres, используя образ Docker postgres:9 и запускать ее под определенным именем хоста и портом. За ним следует часть, где последняя опубликованная версия изображения orangesignal/sonar упоминается и связана с базой данных Postgres.
У меня уже был установлен Docker, но мне еще нужно было установить Docker Compose, чтобы иметь возможность работать
|
1
|
tvinke@picard ~/docker-sonarqube $ docker-compose up |
Это начинает весь Шебанг.
|
01
02
03
04
05
06
07
08
09
10
11
|
...sonar_1 | 2016.02.26 10:24:35 INFO web[o.s.s.s.IndexSynchronizer] Index source linessonar_1 | 2016.02.26 10:24:35 INFO web[o.s.s.s.IndexSynchronizer] Index userssonar_1 | 2016.02.26 10:24:35 INFO web[o.s.s.s.IndexSynchronizer] Index viewssonar_1 | 2016.02.26 10:24:35 INFO web[jruby.rack] jruby 1.7.9 (ruby-1.8.7p370) 2013-12-06 87b108a on Java HotSpot(TM) 64-Bit Server VM 1.8.0_66-b17 [linux-amd64]sonar_1 | 2016.02.26 10:24:35 INFO web[jruby.rack] using a shared (threadsafe!) runtimesonar_1 | 2016.02.26 10:24:41 INFO web[jruby.rack] keeping custom (config.logger) Rails logger instancesonar_1 | 2016.02.26 10:24:41 INFO web[o.a.c.h.Http11NioProtocol] Starting ProtocolHandler ["http-nio-0.0.0.0-9000"]sonar_1 | 2016.02.26 10:24:41 INFO web[o.s.s.a.TomcatAccessLog] Web server is startedsonar_1 | 2016.02.26 10:24:41 INFO web[o.s.s.a.EmbeddedTomcat] HTTP connector enabled on port 9000sonar_1 | 2016.02.26 10:24:42 INFO app[o.s.p.m.Monitor] Process[web] is up |
Доступ к панели инструментов SonarQube
На http: // localhost: 9000 сейчас SonarQube обслуживает:
Проекты еще не проанализированы.
Шаг 2 — Получение примера Gradle Project
Мне нужен был пример проекта Gradle.
Я мог бы выбрать создание чистого, основанного на Java проекта Gradle с нуля, но добавление некоторых источников и тестов для анализа заставило бы меня преодолеть 5-минутный срок, который я установил для себя.
Лучший вариант — просто использовать проект из собственного репозитория GitHub с примерами SonarQube:
|
1
|
tvinke@picard ~/workspace $ git clone https://github.com/SonarSource/sonar-examples.git |
Каталог /projects содержит примеры проектов для:
- различные анализаторы (SonarQube Runner, Maven, Ant)
- разные языки (Java, Cobol, .Net и т. д.)
- различные способы выполнения модульных тестов и получения данных покрытия кода
Примеры используют Sonar Runner, который больше не поддерживается. К счастью, проект java-gradle-simple был именно тем, что мне было нужно.
Вывод tree (еще один красивый инструмент Linux):
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
tvinke@picard ~/workspace/sonar-examples/projects/languages/java/gradle/java-gradle-simple $ tree.├── build.gradle├── README.md└── src ├── main │ └── java │ └── example │ └── Greeting.java └── test └── java └── example ├── FailingTest.java └── GreetingTest.java7 directories, 5 files |
Некоторые вещи, на которые я надеялся, что SonarQube может что-то сообщить. То, что я искал, было примером правильного build.gradle с использованием плагина Sonar Gradle.
build.gradle
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
apply plugin: 'java'apply plugin: 'org.sonarqube'apply plugin: 'jacoco'allprojects { ext.baseVersion = "0.1" ext.snapshotVersion = true group = "org.sonarqube" version = "$baseVersion" + (snapshotVersion ? "-SNAPSHOT" : "")}sonarqube { properties { property "sonar.projectName", "Java :: Simple Project :: SonarQube Scanner for Gradle" property "sonar.projectKey", "org.sonarqube:java-gradle-simple" property "sonar.jacoco.reportPath", "${project.buildDir}/jacoco/test.exec" }}buildscript { repositories { maven { } maven { } mavenLocal() } dependencies { classpath 'org.ajoberstar:gradle-jacoco:0.1.0' classpath 'org.sonarqube.gradle:gradle-sonarqube-plugin:1.0' }}test { ignoreFailures = true}repositories { repositories { maven { } }}dependencies { testCompile 'junit:junit:4.12'} |
Как видите, есть несколько плагинов:
|
1
2
3
|
apply plugin: 'java'apply plugin: 'org.sonarqube'apply plugin: 'jacoco' |
Помимо плагина Java, есть также плагин SonarQube и плагин JaCoCo. Последний предоставляет метрики покрытия кода Java с помощью библиотеки JaCoCo («Покрытие кода Java»), созданной командой EclEmma.
Кроме того, настроены некоторые другие вещи, такие как свойства сонара:
|
1
2
3
4
5
6
7
|
sonarqube { properties { property "sonar.projectName", "Java :: Simple Project :: SonarQube Scanner for Gradle" property "sonar.projectKey", "org.sonarqube:java-gradle-simple" property "sonar.jacoco.reportPath", "${project.buildDir}/jacoco/test.exec" }} |
Часть предназначена для идентификации проекта внутри SonarQube, если вы используете его для нескольких проектов.
Я оставил все как есть, потому что я могу просто начать …
Шаг 3 — Анализ с использованием Gradle Sonar Plugin
Плагин Gradle Sonar использует все виды значений по умолчанию и использует большую часть информации из сборки Gradle для анализа проекта.
Поэтому я надеялся, что Things Just Worked (что является ловушкой, если все идет гладко с минимальной конфигурацией), так что просто посмотрите, что произойдет, если мы сделаем так:
|
1
|
gradle sonarqube |
С настройками SonarQube по умолчанию это сработало бы, и была бы найдена локальная база данных H2.
Где на самом деле SonarQube?
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
INFO: Work directory: /home/tvinke/workspace/sonar-examples/projects/languages/java/gradle/java-gradle-simple/build/sonarINFO: SonarQube Server 5.1.211:38:15.164 INFO - Load global repositories11:38:15.281 INFO - Load global repositories (done) | time=119ms11:38:15.283 INFO - Server id: 2016022610243111:38:15.285 INFO - User cache: /home/tvinke/.sonar/cache11:38:15.292 INFO - Install plugins11:38:15.329 INFO - Install JDBC driver11:38:15.335 INFO - Create JDBC datasource for jdbc:h2:tcp://localhost/sonar:sonarqube FAILEDFAILURE: Build failed with an exception.* What went wrong:Execution failed for task ':sonarqube'.> Unable to execute Sonar* Try:Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.BUILD FAILEDTotal time: 2.41 secs |
К сожалению, наш docker-compose.yml говорит иначе — вместо этого мы используем базу данных Postgres с другими настройками JDBC, а не базу данных H2 в jdbc:h2:tcp://localhost/sonar .
Мы можем либо переопределить значения по умолчанию, установив некоторые глобальные свойства в ~/.gradle/gradle.properties например
|
1
2
3
4
|
systemProp.sonar.host.url=http://localhost:9000systemProp.sonar.jdbc.url=jdbc:postgresql://localhost/sonarsystemProp.sonar.jdbc.username=sonarsystemProp.sonar.jdbc.password=sonar |
Или передайте его в командной строке (сохраняя значения по умолчанию):
|
1
2
3
|
gradle sonarqube -Dsonar.jdbc.url=jdbc:postgresql://localhost:5432/sonar -Dsonar.verbose=true |
SonarQube начинает и заканчивает быстро анализировать этот небольшой проект:
|
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
|
tvinke@picard ~/workspace/sonar-examples/projects/languages/java/gradle/java-gradle-simple $ gradle sonarqube -Dsonar.jdbc.url=jdbc:postgresql://localhost:5432/sonar:compileJava UP-TO-DATE:processResources UP-TO-DATE:classes UP-TO-DATE:compileTestJava UP-TO-DATE:processTestResources UP-TO-DATE:testClasses UP-TO-DATE:test UP-TO-DATE:sonarqubeINFO: Default locale: "en_US", source code encoding: "UTF-8" (analysis is platform dependent)INFO: Work directory: /home/tvinke/workspace/sonar-examples/projects/languages/java/gradle/java-gradle-simple/build/sonarINFO: SonarQube Server 5.1.212:00:29.104 INFO - Load global repositories12:00:29.184 INFO - Load global repositories (done) | time=81ms12:00:29.185 INFO - Server id: 2016022610243112:00:29.186 INFO - User cache: /home/tvinke/.sonar/cache12:00:29.192 INFO - Install plugins12:00:29.219 INFO - Install JDBC driver12:00:29.223 INFO - Create JDBC datasource for jdbc:postgresql://localhost:5432/sonar12:00:29.758 INFO - Initializing Hibernate12:00:30.421 INFO - Load project repositories12:00:30.574 INFO - Load project repositories (done) | time=153ms12:00:30.574 INFO - Load project settings12:00:30.786 INFO - Load technical debt model12:00:30.801 INFO - Apply project exclusions12:00:30.939 WARN - 'sonar.dynamicAnalysis' is deprecated since version 4.3 and should no longer be used.12:00:30.954 WARN - SCM provider autodetection failed. No SCM provider claims to support this project. Please use sonar.scm.provider to define SCM of your project.12:00:30.955 INFO - ------------- Scan Java :: Simple Project :: SonarQube Scanner for Gradle12:00:30.959 INFO - Load module settings12:00:31.025 INFO - Load rules12:00:31.231 INFO - Base dir: /home/tvinke/workspace/sonar-examples/projects/languages/java/gradle/java-gradle-simple12:00:31.231 INFO - Working dir: /home/tvinke/workspace/sonar-examples/projects/languages/java/gradle/java-gradle-simple/build/sonar12:00:31.232 INFO - Source paths: src/main/java12:00:31.232 INFO - Test paths: src/test/java12:00:31.233 INFO - Binary dirs: build/classes/main12:00:31.233 INFO - Source encoding: UTF-8, default locale: en_US12:00:31.233 INFO - Index files12:00:31.241 INFO - 3 files indexed12:00:31.314 INFO - Quality profile for java: Sonar way12:00:31.326 INFO - Sensor JavaSquidSensor12:00:31.513 INFO - Configured Java source version: 712:00:31.746 INFO - Java Main Files AST scan...12:00:31.748 INFO - 1 source files to be analyzed12:00:31.950 INFO - Java Main Files AST scan done: 204 ms12:00:31.950 INFO - 1/1 source files have been analyzed12:00:31.951 INFO - Java bytecode scan...12:00:31.964 INFO - Java bytecode scan done: 13 ms12:00:31.964 INFO - Java Test Files AST scan...12:00:31.964 INFO - 2 source files to be analyzed12:00:32.011 INFO - Java Test Files AST scan done: 47 ms12:00:32.011 INFO - 2/2 source files have been analyzed12:00:32.013 INFO - Package design analysis...12:00:32.015 INFO - Package design analysis done: 2 ms12:00:32.016 INFO - Sensor JavaSquidSensor (done) | time=690ms12:00:32.016 INFO - Sensor Lines Sensor12:00:32.017 INFO - Sensor Lines Sensor (done) | time=1ms12:00:32.018 INFO - Sensor QProfileSensor12:00:32.021 INFO - Sensor QProfileSensor (done) | time=4ms12:00:32.021 INFO - Sensor InitialOpenIssuesSensor12:00:32.032 INFO - Sensor InitialOpenIssuesSensor (done) | time=11ms12:00:32.032 INFO - Sensor ProjectLinksSensor12:00:32.039 INFO - Sensor ProjectLinksSensor (done) | time=7ms12:00:32.039 INFO - Sensor VersionEventsSensor12:00:32.057 INFO - Sensor VersionEventsSensor (done) | time=18ms12:00:32.057 INFO - Sensor SurefireSensor12:00:32.057 INFO - parsing /home/tvinke/workspace/sonar-examples/projects/languages/java/gradle/java-gradle-simple/build/test-results12:00:32.100 INFO - Sensor SurefireSensor (done) | time=43ms12:00:32.100 INFO - Sensor JaCoCoOverallSensor12:00:32.105 WARN - You are not using the latest JaCoCo binary format version, please consider upgrading to latest JaCoCo version.12:00:32.106 INFO - Analysing /home/tvinke/workspace/sonar-examples/projects/languages/java/gradle/java-gradle-simple/build/jacoco/test.exec12:00:32.117 WARN - You are not using the latest JaCoCo binary format version, please consider upgrading to latest JaCoCo version.12:00:32.117 INFO - Analysing /home/tvinke/workspace/sonar-examples/projects/languages/java/gradle/java-gradle-simple/build/sonar/jacoco-overall.exec12:00:32.151 INFO - No information about coverage per test.12:00:32.152 INFO - Sensor JaCoCoOverallSensor (done) | time=52ms12:00:32.152 INFO - Sensor SCM Sensor12:00:32.152 INFO - No SCM system was detected. You can use the 'sonar.scm.provider' property to explicitly specify it.12:00:32.152 INFO - Sensor SCM Sensor (done) | time=0ms12:00:32.152 INFO - Sensor JaCoCoSensor12:00:32.152 WARN - You are not using the latest JaCoCo binary format version, please consider upgrading to latest JaCoCo version.12:00:32.153 INFO - Analysing /home/tvinke/workspace/sonar-examples/projects/languages/java/gradle/java-gradle-simple/build/jacoco/test.exec12:00:32.155 INFO - No information about coverage per test.12:00:32.155 INFO - Sensor JaCoCoSensor (done) | time=3ms12:00:32.155 INFO - Sensor CPD Sensor12:00:32.155 INFO - JavaCpdEngine is used for java12:00:32.155 INFO - Cross-project analysis disabled12:00:32.169 INFO - Sensor CPD Sensor (done) | time=14ms12:00:32.170 INFO - No quality gate is configured.12:00:32.195 INFO - Compare to previous analysis (2016-02-26)12:00:32.197 INFO - Compare over 30 days (2016-01-27, analysis of Fri Feb 26 09:54:19 CET 2016)12:00:32.501 INFO - Execute decorators...12:00:33.012 INFO - Store results in database12:00:33.177 INFO - Analysis reports generated in 13ms, dir size=1002 bytes12:00:33.181 INFO - Analysis reports compressed in 4ms, zip size=2 KB12:00:33.211 INFO - Analysis reports sent to server in 29ms12:00:33.211 INFO - ANALYSIS SUCCESSFUL, you can browse http://localhost:9000/dashboard/index/org.sonarqube:java-gradle-simple12:00:33.211 INFO - Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report.BUILD SUCCESSFULTotal time: 5.274 secs |
Результат:
АНАЛИЗ УСПЕШНЫЙ
На панели инструментов SonarQube приведен список нашего простого Java-проекта. Обзор проекта теперь показывает много информации о состоянии текущей кодовой базы.
У собственного примера проекта SonarQube есть 2 (преднамеренные) проблемы:
Обзор проблем говорит о том, что на самом деле происходит:
Так что ответьте на мой первоначальный вопрос: не так сложно проанализировать проект Gradle с помощью локальной установки SonarQube.
Поскольку у меня уже были установлены Docker и Docker Compose, нам понадобилось «5 минут», чтобы добраться сюда, но вам потребуется еще 10 минут, чтобы погасить технический долг.
Теперь, чего вы ждете — иди исправим! 🙂
Дальнейшее чтение
- Сайт SonarQube — http://www.sonarqube.org/
- Оранжевый сигнал / сонар на DockerHub и GitHub
- Sonarqube.org вики
- Настройка и обновление> Установка и настройка плагина Gradle Sonar
- Анализ исходного кода> Анализ с помощью Gradle
- Документы Gradle.org — https://plugins.gradle.org/plugin/org.sonarqube
- Домашняя страница JaCoCo Java Code Coverage — http://eclemma.org/jacoco/
| Ссылка: | 3 шага для анализа Gradle-проекта с помощью SonarQube с помощью Docker от нашего партнера по JCG Теда Винке в блоге |









