sonar代码审查

article/2025/9/15 18:39:28

sonar代码审查

  • sonarqube简介
    • 七个方面检测代码质量
    • sonarqube结构组件
    • 集成方式
  • sonar部署
    • 部署须知
    • sonar搭建步骤
      • 1.查看本地环境
      • 2.查看java环境
      • 3.安装mysql
      • 4.安装及配置sonar
      • 5.启动sonar
        • 启动
        • 启动遇到的问题
  • sonar代码扫描
    • 一、使用sonar-scanner进行本地扫描
    • 二、使用Android studio的sonar插件进行本地扫描
    • 三、sonar,sonar-scanner集成gitlab
    • 四.sonar集成jenkins

sonarqube简介

sonarqube是一个用的比较多的代码审查工具,支持20+ 种编程语言,经过sonarqube代码审查后把出现在代码里的问题都暴露出来并进行分类,开发人员根据严重程度解决排期,将问题数量降低,这样就可以创建并维护一个干净的代码基础。即使是遗留项目,保持新代码的整洁,也能最终获得一个值得骄傲的代码基础。

七个方面检测代码质量

  • 检查代码是否符合编程标准:命名规范、编写规范等(check-style)
  • 潜在bug
  • 重复代码
  • 单元测试覆盖率
  • 注释量
  • 结构耦合
  • 代码复杂度分布

sonarqube结构组件

1.server(三个子进程:web server, search server, compute engineserver):服务端,用于接收客户端扫描报告
2.database
3.plugins
4.scanners:客户端扫描工具

集成方式

1.Sonar Scanners本地扫描代码检查质量
2.Android Studio插件分析,配置sonar server
3.GitLab Runner+Sonar
4.Jenkins插件
分析后将结果推送到SonarQube平台数据库中,可以通过访问SonarQube网页,查看分析结果

sonar部署

部署须知

1.只能有1个sonarqube server、1个sonarqube database
2.考虑性能优化,每一个组件(server,database,scanners)尽量在不同机器上,所有机器时间需要同步
3.server与database要在同一网段,scanners与server可不在同一网段,scanners与database不通信
4.sonar要有Java环境,需要知道sonar与java对应版本,从sonar7.9开始只支持java11+(这一点很重要!!!!我就在这里踩坑了)
5.sonar内置数据库为H2,不需要单独配置,如果需要更换数据库需要在配置文件中单独配置,sonar7.9最新版本不支持mysql,数据库支持MySQL/Oracle/PostgreSQL

sonar搭建步骤

1.查看本地环境

$ uname -a
Linux dan-HP-Z4-G4-Workstation 4.15.0-60-generic #67~16.04.1-Ubuntu SMP Mon Aug 26 08:57:33 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

2.查看java环境

$ java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-8u222-b10-1ubuntu1~16.04.1-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)

这里我的java环境是java8,最新的sonar只支持java11+,所以没有下载最新的sonar版本,而是下载了sonar7.3版本,大家根据自己的环境选择对应的最新稳定版本即可

3.安装mysql

注意sonar支持的mysql版本 >=5.6 && <8.0,大家不要安装过低或者过高版本

$ sudo apt-get install mysql-server(root密码设置可以跳过,就为空密码)
$ sudo apt-get install mysql-client
$ sudo apt-get install libmysqlclient-dev

安装成功后可以通过下面的命令测试是否安装成功:sudo netstat -tap | grep mysql

创建sonar数据库和用户:

$ mysql -uroot -p
mysql>CREATE DATABASE sonar;  
mysql>show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sonar              |
| sys                |
+--------------------+
5 rows in set (0.00 sec)
mysql> CREATE USER 'sonar'@'%' IDENTIFIED BY '123456'; 
mysql> GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY '123456';
mysql> flush privileges;  

4.安装及配置sonar

sonar官方下载地址
下载完成后解压、配置sonar数据库信息

