前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Golang 项目集成 SonarQube 做代码质量分析

Golang 项目集成 SonarQube 做代码质量分析

作者头像
seth-shi
发布2024-08-02 11:07:31
2090
发布2024-08-02 11:07:31
举报
文章被收录于专栏:seth-shi的专栏

安装配置

安装
配置Gitlab登录
  • 文档说明: https://docs.sonarsource.com/sonarqube/10.1/instance-administration/authentication/gitlab/
    • 创建应用https://<Your Gitlab URL>/-/profile/applications(read_user权限)
    • 注意生成callback<Your SonarQube URL>/oauth2/callback/gitlab
  • 再次访问登录页出现Gitlab登录按钮代表配置成功
    • 这里注意一定要配置Server base URL否则无法跳转成功
    • 配置Gitlab导入项目
    • 创建Token https://<Your Gitlab URL>/-/profile/personal_access_tokens
    • Gitlab网址为 https://<Your Gitlab URL>/api/v4
    • 配置成功之后,在创建项目的地方就会出现Gitlab选项

    配置多分支(默认只能一个分支)

项目配置

  • SonarQube创建好项目需要准备三个配置(变量名自定义)
    • SONAR_HOST_URL=(sonar的访问网址)
    • SONAR_PROJECT_KEY=(项目标识)
    • SONAR_TOKEN=(令牌, 创建完项目最后一步会给出创建页面)
    • 把以上三个配置到Gitlab
.gitlab-ci.yml
代码语言:javascript
复制
sonarqube-check:
  stage: check
  image:
    name: sonarsource/sonar-scanner-cli:latest
    entrypoint: [""]
  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
    GIT_DEPTH: "0"
    ## 注意引入三个变量
    SONAR_HOST_URL: "${SONAR_HOST_URL}"
    SONAR_TOKEN: "${SONAR_TOKEN}"
    SONAR_PROJECT_KEY: "${SONAR_PROJECT_KEY}"
  allow_failure: false
  only:
    - main
    - dev
  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache
  coverage: '/total:\s+\(statements\)\s+\d+.\d+%/'
  script:
    - bash ./deployment/sonarqube-check.sh
    - sonar-scanner -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.token=$SONAR_TOKEN -Dsonar.projectKey=$SONAR_PROJECT_KEY -Dsonar.branch.name=$CI_COMMIT_REF_NAME
.golangci.yml
代码语言:javascript
复制
run:
  # 并发运行线程数
  concurrency: 4
  # 分析超时时间
  timeout: 5m
  # 退出状态码
  issues-exit-code: 1
  # 包含测试文件
  tests: true
  # 忽略以下默认目录
  #   vendor$, third_party$, testdata$, examples$, Godeps$, builtin$


output:
  # 输出的格式
  # colored-line-number|line-number|json|tab|checkstyle|code-climate|junit-xml|github-actions
  # 打印有问题的代码行
  print-issued-lines: true
  # 打印没通过哪个检测器
  print-linter-name: true
  # 问题唯一输出
  uniq-by-line: true
  # 按文件路径排序
  sort-results: false

linters:
  disable-all: true  # 关闭其他linter
  enable:            # 下面是开启的linter列表,之后的英文注释介绍了相应linter的功能
    # 降低代码复杂度
    - cyclop
    - gocognit
    - gocyclo
    - maintidx
    # 高可拓展性的go源码linter
    - gocritic
    # 禁止保留未使用的代码块
    #---------------------------------------
    - ineffassign
    - durationcheck
    # 所有err都要处理
    - errcheck
    # 在Go 1.13之后使用errors.Wrap可能导致的问题
    - errorlint
    # 检查switch的全面性,以免遗漏场景
    - exhaustive
    # 禁止将for-range value的指针暴露给外部
    - exportloopref
    # 禁止出现长函数
    - funlen
    # 如果有相同的string变量请使用consts替换
    - goconst
    # 禁止出现长语句
    - lll
    # 返回两个参数,一个数据,一个是err,禁止两个都是nil
    - nilnil
    # 如果知道slice大小,定义时需分配空间
    - prealloc
    # 检查prometheus meteics的指标名是否规范
    - promlinter
    # 强制要求const/import/var在一个组
    - grouper
    # 检查变量名长度
    - varnamelen
    # 强制一致性的impotr别名
    - importas
    # 类型断言时需检查是否成功
    - forcetypeassert
    # 保证类型、常量、变量和函数的声明顺序和数量
    - decorder
    # 检查err的定义规范--types类型的定义是以Error结尾的,常量的定义是Err打头的
    - errname
    # 禁止errors使用'=='和'!='等表达式--与nil和io.EOF比较除外
    - err113
    # 官方代码格式化
    - gofmt
    - goimports
    # 检查依赖的黑白名单
    - gomodguard
    # 检查类似printf的函数是否以f结尾
    - goprintffuncname
    # 官方错误检查
    - govet
    # 检查拼写错误
    - misspell
    # 如果函数过长,禁用裸返回
    - nakedret
    # 禁止深度嵌套的if语句
    - nestif
    # 禁止使用Go关键字命名
    - predeclared
    # 去掉没有必要的type转换
    - unconvert
    # 检查帮助函数里面有没有调用t.Helper()函数
    - thelper

