Flutter и SonarQube для статического анализа кода

Если вы читаете эту статью, то наверняка занимаетесь разработкой приложений на Flutter и в ознакомительной информации о нем не нуждаетесь. 

Теперь о SonarQube. Это один из тех инструментов, о которых должен знать каждый разработчик. SonarQube стоит на страже высокого качества кода

И наконец, Docker. Это платформа с поддержкой контейнеризации на базе открытого ПО. Подумать только, в распоряжении разработчика намного более легковесная виртуальная машина с предварительными настройками всего необходимого, и лишь одно касание отделяет его от развертывания. 

По этим темам опубликовано множество статей и видео на YouTube, поэтому обойдемся здесь без подробностей и сразу перейдем к поставленной задаче. 

1. Скачивание и установка Docker

Заходим на сайт https://docs.docker.com/engine/install/ и устанавливаем версию Docker для настольного компьютера в соответствии с ОС. 

Предоставление поддержки для Apple Silicon заслуживает особой благодарности. 

После скачивания и первоначального запуска переходим на https://hub.docker.com для создания аккаунта. На данный момент вполне подходит бесплатная учетная запись. 

В ответ на вопросы о том, что такое Docker Id, поясняю  —  это имя пользователя. 

2. Скачивание образа SonarQube и создание контейнера

Допустим, вы решили начать с запуска бесплатной версии сообщества Community из терминала: 

docker pull sonarqube:9.3-community

В результате можно получить ошибку: 

no matching manifest for linux/arm64/v8 in the manifest list entries
(в списке манифестов отсутствует подходящий манифест для linux/arm64/v8)

На момент написания статьи официальная поддержка Apple Silicon не предоставляется. При желании можно попробовать версию SonarQube 9+, но я бы этого не делал из-за ее очень медленной работы. Если какая-то задача загружается 30 секунд на Apple Silicon, по крайней мере, в первый год, то игра не стоит свеч. 

Следующая команда принудительно скачает образ Docker для нашей архитектуры. Однако работать он будет по принципу эмуляции, т.е. невыносимо медленно, о чем я уже говорил.  

docker pull sonarqube:9.3-community --platform linux/amd64

3. Долой пункт 2, или новая попытка! 

Вымарываем пункт 2 и находим неофициальный образ Docker, который сработает для чипа Silicon (отметим, что это не какой-то случайный образ, а тот, который используют многие разработчики): 

docker pull mwizner/sonarqube:8.9.5-community

На следующем этапе мы создаем контейнер/приложение, но прежде проверяем только что скаченный образ: 

docker images
REPOSITORY TAG IMAGE ID mwizner/sonarqube 8.9.5-community f5e2e7d2d122

Присваиваем контейнеру имя sonarqubeapp и задействуем ID образа из предыдущей справки: 

docker create --name sonarqubeapp -p 9000:9000 f5e2e7d2d122

Запускаем контейнер:

docker start sonarqubeapp

После 15–20 секундной загрузки переходим на http://localhost:9000 и оказываемся на работающем сайте. Для запуска в качестве имени пользователя и пароля можно воспользоваться admin/admin.

4. Скачивание плагина для анализа Dart и Flutter

На момент написания статьи Dart и Flutter из SonarQube официально не поддерживаются. Но ведь у нас есть GitHub и сообщество, дай им Бог здоровья! 

Переходим по ссылке https://github.com/insideapp-oss/sonar-flutter, где нас ждет плагин/расширение, уже готовый к скачиванию. 

Заходим на Releases и выбираем самую последнюю версию, а именно sonar-flutter-plugin-0.4.0.jar

5. Копирование плагина .jar в контейнер 

Заходим в каталог Downloads или в место скачивания плагина и выполняем команду:

docker cp sonar-flutter-plugin-0.4.0.jar sonarqubeapp:/opt/sonarqube/extensions/plugins

С помощью docker cp делаем копию файла, поскольку файловая система контейнера не видна нам снаружи. Напрашивается аналогия с с Sandbox на iOS. 