$ unzip sonarqube-7.3.zip
$ cd sonarqube-7.3/
$ vim conf/sonar.properties 
sonar.jdbc.username=sonar
sonar.jdbc.password=123456
sonar.jdbc.url=jdbc:mysql://127.0.0.1:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false
#sonar.jdbc.driverClassName:com.mysql.jdbc.Driver
sonar.web.host=0.0.0.0
sonar.web.context=/sonar   (访问url地址,这里根据实际设置,默认是访问根目录)
sonar.web.port=8083    (访问端口默认是9000,可更改)

5.启动sonar

启动

$ cd sonarqube-7.3/bin/
$ ls
jsw-license  linux-x86-32  linux-x86-64  macosx-universal-64  windows-x86-32  windows-x86-64
$ cd linux-x86-64  (根据自己实际环境来选择)
$ ./sonar.sh start
Starting SonarQube...
Started SonarQube.

如果启动失败进入sonarqube-7.3/logs查看日志文件定位失败原因

启动遇到的问题

2019.10.23 09:29:22 INFO  web[][o.sonar.db.Database] Create JDBC data source for jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false
2019.10.23 09:29:22 ERROR web[][o.s.s.p.Platform] Web server startup failed
java.lang.IllegalStateException: Can not connect to database. Please check connectivity and settings (see the properties prefixed by 'sonar.jdbc.').at org.sonar.db.DefaultDatabase.checkConnection(DefaultDatabase.java:108)at org.sonar.db.DefaultDatabase.start(DefaultDatabase.java:75)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.picocontainer.lifecycle.ReflectionLifecycleStrategy.invokeMethod(ReflectionLifecycleStrategy.java:110)at org.picocontainer.lifecycle.ReflectionLifecycleStrategy.start(ReflectionLifecycleStrategy.java:89)at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.start(AbstractInjectionFactory.java:84)at org.picocontainer.behaviors.AbstractBehavior.start(AbstractBehavior.java:169)at org.picocontainer.behaviors.Stored$RealComponentLifecycle.start(Stored.java:132)at org.picocontainer.behaviors.Stored.start(Stored.java:110)at org.picocontainer.DefaultPicoContainer.potentiallyStartAdapter(DefaultPicoContainer.java:1016)at org.picocontainer.DefaultPicoContainer.startAdapters(DefaultPicoContainer.java:1009)at org.picocontainer.DefaultPicoContainer.start(DefaultPicoContainer.java:767)at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:135)at org.sonar.server.platform.platformlevel.PlatformLevel.start(PlatformLevel.java:90)at org.sonar.server.platform.platformlevel.PlatformLevel1.start(PlatformLevel1.java:156)at org.sonar.server.platform.Platform.start(Platform.java:211)at org.sonar.server.platform.Platform.startLevel1Container(Platform.java:170)at org.sonar.server.platform.Platform.init(Platform.java:86)at org.sonar.server.platform.web.PlatformServletContextListener.contextInitialized(PlatformServletContextListener.java:45)at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4745)at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5207)at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1419)at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)at java.util.concurrent.FutureTask.run(FutureTask.java:266)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Access denied for user 'sonar'@'%' to database 'sonar')at org.apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1549)at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1388)at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)at org.sonar.db.profiling.NullConnectionInterceptor.getConnection(NullConnectionInterceptor.java:31)at org.sonar.db.profiling.ProfiledDataSource.getConnection(ProfiledDataSource.java:322)at org.sonar.db.DefaultDatabase.checkConnection(DefaultDatabase.java:106)... 30 common frames omitted
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Access denied for user 'sonar'@'%' to database 'sonar'at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)at java.lang.reflect.Constructor.newInstance(Constructor.java:423)at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)at com.mysql.jdbc.Util.getInstance(Util.java:408)at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:944)at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3976)at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3912)at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:871)at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1714)at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1224)at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2190)at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2221)at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2016)at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:776)at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)at java.lang.reflect.Constructor.newInstance(Constructor.java:423)at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:386)at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:330)at org.apache.commons.dbcp.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:38)at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:582)at org.apache.commons.dbcp.BasicDataSource.validateConnectionFactory(BasicDataSource.java:1556)at org.apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1545)... 35 common frames omitted