linters-settings:
  cyclop:
    # 函数最大复杂度=(函数本身是1 + 1 * ('if', 'for', 'case', 'select', '&&', '||'))
    # 1 - 10 程序简单,风险小
    # 11 - 20 更复杂,中等风险
    # 21 - 50 复杂、高风险
    # 50 不可测试的代码,非常高的风险
    max-complexity: 30
    # 跳过测试
    skip-tests: false
  gocognit:
    # 代码复杂度
    min-complexity: 30
  gocyclo:
    # 代码复杂度
    min-complexity: 30
  dogsled:
    # val, _, _ := xx() 这种的 _ 不能超过 n 个
    max-blank-identifiers: 2
  errcheck:
    # `a := b.(MyStruct)`; 类型断言不加 err
    check-type-assertions: true
    # `num, _ := strconv.Atoi(numStr)`; 忽略错误
    check-blank: true
    # 要忽略检测的函数列表
    # see https://github.com/kisielk/errcheck#excluding-functions for details
    exclude-functions:
      - io.Copy(*bytes.Buffer)
      - io.Copy(os.Stdout)
  errorlint:
    # 打印错误只能 fmt.Errorf("oh noes: %w", err), 而不是 fmt.Errorf("oh noes: %v", err)
    errorf: true
    # 使用 ok := errors.As(err, &me), 而不是 myErr, ok := err.(*MyError)
    asserts: true
    # 使用 errors.Is(err, ErrFoo), 而不是 err == ErrFoo
    comparison: true

  exhaustive:
    # 枚举检查, 枚举在 switch 中不能写 default
    default-signifies-exhaustive: false

  funlen:
    # 函数不能超过 100 行
    lines: 100
    # 40 个语句 (statements + 空白行 < lines)
    statements: 40

  goconst:
    # 字符串常量最小长度
    min-len: 3
    # 当这个字符串超过 n 次, 就应该替换为常量
    min-occurrences: 3
    # 忽略测试
    ignore-tests: false
    # 查找有现有常量定义的字符串
    match-constant: true
    # 数字常量也要定义
    numbers: true
    # 数字的最小值
    min: 3
    # 数字的最大值
    max: 99999
    # 当行数不用坐参数时,是否忽略(不忽略, 当 if 的时候也要判断)
    ignore-calls: false

  gofmt:
    # 代码格式化
    simplify: true

  goimports:
    # 优化 import 引入
  lll:
    # 每一行最大长度
    line-length: 120
    # tab 宽度=1
    tab-width: 1

  makezero:
    # 只允许初始化长度为0的切片。非零长度的切片 append
    always: false
  nestif:
    # 深度嵌套 if, 最大只能 n
    min-complexity: 4

  nilnil:
    # 不能同时返回两个 nil
    checked-types:
      - ptr
      - func
      - iface
      - map
      - chan

  nlreturn:
    # return 之前有一个空行
    block-size: 1
  varnamelen:
    max-distance: 9
    min-name-length: 1

  #  prealloc:
  #    # 优化与分配, 不要项目刚开始的时候使用
  #    simple: true
  #    range-loops: true
  #    for-loops: false

  predeclared:
    # 声明的东西不能是预订的名字, 比如 new,int
    ignore: ""
    # include method names and field names (i.e., qualified names) in checks
    q: false

  staticcheck:
    # 静态检测
    checks: [ "all" ]

  stylecheck:
    # 代码风格检测
    # https://staticcheck.io/docs/options#checks
    checks: [ "all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022" ]
    # https://staticcheck.io/docs/options#dot_import_whitelist
    dot-import-whitelist:
      - fmt
    # https://staticcheck.io/docs/options#initialisms
    initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS" ]
    # https://staticcheck.io/docs/options#http_status_code_whitelist
    http-status-code-whitelist: [ "200", "400", "404", "500" ]

  unparam:
    # 没使用的参数
    check-exported: false

  unused:
    exported-is-used: false
    exported-fields-are-used: false
./deployment/sonarqube-check.sh
代码语言:javascript
复制
#!/bin/bash

go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct

go mod tidy

## 代码质量检查
golangci-lint run ./... --out-format checkstyle > report.xml
ret01=$?
echo -e "\033[32m  >>>>> ret01: $ret01 <<<<<  \033[0m"


## 代码覆盖率
go test ./... -coverprofile="coverage.cov" -covermode count
ret02=$?
echo -e "\033[32m  >>>>> ret02: $ret02 <<<<<  \033[0m"

## 给 gitlab 正则匹配找到覆盖率
go tool cover -func="coverage.cov"

## 代码测试
go test -json ./... > report.json
ret03=$?
echo -e "\033[32m  >>>>> ret03: $ret03 <<<<<  \033[0m"

ret=$(expr $ret01 + $ret02 + $ret03)
echo -e "\033[32m  >>>>> ret: $ret <<<<<  \033[0m"
exit "$ret"

最后结果

  • 一切准备就绪之后, 就可以在你的代码仓库显示统计数据
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-08-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 安装配置
    • 安装
      • 配置Gitlab登录
      • 项目配置
        • .gitlab-ci.yml
          • .golangci.yml
            • ./deployment/sonarqube-check.sh
            • 最后结果
            相关产品与服务
            腾讯云服务器利旧
            云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档