美文网首页
使用SonarQube 8.1静态检查OC代码质量

使用SonarQube 8.1静态检查OC代码质量

作者: ZephyrCo | 来源:发表于2020-01-14 11:47 被阅读0次

    前言

    SonarQube是一个开源的代码质量管理系统,它支持包括ObjectiveC、Java、C/C++、C#、PHP在内的超过25种编程语言。它能够提供包括重复代码、编码标准、单元测试、代码覆盖率、代码复杂度、潜在Bug、注释的报告。它还可以与持续集成工具配合使用实现完全自动化的分析。

    之前在网上搜索学习SonarQube在Mac上的集成和使用教程,发现教程都比较老,使用的都是较老版本的SonarQube,在集成最新的8.1版本时踩了不少坑。本文就是对在Mac系统上安装和使用新版SonarQube的总结。后续会继续更新使用SonarQube静态分析Swift代码及结合Jenkins进行自动化分析。

    注意:SonarQube需要Java 11及以上的运行环境,在终端输入java --version即可查看系统的Java版本,如果不满足,请先自行下载和安装。

    SonarQube平台架构

    SonarQube平台主要由四大要件构成:

    • 数据库:存放配置数据和检测数据(7.9及以后的版本不再支持MySQL,本文使用的是PostgreSQL)
    • Web服务:在本地网页上查看配置数据和代码质量检测结果
    • 分析器:对项目代码进行分析(OCLint)
    • 插件:支持各种语言的插件

    安装配置PostgreSQL数据库

    SonarQube运行和储存数据需要数据库,而网上大多数教程使用的MySQL数据库已经不被7.9以后版本的SonarQube支持了,所以我选择了同样开源的关系数据库PostgreSQL。这个数据库和MySQL语法略有不同,但使用上基本大同小异。

    我们先来安装和配置PostgreSQL数据库。

    安装数据库

    安装PostgreSQL数据库有两种方式,一种是Homebrew,一种是直接上官网下载安装程序安装,后一种有可视化界面使用上比较简单。

    使用Homebrew安装

    安装Homebrew(电脑上已经安装了的可以跳过这步)。

    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
    

    安装数据库

    brew install postgresql 
    

    安装完成后,进行初始化

    initdb /usr/local/var/postgres
    

    启动服务

    pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start
    

    设置开机启动

    ln -sfv /usr/local/opt/postgresql/*.plist ~/Library/LaunchAgents
    launchctl load ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
    

    软件方式安装

    进入官网按照提示进行下载和安装,安装完之后直接双击运行即可。

    使用软件方式安装会自动创建两个用户,一个是postgres,一个是与电脑当前登录用户同名的用户,并且分别为两个用户创建了默认的数据库。后面我们添加用户和数据库时可以登录postgres这个用户进行创建。(注:PostgreSQL数据库可以使用pgAdmin在本地网页图形化界面上进行管理,具体安装和使用请自行搜索)

    软件方式安装需要配置一下环境路径,这样我们就可以在命令行直接使用psql命令。

    在 ~/.bash_profile中添加以下内容(具体路径可以查看从图形界面进入psql命令行时显示的路径)

    export PATH=$PATH:/Applications/Postgres.app/Contents/Versions/12/bin
    

    保存之后退出,在终端输入source ~/.bash_profile使设置生效。然后就可以直接在终端中键入psql --version,显示如下则表示设置成功。

    psql (PostgreSQL) 12.2
    

    默认情况下本地用户登录都是受信任的,不需要输入密码,如果想要使用密码登录,可以修改/Users/本地用户名/Library/Application Support/Postgres/var-12/pg_hba.conf文件,将以下内容中的trust改为md5

    # TYPE  DATABASE        USER            ADDRESS                 METHOD
    
    # "local" is for Unix domain socket connections only
    local   all             all                                     trust
    # IPv4 local connections:
    host    all             all             127.0.0.1/32            trust
    # IPv6 local connections:
    host    all             all             ::1/128                 trust
    # Allow replication connections from localhost, by a user with the
    # replication privilege.
    local   replication     all                                     trust
    host    replication     all             127.0.0.1/32            trust
    host    replication     all             ::1/128                 trust
    

    修改后

    # TYPE  DATABASE        USER            ADDRESS                 METHOD
    
    # "local" is for Unix domain socket connections only
    local   all             all                                     md5
    # IPv4 local connections:
    host    all             all             127.0.0.1/32            md5
    # IPv6 local connections:
    host    all             all             ::1/128                 md5
    # Allow replication connections from localhost, by a user with the
    # replication privilege.
    local   replication     all                                     md5
    host    replication     all             127.0.0.1/32            md5
    host    replication     all             ::1/128                 md5
    

    重启PostgreSQL之后使用psql -U 用户名登录就需要输入密码了。

    注:PostgreSQL常用指令如下:

    psql -U [user] -d [database] -h [host] -p [post] //登录
    \password:设置当前登录用户的密码
    \h:查看SQL命令的解释,比如\h select。
    \?:查看psql命令列表。
    \l:列出所有数据库。
    \c [database_name]:连接其他数据库。
    \d:列出当前数据库的所有表格。
    \d [table_name]:列出某一张表格的结构。
    \du:列出所有用户。
    \e:打开文本编辑器。
    \conninfo:列出当前数据库和连接的信息。
    \password [user]: 修改用户密码
    \q:退出
    

    配置数据库

    首先使用postgres用户登录数据库

    psql postgres
    

    然后创建用户sonar并设置密码,这里的密码你可以填写自己的密码

     CREATE USER sonar WITH PASSWORD 'sonar';
    

    创建属于用户sonar的数据库sonar

    CREATE DATABASE sonar OWNER sonar;
    

    sonar用户加上添加数据库的权限

    ALTER ROLE sonar CREATEDB;
    

    这样,数据库配置就完成了,接下来正式安装SonarQube

    安装和配置SonarQube

    安装SonarQube主要分为三步:

    • 安装配置SonarQube本地服务器
    • 安装配置sonar-scanner
    • 安装配置xcprettyOCLintslather等工具和插件

    安装配置本地服务器

    SonarQube的服务可以运行在本地服务器或者远程服务器上,本文主要讲解本地服务器的配置方式。

    首先上SonarQube官网上下载SonarQube源文件并解压。

    然后配置conf/sonar.properties文件

    设置数据库url

    sonar.jdbc.url=jdbc:postgresql://localhost/sonar
    

    设置数据库账号密码

    sonar.jdbc.username=sonar
    sonar.jdbc.password=sonar
    

    进入bin/macosx-universal-64文件夹,给sonar.sh设置权限

    chmod 777 sonar.sh
    

    使用./sonar.sh console来启动服务器,在浏览器输入http://localhost:9000来测试服务器是否启动成功。页面正常显示就表示启动成功。

    sonarqube_start_page.png

    如果启动失败,可以根据SonarQube项目目录的logs文件夹中的日志查找原因。大部分启动不成功的情况都是数据库原因,这个在web.log文件中有记录。

    注:SonarQube常用命令如下:

    ./sonar.sh console #Debug信息
    ./sonar.sh start #启动服务
    ./sonar.sh stop #停止服务
    ./sonar.sh restart #重启服务
    

    安装和配置sonar-scanner

    直接使用HomeBrew安装sonar-scanner

    brew install sonar-scanner
    

    安装完成后输入sonar-scanner -v或者sonar-scanner --version可以看到如下配置文件地址和版本信息

    INFO: Scanner configuration file: /usr/local/Cellar/sonar-scanner/4.2.0.1873/libexec/conf/sonar-scanner.properties
    INFO: Project root configuration file: NONE
    INFO: SonarQube Scanner 4.2.0.1873
    INFO: Java 11.0.5 Oracle Corporation (64-bit)
    INFO: Mac OS X 10.15.2 x86_64
    

    根据上面显示的配置文件地址打开配置文件,即/usr/local/Cellar/sonar-runner/2.5/libexec/conf/sonar-runner.properties,修改或添加以下内容

    sonar.host.url=http://localhost:9000
    sonar.jdbc.username=sonar
    sonar.jdbc.password=sonar
    sonar.jdbc.url=jdbc:postgresql://localhost/sonar
    

    修改完后保存,sonar-scanner这部分就完成了。

    安装其他工具和插件

    首先安装环境工具。

    安装xcpretty

    git clone https://github.com/Backelite/xcpretty.git
    cd xcpretty
    git checkout fix/duration_of_failed_tests_workaround 
    gem build xcpretty.gemspec 
    sudo gem install --both xcpretty-0.2.2.gem
    

    安装oclint

    brew tap oclint/formulae
    brew install oclint
    

    或者

    brew cask install oclint
    

    如果使用Homebrew安装失败,可以直接下载安装包oclint-0.13.1-x86_64-darwin-17.4.0.tar.gz安装,下载后目录结构如下:

    oclint.png

    然后把oclint路径加入到环境变量,我是把oclint文件夹放在用户根目录/Users/用户名/oclint-0.13.1。使用命令vi ~/.bash_profile进入编辑页面,在末尾加上

    export PATH="/Users/用户名/oclint-0.13.1/bin:$PATH"
    

    然后使用:wq保存退出即可

    安装slather

    gem install slather
    

    安装lizard

    sudo pip install lizard
    

    安装OC代码静态分析插件

    由于官方插件SonarCFamily比较贵,使用开源的就好。

    这里下载相应版本的jar文件即可(也可以下载源文件自行编译,这个比较费时间,不推荐)。将下载好的jar文件放到SonarQube安装目录下的extensions/plugins文件夹中,插件安装就完成了。

    使用SonarQube静态扫描代码

    终端路径切换到待扫描项目的根目录下,输入touch run-sonar.sh命令生成run-sonar.sh,然后输入vi run-sonar.sh编辑文件,在里面添加以下内容(注意把里面的xxx更改为你的项目名称的Scheme名称):

    xcodebuild -workspace xxx.xcworkspace -scheme xxx clean build | tee xcodebuild.log | xcpretty --report json-compilation-database
    
    mv build/reports/compilation_db.json compile_commands.json
    
    oclint-json-compilation-database -exclude Pods -- -report-type pmd -o oclint.xml -max-priority-1 99999 -max-priority-2 99999 -max-priority-3 99999 -rc LONG_LINE=140 -rc LONG_METHOD=80 -rc NCSS_METHOD=50 -rc SHORT_VARIABLE_NAME=1 -rc CYCLOMATIC_COMPLEXITY=13 -rc MINIMUM_CASES_IN_SWITCH=2 -rc NPATH_COMPLEXITY=1500
    
    rm -rf sonar-reports
        
    mkdir sonar-reports
    
    cat oclint.xml  | sed "s#Switch Statements Should Have Default Rule#switch statements should have default#g" | sed "s#missing hash method#must override hash with isEqual#g" | sed "s#prefer early exits and continue#use early exits and continue#g" | sed "s#use boxed expression#replace with boxed expression#g" | sed "s#use container literal#replace with container literal#g" | sed "s#use number literal#replace with number literal#g" | sed "s#use object subscripting#replace with object subscripting#g" | sed "s#missing default in switch statements#switch statements should have default#g" | sed "s#unnecessary default statement in covered switch statement#switch statements don't need default when fully covered#g" | sed "s#covered switch statements dont need default#switch statements don't need default when fully covered#g" > sonar-reports/oclint.xml
        
    /bin/sh sonar-scanner -X
    

    以同样的方式新建sonar-project.properties文件,使用vi命令添加以下内容(同样注意替换项目的相关内容):

    ##########################
    # Required configuration #
    ##########################
    
    sonar.projectKey=你的项目Key
    sonar.projectName=项目名
    sonar.projectVersion=版本号
    sonar.language=objc
     
    # Project description
    sonar.projectDescription=Text sonarquebe
     
    # Path to source directories 
    sonar.sources=项目源码文件夹名称
    # Path to test directories (comment if no test)
    # sonar.tests=testSrcDir
    
     
    # Xcode project configuration (.xcodeproj or .xcworkspace)
    # -> If you have a project: configure only sonar.objectivec.project
    # -> If you have a workspace: configure sonar.objectivec.workspace and sonar.objectivec.project
    # and use the later to specify which project(s) to include in the analysis (comma separated list)
    sonar.objectivec.project=项目名.xcodeproj 
    # sonar.objectivec.workspace=myApplication.xcworkspace
    
    # Scheme to build your application
    sonar.objectivec.appScheme=需要编译的Scheme名
    # Scheme to build and run your tests (comment following line of you don't have any tests)
    # sonar.objectivec.testScheme=myApplicationTests
     
    ##########################
    # Optional configuration #
    ##########################
    
    # Encoding of the source code
    sonar.sourceEncoding=UTF-8
    
    # JUnit report generated by run-sonar.sh is stored in sonar-reports/TEST-report.xml
    # Change it only if you generate the file on your own
    # The XML files have to be prefixed by TEST- otherwise they are not processed 
    # sonar.junit.reportsPath=sonar-reports/
    
    # Cobertura report generated by run-sonar.sh is stored in sonar-reports/coverage.xml
    # Change it only if you generate the file on your own
    sonar.objectivec.coverage.reportPattern=sonar-reports/coverage*.xml
    
    # OCLint report generated by run-sonar.sh is stored in sonar-reports/oclint.xml
    # Change it only if you generate the file on your own
    sonar.objectivec.oclint.report=oclint.xml
    sonar.objectivec.oclint.reportPath=sonar-reports/oclint.xml
    
    # Paths to exclude from coverage report (tests, 3rd party libraries etc.)
    # sonar.objectivec.excludedPathsFromCoverage=pattern1,pattern2
    sonar.objectivec.excludedPathsFromCoverage=.*Tests.*
    
    # Project SCM settings
    # sonar.scm.enabled=true
    # sonar.scm.url=scm:git:https://...
    
    

    输入wq命令保存并退出。

    为避免编译的时候出现oclint: error: one compiler command contains multiple jobs:的报错,需要使用XCode打开工程文件并且在Build Settings中将COMPILER_INDEX_STORE_ENABLE设置为NO

    进入到SonarQube项目文件夹,进入到bin/macosx-universal-64,使用命令./sonar.sh restart来重启服务器。

    如果重启服务器失败,可以先看看PostgreSQL有没有正常启动,如果没有,按照前面PostgreSQL配置步骤启动。

    上面的步骤全部完成后,就可以在工程目录下使用./run-sonar.shsh run-sonar.sh命令来执行脚本。

    命令执行行完毕并且没有报错,就可以在浏览器中输入http://localhost:9000查看检测结果。

    sonarqube_snap.png

    相关文章

      网友评论

          本文标题:使用SonarQube 8.1静态检查OC代码质量

          本文链接:https://www.haomeiwen.com/subject/qgnoactx.html