原因定位:Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Access denied for user ‘sonar’@’%’ to database ‘sonar’)
解决方案:sonar用户访问sonar数据库权限受阻,GRANT ALL ON sonar.* TO ‘sonar’@’%’ IDENTIFIED BY ‘123456’;

6.访问sonar网页
根据步骤4中的配置,访问URL为:http://ip:8083/sonar
1)点击右上角"Log in"进行登录,登录账号和密码:admin&admin
2)登陆成功后自动弹出生成Token的弹框,Token是分析时使用用于验证身份的,可以设置也可以跳过后面用到的时候再设置
3)设置好Token后选择主要语言和build方式
4)汉化
Administration—marketplace—搜索chinese pack安装—安装完成后弹出restart or Revert,选择restart
restart成功后需要重新登陆
在这里插入图片描述
汉化后:
在这里插入图片描述
5)安装一些需要的插件:
Checkstyle——检查违反统一代码编写风格的代码
FindBugs——检查违反规则的缺陷代码
PMD——检查违反规则的代码
6)sonarqube新建用户
配置—权限—用户
创建成功后,点击Token创建令牌
点击组,可以修改组权限
7)sonarqube配置checkstyle代码规则
参考:https://www.jianshu.com/p/ff1d800885ce

sonar代码扫描

一、使用sonar-scanner进行本地扫描

1.下载sonar-scanner:官网下载地址&安装教程
2.下载后解压、配置

$ unzip sonar-scanner-cli-4.2.0.1873-linux.zip
$ cd sonar-scanner-4.2.0.1873-linux/
$ vim conf/sonar-scanner.properties
#----- Default SonarQube server
sonar.host.url=http://ip:8083/sonar  (前面sonar搭建中的网页URL)
#----- Default source code encoding
sonar.sourceEncoding=UTF-8
#----- Database MySQL
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false
sonar.jdbc.username=sonar        (前面sonar搭建中的mysql数据库用户)
sonar.jdbc.password=123456        (前面sonar搭建中的mysql数据库用户密码)
sonar.login=admin            (前面sonar搭建中的网页登录名)
sonar.password=admin    (前面sonar搭建中的网页登录密码)

3.添加环境变量

$ sudo vim /etc/profile
export SONAR_HOME=/home/dan/8Tdisk/sonarqube-7.3
export SONAR_RUNNER_HOME=/home/dan/8Tdisk/sonar-scanner-4.2.0.1873-linux
export PATH=$PATH:$JAVA_HOME/bin:$SONAR_RUNNER_HOME/bin
$ source /etc/profile

4.进入要扫描的项目根目录下,添加sonar-project.properties配置文件

$ vim sonar-project.properties
sonar.projectKey=test
sonar.projectName=test
sonar.projectVersion=1.3.1
sonar.sources=app/src   #要扫描的源码文件,如果有多个用逗号隔开
sonar.java.binaries=build  #不需要扫描的目录
sonar.language=java
sonar.sourceEncoding=UTF-8

5.开始扫描

