SonerQubeを使ったGoプロジェクトの品質管理

# はじめに
普段goプロジェクトの静的解析はgometalinterで実施するだけなことが多いのですが,
長期的なコード品質の管理を行っていくためにgoプロジェクトでのSonarQubeの利用方法を検証したのでそのまとめです.
この記事ではローカル環境でのSonarQubeの立ち上げと,Goプロジェクトの解析を実施するまでの検証を行います.

# SonarQubeとは？
[SonarQube](https://www.sonarqube.org/)とはOSSのソースコード静的解析ツールです.
静的解析を行いコード規模, 重複率, 複雑性, 技術的負債やその割合,工数などの情報をGUIで閲覧することができます.
解析結果はDBに蓄積されるのでコード品質の推移を確認でき,また用途に合わせて独自の解析ルールを追加することも可能です.  

# SonarQubeServer
SonarQubeServerは、DBや解析機と連携し品質管理を行い、GUIを提供します.
言語解析に必要なプラグインなどのインストールもこちらから行います.

## SonarQubeServerの立ち上げ
SonarQubeServerをDockerで立ち上げる場合には公式イメージがDockerHubに上がっているのでそちらを利用できそうです.
今回は参考リンク(後述)からdocker-compose.ymlをお借りしてSonarQubeServerを立ち上げていきます.

**ディレクトリ構成**

```
.
|-- containers/
|   `-- datastore/
|       `-- Dockerfile
`-- docker-compose.yml
```

**DockerFile**  
postgres用のDockerFileを用意します.  

```DockerFile
FROM busybox:latest

MAINTAINER tomohiro.yoshie <tomohiro.yoshie@d2c.co.jp>

# sonarqube
VOLUME /opt/sonarqube/conf
VOLUME /opt/sonarqube/data
VOLUME /opt/sonarqube/extensions
VOLUME /opt/sonarqube/lib/bundled-plugins
# postgresql
VOLUME /var/lib/postgresql
VOLUME /var/lib/postgresql/data

CMD /bin/sh
```

**docker-compose.yml**
  
```docker-compose.yml
sonarqube:
    image: sonarqube
    ports:
        - '9000:9000'
    environment:
        - SONARQUBE_JDBC_USERNAME=sonar
        - SONARQUBE_JDBC_PASSWORD=sonar
        - SONARQUBE_JDBC_URL=jdbc:postgresql://sonarqube_db:5432/sonar
    links:
        - sonarqube_db
    volumes_from:
        - sonarqube_datastore

sonarqube_db:
    image: postgres
    environment:
        - POSTGRES_USER=sonar
        - POSTGRES_PASSWORD=sonar
    volumes_from:
        - sonarqube_datastore

sonarqube_datastore:
    build: containers/datastore
```

準備ができたらSonarQubeServerを立ち上げます.

```
$ docker-compose up -d
```

しばらく待つと`http://{docker-host}:9000`でアクセスできるようになるので,`admin/admin`でログインします.
![SonarQube-Login.png](https://qiita-image-store.s3.amazonaws.com/0/146016/bdba8bdf-d6f9-0b8a-3c08-5815a8ee9177.png)
初回ログイン時にはチュートリアルが表示されますが今回はSkipします.

### 参考リンク
- [DockerHub](https://hub.docker.com/_/sonarqube/)
- [Docker ComposeでSonarQubeの環境を作る](https://qiita.com/ot-aoyagi/items/d97b2431fefbf5635e93)

## Goプラグインのインストール
SonarQubeでGo言語を解析するにはGoプラグインのインストールが必要です.
ダッシュボードから Administration → Marketplaceに移動します.

![Marketplace.png](https://qiita-image-store.s3.amazonaws.com/0/146016/c53f9aef-f61a-82c7-d68d-d45e744c77b3.png)


画面中部にある検索窓から`SonarGo`プラグインを検索しインストールしておきます.
インストールを選択すると,再起動を促されますので再起動しプラグインを有効可します.

## 日本語プラグインのインストール
日本語化を行う場合は、上記手順と同様に`Japanese Pack`を検索しインストールします.
こちらもインストールを選択すると,再起動を促されますので再起動しプラグインを有効可します.

こちらのプラグインは対応バージョンが古く中途半端な翻訳となってしまいました.
完全な日本語化を行いたい場合はプラグインのリポジトリから日本語訳を追加するなど対応が必要そうです.
https://github.com/SonarQubeCommunity/sonar-l10n-ja

# SonarScanner
SonarScannerは解析器の役割を持ちます.
SonarQubeServerの準備が終わったらローカルPCにSonarScannerのインストールを行います.

## SonarScannerのインストール
SonarScannerは下記ページからダウンロードします.
https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner#AnalyzingwithSonarQubeScanner-Installation

```
wget "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-3.3.0.1492-macosx.zip"
unzip sonar-scanner-cli-3.3.0.1492-macosx.zip
mv sonar-scanner-cli-3.3.0.1492-macosx /etc
```

## SonarScanner設定
### sonar-scanner.properties設定
SonarScanner本体の設定を行います.
本体の設定は/conf/sonar-scanner.propertiesのファイルを編集します.
デフォルトではSonarQubeServerのURLが`http://localhost:9000`で記載されているので、ホストが異なる場合は修正します.

```/etc/sonar-scanner-3.3.0.1492-macosx/conf/sonar-scanner.properties
#Configure here general information about the environment, such as SonarQube server connection details for example
#No information about specific project should appear here

#----- Default SonarQube server
sonar.host.url=http://localhost:9000

#----- Default source code encoding
sonar.sourceEncoding=UTF-8
```

### sonar-project.properties設定
解析対象のプロジェクトディレクトリに`sonar-project.properties`を作成します.  
プロジェクト名や解析対象のファイルをこのファイルに指定します.
検証で利用するgoプロジェクトはdepで管理しているのでvenderディレクトリ,testファイルは除外しました.

```sonar-project.properties
sonar.projectKey=my:project
sonar.projectName=My project
sonar.projectVersion=1.0

sonar.sources=.
sonar.exclusions=**/*_test.go,**/vendor/**
sonar.tests=.
sonar.test.inclusions=**/*_test.go
sonar.test.exclusions=**/vendor/**
```

# 解析
ここまでで、SonarQubeを利用するための設定が完了しました.
プロジェクトディレクトリでsonar-runnerを実行します.  

```
$ /etc/sonar-scanner-3.3.0.1492-macosx/bin/sonar-scanner
...略...
INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
INFO: Total time: 6.928s
INFO: Final Memory: 9M/330M
INFO: ------------------------------------------------------------------------
```

解析が成功するとsonar-scanner.propertiesに記載したSonarQubeServerに結果が送信され、GUI上で解析結果を確認できるようになります.
ダッシュボードを確認すると解析結果が表示されています.

![result.png](https://qiita-image-store.s3.amazonaws.com/0/146016/cebf9027-740d-cfea-3406-26ee5eda356a.png)

各項目をクリックすると細かい解析結果を参照できます.
例えばコードスメルの指摘などはこんな感じ.
![Issues.png](https://qiita-image-store.s3.amazonaws.com/0/146016/c9b63fb5-bfef-61ba-2c19-5d7f282f3a55.png)

# 最後に
以上でSonarQubeの検証を行うことができました.
SonarQubeを導入することで、コードレビューの負担が減りロジックに集中でき,チーム開発でプロジェクトの品質を保つという意味では強力なツールと言えそうです.
今回のタイトルにはGoプロジェクトと記載しましたが,SonarQubeはプラグインによって様々な言語に対応しているので,プロジェクトの言語に関わらず広く利用できそうです.

また今回はCI連携については検証しませんでしたがこちらについても気軽に行えるようですのでいずれチェックしてみたいと思います.