根本原因是本地缺失 sonar-scanner 二进制文件且未加入 $path;需手动下载解压并配置 path,同时 go 扫描还需确保 go 在 path 中、go.mod 位置正确、coverage.out 路径匹配 sonar.sources。

sonar-scanner 命令找不到或报错 command not found
根本原因不是 SonarQube 服务没起,而是本地缺扫描器二进制文件,且没加到 $PATH。官方不提供包管理安装,必须手动下载解压并配置路径。
- 去 SonarQube 官网下载页 下对应系统的
sonar-scanner(比如sonar-scanner-cli-4.8.0.2856-linux.zip) - 解压后把
bin/sonar-scanner所在目录加入$PATH,例如:export PATH="/opt/sonar-scanner/bin:$PATH" - 验证:运行
sonar-scanner -h能打印帮助即成功;若提示cannot execute binary file: Exec format Error,说明平台不匹配(比如在 macos 下用了 Linux 版)
Go 项目扫描时 missing Go executable 错误
SonarQube 的 Go 插件(sonar-go-plugin)依赖本地 go 命令做 AST 解析和覆盖率收集。它不认 GOPATH 或 GOROOT,只认系统 $PATH 中的 go。
- 运行
which go确认路径,再检查sonar-scanner是否能访问同一环境(CI 中常因 shell 类型不同导致$PATH隔离) - CI 场景下(如 github Actions),别用
setup-go后直接跑sonar-scanner—— 它可能在子 shell 中,go不在父进程$PATH里;显式用run: export PATH="$(go env GOPATH)/bin:$PATH" && sonar-scanner ... - 如果项目用 Go modules,确保
go.mod在扫描根目录;否则插件可能跳过所有文件,日志里只显示0 files indexed
sonar-project.properties 中关键 Go 相关配置项
Go 项目不像 Java 有标准构建产物路径,必须靠配置告诉扫描器源码在哪、怎么识别测试、是否启用覆盖率。
-
sonar.sources=.—— 必须设为当前目录或含go.mod的目录,不能写成src/或留空 -
sonar.exclusions=**/*_test.go,**/testdata/**—— 显式排除测试文件,否则覆盖率统计会失真(_test.go被当普通源码计) -
sonar.go.tests.reportPaths=coverage.out—— 这个文件需由go test -coverprofile=coverage.out ./...生成;注意路径是相对于sonar-scanner执行目录的,不是go.mod目录 -
sonar.go.coverage.reportPaths已废弃,新版插件只认sonar.go.tests.reportPaths;写错会导致覆盖率始终为 0
覆盖率数据不显示或为 0%
Go 的覆盖率扫描最常卡在这一步:文件路径映射失败。SonarQube 要求覆盖率报告里的文件路径和 sonar.sources 下的路径完全一致(包括大小写和相对位置)。
立即学习“go语言免费学习笔记(深入)”;
- 生成
coverage.out时,必须在go.mod所在目录执行:go test -coverprofile=coverage.out -covermode=count ./...;若在子目录运行,路径会带前缀(如./internal/pkg/xxx.go),而sonar.sources=.期望的是internal/pkg/xxx.go - 用
go tool cover -func=coverage.out检查输出中的路径是否“干净”;若看到./开头,就用sed -i 's|^./||' coverage.out修正(Linux/macOS) - 扫描时加参数
-Dsonar.verbose=true,看日志里是否有Could not resolve x.go from coverage report—— 这说明路径对不上,不是代码问题
Go 的覆盖率路径映射是硬伤,改一次 go test 执行位置,就得同步调 sonar-project.properties 和 coverage.out 生成逻辑,漏掉任意一环都会静默失败。