$ sonar-scanner
(第4步也可以不做,扫描时执行
$ sonar-scanner -Dsonar.projectKey=test -Dsonar.sources=app/src -Dsonar.java.binaries=build -Dsonar.language=java -Dsonar.sourceEncoding=UTF-8 -Dsonar.host.url=http://localhost:8083/sonar -Dsonar.login=admin -Dsonar.password=admin)
19:30:51.439 DEBUG: Post-jobs :
19:30:51.441 INFO: Task total time: 8.025 s
19:30:51.482 INFO: ------------------------------------------------------------------------
19:30:51.482 INFO: EXECUTION SUCCESS
19:30:51.482 INFO: ------------------------------------------------------------------------
19:30:51.482 INFO: Total time: 9.306s
19:30:51.514 INFO: Final Memory: 14M/68M
19:30:51.514 INFO: ------------------------------------------------------------------------

扫描结束,查看sonar server网页查看结果

二、使用Android studio的sonar插件进行本地扫描

1.安装插件:settings-Plugins–Browse输入sonar,选择sonarlint进行安装
2.在Other Settings–SonarLint General Settings中勾选“Automatically trigger analysis”并配置Sonar server信息(Name, URL,token),配置好后“Updata binding”
3.在Other Settings–SonarLint Project Settings–勾选“Bind project to SonarQube/SonarCloud”,选择Project
如果在第2步AS中遇到The following plugins do not meet the required minimum versions, please upgrade them in SonarQube: kotlin (installed: 1.0.1.965, minimum: 1.2.1.2009)提示
需要在Sonarqube中更新kotlin的版本

三、sonar,sonar-scanner集成gitlab

使得每次在gitlab上提交代码时都使用gitlab-ci运行器后台使用sonar-scanner进行检查
1.sonarqube中安装gitlab插件
配置-应用市场-搜索gitlab安装并重启
也可以直接下载sonar-gitlab-plugin-4.0.0插件,放到sonar安装目录extensions/plugins下面,然后重启server

2.gitlab中设置用户Access Token
User–Setting–Access Token:Name设置为sonar_token,Expires at不设置,Scopes全选上,点击
此gitlab用户需要加到项目成员或者项目所属组城中中,这样才有权限comment和添加注释行
创建token成功后,一定要将token记住
在这里插入图片描述

3.sonar配置Token令牌
配置–配置–通用设置–Gitlab–设置Gitlab url、Gitlab User Token: Gitlab url是gitlab的服务器地址,Gitlab User Token是前面步骤2记下来的Gitlab User Token
在这里插入图片描述
4.安装gitlab-runner
gitlab runner用于运行作业并将结果返回给gitlab。他通常与gitlab ci联合使用。gitlab runner官网安装教程地址:https://docs.gitlab.com/runner/install/
建议不要和 GitLab 服务端安装在同一台服务器
1)下载gitlab runner二进制文件

  • Linux x86-64
$ sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
  • Linux x86
$ sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-386
  • Linux arm
$ sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-arm

如果后续要更新gitlab-runner二进制文件,步骤如下:

$ sudo gitlab-runner stop
$ sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64
$ sudo chmod +x /usr/local/bin/gitlab-runner
$ sudo gitlab-runner start

2)gitlab-runner执行权限

$ sudo chmod +x /usr/local/bin/gitlab-runner

3)创建一个gitlab-runner用户并设置密码,之后用这个用户进行CI/CD

$ sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash 
$ sudo useradd  -d  /export/dan/gitlab-runner --comment 'GitLab Runner' -m -s /bin/bash gitlab-runner 
$ sudo passwd gitlab-runner 

4)安装并启动gitlab runner service

$ sudo gitlab-runner install --user=gitlab-runner --working-directory=/export/dan/gitlab-runner
$ sudo gitlab-runner start
$ sudo gitlab-runner status查看状态是running
sudo: unable to resolve host MOOS-BUILD
Runtime platform                                    arch=amd64 os=linux pid=24405 revision=1564076b version=12.4.0
gitlab-runner: Service is running!

这里遇到一个问题:start之后也不报错,但是查看status为Service is not running!
查看了一下系统日志,发现是runner install时指定的working dir不存在,建立该路径再restart就好了
如果发现状态不对可以查看一下日志定位原因:sudo tail /var/log/syslog

5)注册gitlab-runner
注册——将gitlab runner和gitlab项目绑定起来,在注册时需要用到gitlab URL、registration token
先在gitlab网页上查看 该项目–Settings–CI/CD–Runners Expand看到注册runner所需要的URL和token
在这里插入图片描述
然后注册:

$ sudo gitlab-runner register
Runtime platform                                    arch=amd64 os=linux pid=24732 revision=1564076b version=12.4.0
Running in system-mode.
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
**输入gitlab访问URL**
Please enter the gitlab-ci token for this runner:
**输入注册token**
Please enter the gitlab-ci description for this runner:
**输入runner描述信息**
Please enter the gitlab-ci tags for this runner (comma separated):
**输入runner的tags,用于中后CI/CD操作时表示使用哪个runner来进行流水线job,tags非常关键**
Registering runner... succeeded                     runner=********
Please enter the executor: docker, docker-ssh, parallels, ssh, virtualbox, custom, shell, docker+machine, docker-ssh+machine, kubernetes:
**输入运行方式**
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

注册成功后可以去gitlab网页上看一下这个runner是否已经存在了,若存在并查看此runner并记下Token(点击下图中红色笔迹圈出编辑按钮进行查看)
在这里插入图片描述
6)查看runner注册信息
runner信息一般放在一个.toml配置文件中,存放位置在/etc/gitlab-runner/config.toml
在config.toml中可以指定使用具体哪种shell(bash,windows powershell,windows batch)
7)运行注册好的runner

$ sudo gitlab-runner run-single -u http://gitlabip/ -t token --executor shell

要让一个Runner运行起来,–url、–token(这里的token不是注册时使用的token,而是注册成功后此runner特有的runner token)和–executor选项是必要的。其他选项可根据具体情况和需求进行设置。(sudo gitlab-runner run-single --help查看命令选项)
这样来看命令中的选项和/etc/gitlab-runner/config.toml中的配置项是一致的,为什么还需要再设置一下??难道不会默认读配置中的选项吗??
8)同时运行多个runners

$ sudo gitlab-runner run --help
Runtime platform arch=amd64 os=linux pid=25343 revision=1564076b version=12.4.0
NAME:
gitlab-runner run - run multi runner service
USAGE:
gitlab-runner run [command options] [arguments…]
OPTIONS:
-c value, --config value Config file (default: “/etc/gitlab-runner/config.toml”) [$CONFIG_FILE]
–listen-address value Metrics / pprof server listening address [$LISTEN_ADDRESS]
-n value, --service value Use different names for different services (default: “gitlab-runner”)
-d value, --working-directory value Specify custom working directory
-u value, --user value Use specific user to execute shell scripts
–syslog Log to system service logger [$LOG_SYSLOG]

  • –config:指定配置文件,配置文件中存放着runner运行时所需要的信息,且一个配置文件中可以存放多个runners的信息
  • –listen-address:指定HTTP服务器应该监听的地址ip:port
  • -n:指定service别名,指定多个配置文件时作用大
  • -d:指定批量运行service的工作目录
  • -u:指定用户用什么权限来运行runner,最好不要以root权限(太高)
  • –syslog:把日志记录到系统日志

9)查看所有的runners列表

$ sudo gitlab-runner list

10)检查注册runner是否有效链接gitlab

$ sudo gitlab-runner verify
Runtime platform                                    arch=amd64 os=linux pid=27928 revision=1564076b version=12.4.0
Running in system-mode.Verifying runner... is alive                        runner=*******

使用shell executor,项目会被拉到目录:/builds
项目的caches在:/cache//
——runner当前执行的目录或者使用–working-directory指定的目录,默认在/home/gitlab-runner下面
——runner的token前8位
——一个唯一的number,用于区别job,从0开始 $CI_JOB_ID
——项目拥有者的名称,即该项目组名
——项目名

11)注销gitlab-runner

$ sudo gitlab-runner unregister --name 
$ sudo gitlab-runner unregister --url http://gitlabip/ --token t0k3n

12)使用.gitlab-ci.yml配置项目
将此文件放在项目根目录下:
auto_test:
stage: test
script:
- cd /home/dan/gitlab-runner
- chmod +x auto_test.sh
- ./auto_test.sh
except:
- master
tags:
- sonartest-tag