sonarqubeapp —  имя контейнера, а после : указан путь к каталогу с плагинами внутри контейнера. 

Перезапускаем контейнер для обновления плагинов: 

docker restart sonarqubeapp

Если мы все сделали правильно, то на портале увидим нечто подобное:

6. Скачивание SonarScanner

Сканер позволяет загружать локальные результаты на портал для отображения данных. 

Он запускается из образа Docker с доступом к исходному репозиторию, но мы сосредоточимся на локальной установке. 

Переходим на https://docs.sonarqube.org/latest/analysis/scan/sonarscanner/, скачиваем архив и распаковываем в домашний каталог. 

Обязательно добавьте путь к .bash_profile или .zshrc, или любой другой конфигурации оболочки системы для повсеместной видимости команды. Теперь перезапускаем терминал:  

export PATH="$HOME/sonar-scanner-4.7.0.2747-macosx/bin:$PATH"

7. Создание конфигурационного файла 

На предпоследнем этапе понадобится конфигурационный файл в корневом каталоге проекта Flutter, который осуществляет обмен информацией между исходным кодом и порталом SonarQube.

# Идентификация проекта, жестко прописанный код или применение переменных среды 
sonar.projectKey=my-project-key
sonar.projectName=My Project
sonar.login=my-long-token

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

# Расположение исходного кода
# Путь указан относительно файла sonar-project.properties file. По умолчанию to .
# Использование запятых для указания более одного каталога.
sonar.sources=lib
sonar.tests=test

# Кодирование исходного кода. По умолчанию работает предустановленная система кодирования.
sonar.sourceEncoding=UTF-8

# исключение сгенерированных файлов
sonar.exclusions=test/**/*_test.mocks.dart,lib/**/*.g.dart

Строки 2–4: вы получаете их после создания нового проекта на портале. 

8. На старт-внимание-поехали!

В завершении собираем все вместе, переходим в корневую папку проекта Flutter и выполняем: 

flutter pub get # на всякий случай 
flutter test --machine --coverage > tests.output
sonar-scanner

Происходит загрузка результатов теста и информации о базе кода на портал для анализа. Если все прошло гладко, мы увидим следующий итог: 

Дополнительная информация 

Помните пункт 3? Мы взяли исходный образ и настроили его под конкретный случай. 

При необходимости сохранить образ со всеми настройками для применения на другом Mac или в целях распространения можно опубликовать контейнер/приложение как приватный или публичный репозиторий. 

# Сначала заходим в аккаунт Docker Hub и создаем новый репозиторий (приватный или публичный) 
docker commit sonarqubeapp
docker images # get the newly created empty image id
docker tag [Empty Image Id] [Docker Id]/[Repository Name]:[Version]
docker push [Docker Id]/[Image Name]:[Version]

Пример:

docker commit sonarqubeapp
docker images
docker tag b0dcc123456 myaccount/project-image:1.0
docker push myaccount/project-image:1.0

В следующий раз, когда мы уже все настроим, можно пропустить шаги со 2 по 5. 

Выводы 

SonarQube —  превосходный инструмент, ускоряющий командную работу и повышающий показатели качества кода, благодаря анализу статических данных, таких как запахи кода, его покрытие, дублирование строк, цикломатическая сложность и т.д. 

Он предполагает интеграцию с разработкой CI/CD, открывая мир новых возможностей: оформление пул-реквестов, определение лимитов качества (например, отсутствие в отправляемых коммитах кода с запашком или тестовое покрытие более 75% и т.д.)

И это только малая часть большого потенциала.

Читайте также:

Читайте нас в TelegramVK и Яндекс.Дзен


Перевод статьи Catalin Patrascu: Flutter and SonarQube for Static Code Analysis

Предыдущая статьяReSvelte — инструмент разработчика Svelte и визуализатор дерева компонентов (расширение VS Code)
Следующая статьяЭлементы архитектуры веб-приложений