Share This Post

程式碼審查工具

在原始碼逐漸堆疊的情況下,加上需求不斷的增加,要同時維護好程式碼品質是一個需要耗費時間的流程,雖然市面上有許多程式碼檢查工具,不過有些價錢都滿高的,這時候就需要一個開源的程式碼檢查工具。

SonarQube 是一款基於 Java 開發的原始碼檢測與品質管理系統,因著 Java 的關係,Server 與 Client 都是跨平台的。雖然 SonarQube 也有需要付費的版本,不過今天是使用 comminity 的社群版本。

支援的語言

Sonarqube 好處

  • Web 操作介面
  • 支援多種語言 Java、C#、JavaScript、PHP、Python 等
  • 檢測安全漏洞
  • 分析可靠性、重複性、技術債務、測試覆蓋率
  • 追蹤問題
  • 團隊協作和權限管理

下載並執行

選擇 comminity 版本下載並解壓縮後,打開啟動執行檔就可以運行了。

# on linux
bin/linux-x86-64/sonar.sh start 
# on macOS
bin/macosx-universal-64/sonar.sh start
# on Windows
bin\\windows-x86-64\\StartSonar.bat

使用 Docker 來運行

SonarQube 官方也有提供 image 供快速建置。

  • 拉取 image
docker pull sonarqube
  • 執行 sonarqube
  1. Linux
docker run -d --name sonarqube \
        -p 9000:9000 \
	-v /path/to/conf:/opt/sonarqube/conf \
	-v /path/to/data:/opt/sonarqube/data \
	-v /path/to/extensions:/opt/sonarqube/extensions \
	sonarqube

2. Windows

docker volume create sonar

docker run -d –name sonarqube -p 9000:9000
-v sonar:/opt/sonarqube/conf -v sonar:/opt/sonarqube/data
-v sonar:/opt/sonarqube/extensions `
sonarqube

打開 SonarQube server

sonarqube 預設會架設在 9000 port,帳號密碼預設為 admin/admin,登入進去後會要求改密碼。

SonarQube Rules

SonarScanner 在執行掃描時,主要針對的規則分為四個部分

  • Code Smell (Maintainability domain)
  • Bug (Reliability domain)
  • Vulnerability (Security domain)
  • Security Hotspot (Security domain)

Code Smell 和 Bug,基本上是不用懷疑,一定要修正的。

Vulnerability 如果超過 80% ,就會顯示異常。

Security Hotspot 按照官方文件說明是 80% 的人看過問題會修正它。

SonarQube Quality Gates

以通過 Quality Gates 為目標,沒有設定的話會使用預設值。

選擇專案

執行掃描程式 SonarScanner

sonar-scanner \\
  -Dsonar.projectKey=gohiking-web \\
  -Dsonar.sources=. \\
  -Dsonar.host.url=http://localhost:9000 \\
  -Dsonar.login=sqp_50e50b1e781befa90007654515c40ed8d06b3689
  • 使用 docker 執行
    1. Windows
docker run `
    --rm `
    -e SONAR_HOST_URL="<http://host.docker.internal:9000>" `
    -e SONAR_LOGIN="sqp_50e50b1e781befa90007654515c40ed8d06b3689" `
    -v "$(pwd):/usr/src" `
    sonarsource/sonar-scanner-cli

host.docker.internal → docker 訪問 localhost 的方式 $(pwd) → 需要在專案資料夾執行

而 projectKey 則是透過