sonar_analyze:
stage: test
script:
- sonar-scanner -Dsonar.projectKey=sonartest -Dsonar.sources=. -Dsonar.java.binaries=. -Dsonar.sourceEncoding=UTF-8 -Dsonar.host.url=http://localhost:8083/sonar -Dsonar.login=admin -Dsonar.password=admin
only:
- master
tags:
- sonartest-tag

这里的tags就是runner注册时填的tag,如果这里没有跟runner对应起来,是跑不通的

四.sonar集成jenkins

1)在jenkins中安装sonar插件
系统管理–插件管理–可选插件中搜索sonar scanner并安装重启
2)系统管理–系统设置–全局属性中勾选Tool Locations-新增sonar


http://chatgpt.dhexx.cn/article/fFlKRKDL.shtml

相关文章

代码审查

代码审查&#xff1a; 一种有效帮助提升代码质量的有效途径。 代码审查3W(what why when)常见的代码审查工具代码审查流程 1.代码审查3W(what why when)&#xff1a; 代码审查&#xff1a;对计算机源代码系统化的审查&#xff0c;常用软件同行评审的方式进行&#xff0c;目…

java 代码审查_代码审查(Code Review)清单

代码审查可以帮助提高代码质量,避免由于代码习惯而造成的 bug。下面列出的这些要点因该可以作为大部分代码审查的指导,如果是 Java 应用的话,这些建议应该被视作最佳实践。 文档 1. Javadoc 应该在每一个类和方法中添加。 2. 如果是修复某个 bug,应该添加 bug ID。 3. 走捷…

静态代码审查

本篇介绍静态代码审查的意义以及如何在Android studio中集成它们。需要注意的是&#xff0c;这些工具不是万能的&#xff0c;虽然它们能高效且全面地执行代码检查工作&#xff0c;但它们并不具备人类的“逻辑思维”优势。也就是说&#xff0c;静态代码审查工具是无法确保程序逻…

代码审查的必要性和最佳实践

目录 代码审查的流程 代码审查的争议 加班要累死了&#xff0c;完成项目都来不及&#xff0c;还做什么代码审查&#xff1f; 代码审查太费时间&#xff0c;改来改去无非是一些格式、注释、命名之类不痛不痒的问题。 团队的习惯和流程就是不做代码审查&#xff0c;大家都是…

如何审查网页元素

如何审查网页元素 对于一个优秀的爬虫工程师而言&#xff0c;要善于发现网页元素的规律&#xff0c;并且能从中提炼出有效的信息。因此&#xff0c;在动手编写爬虫程序前&#xff0c;必须要对网页元素进行审查。本节将讲解如何使用“浏览器”审查网页元素。 浏览器都自带检查…

代码审查(文档整理)

常用的代码审查工具 git/SUBVERSIONGerritUpsource显示代码变更√√√使用源码仓库√√在线代码讨论√√异步审查支持√√使用协议GPLv2/Apache License 2.0Apache License 2.0付费license 代码审查 范根检查法 轻量级的审查流程 结对编程同步代码审查异步代码审查 代码审查需…

代码审查“查”什么?

让我们来谈谈代码审查&#xff08;Code Review&#xff09;。如果花几秒钟去搜索有关内容&#xff0c;你会发现许多论述代码审查好处的文章&#xff08;例如&#xff0c;Jeff Atwood的这篇文章&#xff09;。你还会发现许多介绍如何使用代码审查工具的文档&#xff0c;比如我们…

uniapp的uview2.0框架u--textarea组件无法换行,换行无效问题解决方案

问题描述 在使用uniapp的uview2.0框架u–textarea组件时&#xff0c;想要使u–textarea支持换行输入&#xff0c;但是默认不支持换行输入&#xff0c;各种百度&#xff0c;没有找到解决问题的方案&#xff0c;最后只有查看源码如下 但发现源码没有对属性有过多的处理&#xff…

微信小程序textarea问题总结

微信小程序textarea问题总结 1.textarea多行输入框。该组件是原生组件 2.参考文档中的原生组件说明https://developers.weixin.qq.com/miniprogram/dev/component/native-component.html 原生组件的层级是最高的&#xff0c;所以页面中的其他组件无论设置 z-index 为多少&am…

JavaFX设置TextArea文本内容

本篇主要内容为设置TextArea的内容&#xff0c;涉及的知识面包括如何添加视图和控制层的关联&#xff0c;调用TextArea的方法设置文本内容&#xff0c;不仅实用于TextArea&#xff0c;还可以设置其它如Button&#xff0c;Label&#xff0c;TextField等组件的文本域或者其它属性…

原生div实现textarea

文章导航 为什么要用div实现textarea关键词实现效果源码示例 为什么要用div实现textarea div 实现 textarea 可以实现高度自适应 关键词 contenteditable: true|false 可以将元素内容区域调整为可编辑 实现效果 源码示例 &#x1f383; index.html <!DOCTYPE html>…

html textarea设置只读属性吗,HTML

HTML中的只读属性用于指定textarea元素为只读。如果文本区域为只读&#xff0c;则其内容无法更改&#xff0c;但可以复制并突出显示。这是一个布尔属性。 用法: Contents... 范例1&#xff1a;本示例使用只读属性在仅可读的输入textarea上写入内容。 HTML Textarea readonly A…

让textarea 只读

网上找到几种方案 都试了下 editable"false" readonly"readonly" disabled"disabled" 不知道是不是语法我写错了 但这么写效果是 &#xff08;顺寻代码和图片一致&#xff09; 第二个和第三个都是不能点 不能修改 第一个可以点可以修改

html页面只读,textarea只读 readonly =true;

Java TextArea 只读问题 TextArea ta new TextArea("",10,15,TextArea.SCROLLBARS_VEICAL_ON报啥错啊。 textarea怎么设置为只读 readonly true; C#语言&#xff1a;Listview控件中加了一个textarea&#xff0c;怎么在前台页面将textarea转化服务器控件&#xff0c;…

如何让textarea不可编辑只可读(博客常用)

如何让textarea不可编辑只可读&#xff08;博客常用&#xff09;。 Textarea的相关属性解释&#xff1a; rows&#xff1a;行高&#xff0c;就是你这个文本框能显示多少行文字 cols&#xff1a;宽度&#xff0c;代表你这个文本框有多宽 readonly&#xff1a;有个值readonly&am…

[评价体系] 1、数据规范化/无量纲化方法

目录 1 数据格式 2 不同属性类型的指标规范化方法 2.1 效益型指标&#xff1a;即该指标越大越好 2.2 成本型指标&#xff1a;即该指标越小越好 2.3 固定型/中间型指标&#xff1a;在某个固定值处最好 2.4 区间型指标&#xff1a;有最佳区间 2.5 偏离区间型&#xff1a;偏…

机器学习学习笔记(3)——量纲与无量纲,标准化、归一化、正则化

量纲、无量纲&#xff0c;标准化、归一化、正则化是我百度了很多次都不进脑子的知识&#xff0c;所以我决定还是放在博客上面。 不过鉴于我查阅了很多资料&#xff0c;说是有许多的坑&#xff0c;所以我也不清楚我的理解和解释是否是坑&#xff0c;具体的就留给各位来帮忙评判了…

数据的无量纲化处理和标准化处理的区别是什么

数据的无量纲化处理和标准化处理的区别是什么 请教:两者除了方法上有所不同外,在其他方面还有什么区别? 解答: 标准化处理方法是无量纲化处理的一种方法。除此之外,还有相对化处理方法(包括初值比处理)、函数化(功效系数)方法,等等。由于标准化处理方法可以与分布…

数据归归一化方法(标准化)

数据归一化方法 数据标准化&#xff08;normalization&#xff09;数据标准化处理主要包括数据同趋化处理和无量纲化处理两个方面。 数据同趋化处理主要解决不同性质数据问题&#xff0c;对不同性质指标直接加总不能正确反映不同作用力的综合结果&#xff0c;须先考虑改变逆指标…