简介
Sonar-iOS主要用于扫描iOS代码规范和单元测试覆盖率,包括两部分:服务器部分
和插件部分
,如果不需要安装sonarqube服务器的话,直接看Sonar-iOS-插件安装及Xcode配置扫描即可。
SonarQube服务器安装包括三部分:
- 数据库的安装和配置
- JDK安装
- SonarQube服务器的安装和配置
一、数据库的安装和配置
数据库版本建议安装mysql@5.7
版本
1、安装和卸载指定版本的mysql
brew install mysql@5.7
brew uninstall mysql
brew uninstall mysql@5.7
2、mysql启动和查看命令
//启动mysql服务
brew services start mysql@5.7
//重启服务
brew services restart mysql@5.7
//启动mysql服务
mysql.server start
//查看mysql版本
mysql -V
//查看本地mysql列表
brew list mysql
3、进入mysql
mysql -uroot -p
4、数据库操作
需要先执行第3步中的命令,进入mysql,才能做如下命令操作。
//显示数据库
show databases;
//创建sonarqube数据库表
create database sonarqube;
//退出数据库
exit;
二、Mac系统JDK的安装和配置
安装最新版JDK
brew cask install adoptopenjdk
安装某个特定版本的jdk:
brew tap AdoptOpenJDK/openjdk
brew cask install adoptopenjdk8
brew cask install adoptopenjdk9
查看已安装jdk版本及安装目录
//打开终端,输入如下命令
//注意:输入命令参数区分大小写(必须是-V)
/usr/libexec/java_home -V
如下图:3个红框内依次为:
输入命令;
当前Mac已安装jdk目录;
Mac默认使用的jdk版本;
三、SonarQube服务器的安装和配置
- 文档地址: https://docs.sonarqube.org/latest/setup/install-server/
- 下载SonarQube服务器的安装包(不同版本下载不同的安装包, 本次以Community Edition版本为例)https://www.sonarqube.org/downloads/
- 解压安装包到要安装的目录下
- 配置环境变量
- MacOS的环境变量,可以设置在~/.bash_profile 或~/.profile 文件里
- Oh-my-zsh 的配置文件在 ~/.zshrc
export SONARQUBE_HOME=/Users/king/Workspaces/Services/sonarqube-dev-7.4
export PATH=$SONARQUBE_HOME/bin:$PATH
- 设置访问的数据库信息,修改
$SONARQUBE-HOME/conf/sonar.properties
以MySQL数据库为例:如下图:
# 将MySQL部分打开,配置JDBC相关参数,需要在MySQL中创建sonarqube数据库
sonar.jdbc.username=sonarqube_db_user
sonar.jdbc.password=sonarqube_db_password
sonar.sorceEncoding=UTF-8
sonar.login=admin
sonar.password=admin
sonar.jdbc.url=jdbc:mysql://127.0.0.1:3306/sonarqube?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false
- 配置服务器地址和端口号。默认端口号是9000
sonar.web.host=127.0.0.1
sonar.web.port=9000
- 运行SonarQube服务器,进入
SONARQUBE_HOME
目录下,运行./bin/macosx-universal-64/sonar.sh start
, 如下图:
到这里,如果没有安装过JDK, 那么会报错如下,需要先安装JDK
- 日志都在logs文件夹下。有需要查看直接运行
tail -100f
日志文件 - 浏览器中输入 http://127.0.0.1:9000 访问SonarQube服务器。默认用户名密码是
admin/admin
- 安装插件
- 服务器安装,administration->Marketplace,搜索插件安装即可,收费软件基本都是要求服务器最少是Developer Edition版本。
- 手动安装,下载插件的.jar文件,然后复制到
$SONARQUBE_HOME/extensions/plugins
下,重启服务器即可。
如下图所示:替换backelite-sonar-swift-plugin-0.4.3.jar
文件
sonar服务器常用命令
sonar服务器操作
//启动sonar服务器
sonar.sh start
//停止sonar服务器
sonar.sh stop
tail -100f logs/web.log
四、终端实践:
===>如果之前没有安装过MySQL 5.7,直接安装
brew install mysql@5.7 // 安装
brew link --force mysql@5.7 // 链接
brew services start mysql@5.7 // 启动服务
echo 'export PATH="/usr/local/opt/mysql@5.7/bin:$PATH"' >> ~/.zshrc // 输出到环境变量
===>如果之前安装了 MySQL 5.7,先卸载,再安装
brew uninstall mysql@5.7
rm -rf /usr/local/var/mysql
rm /usr/local/etc/my.cnf
--- 👇和第一种情况一样
接着执行上面的正常安装步骤步骤
===>查看数据库
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.05 sec)
===>查看当前进程
➜ /usr/local/opt git:(master) ✗ >ps aux | grep mysql
admin 19844 0.1 0.5 4884696 78900 ?? S 二01下午 1:26.30 /usr/local/opt/mysql/bin/mysqld --basedir=/usr/local/opt/mysql --datadir=/usr/local/var/mysql --plugin-dir=/usr/local/opt/mysql/lib/plugin --log-error=localhost.err --pid-file=localhost.pid
admin 19751 0.0 0.0 4288056 960 ?? S 二01下午 0:00.04 /bin/sh /usr/local/opt/mysql/bin/mysqld_safe --datadir=/usr/local/var/mysql
admin 17303 0.0 0.0 4268020 604 s000 R+ 3:02下午 0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn mysql
➜ /Users/admin/sonar/sonarqube-7.4 >ps au| grep mysql
admin 23986 0.0 0.0 4304852 2528 s001 S+ 3:38下午 0:00.04 mysql -uroot -p
admin 24300 0.0 0.0 4268020 780 s000 S+ 3:45下午 0:00.01 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn mysql
===>杀掉指定进程
➜ /usr/local/opt git:(master) ✗ >>kill -9 /usr/local/opt/mysql@5.7/bin/mysql.server
➜ /usr/local/opt git:(master) ✗ >>kill -9 19844
➜ /usr/local/opt git:(master) ✗ >>kill -9 19751
===>查看当前目录详细信息:
➜ /usr/local git:(master) ✗ >ls -al
total 8
drwxr-xr-x 21 root wheel 672 6 26 18:47 .
drwxr-xr-x@ 9 root wheel 288 2 5 12:37 ..
-rw-r--r-- 1 root wheel 0 2 13 17:14 .com.apple.installer.keep
drwxr-xr-x 14 admin admin 448 6 27 14:23 .git
-rw-r--r--@ 1 admin wheel 504 12 21 2015 .gitignore
drwxr-xr-x 10 admin wheel 320 6 26 18:47 2019年06月26日-备份2015
drwxrwxr-x 2 admin admin 64 5 12 16:14 Caskroom
drwxr-xr-x 36 admin admin 1152 6 27 09:53 Cellar
drwxrwxr-x 3 admin admin 96 6 17 17:16 Frameworks
drwxrwxr-x 20 admin admin 640 6 27 11:14 Homebrew
drwxr-xr-x 11 admin admin 352 2 13 17:44 Library
drwxrwxr-x 181 admin admin 5792 6 27 11:05 bin
drwxr-xr-x 8 admin admin 256 6 26 14:56 etc
drwxr-xr-x 26 admin admin 832 6 26 10:34 include
drwxr-xr-x 77 admin admin 2464 6 26 10:34 lib
drwxrwxrwx 8 _gamecontrollerd _gamecontrollerd 256 2 13 17:44 openfire
drwxr-xr-x 47 admin admin 1504 6 27 09:53 opt
drwxr-xr-x 3 root wheel 96 2 13 17:43 remotedesktop
drwxrwxr-x 2 admin admin 64 5 12 16:14 sbin
drwxrwxrwx 20 root admin 640 6 26 10:34 share
drwxrwxr-x 5 admin admin 160 6 26 10:30 var
===>查看当前用的哪个数据库:
➜ /usr/local git:(master) ✗ >which mysql
/usr/local/opt/mysql@5.7/bin/mysql
五、sonar服务器创建新工程
1、菜单Projects->点击右侧+号
2、创建新工程【create new project】
3、输入工程名字,自动生成token
自动生成之后如下图
4、点击【continue】
选择对应语言、系统、唯一工程key【工程名即可】
5、点击【Done】会在右侧生成代码
拷贝上图的代码(如下所示),到sonar的配置文件(sonar-project.properties)中的对应位置
sonar-scanner \
-Dsonar.projectKey=com.test.sjgroup:MALauncher-iOS \
-Dsonar.sources=. \
-Dsonar.host.url=http://127.0.0.1:9000 \
-Dsonar.login=00cfabd89d96254d7726dcbcdd5989fdf4eb11cd
sonar-scanner \
-Dsonar.projectKey=com.test.sjgroup:MAAppKit-iOS \
-Dsonar.sources=. \
-Dsonar.host.url=http://127.0.0.1:9000 \
-Dsonar.login=1b3022a23c209aa5cb2083cd65af0380ae98a2f3
sonar-scanner \
-Dsonar.projectKey=com.test.sjgroup:MASecurity-iOS \
-Dsonar.sources=. \
-Dsonar.host.url=http://127.0.0.1:9000 \
-Dsonar.login=765235227bf7f0983a6e6008e30f800b000013c2
遇到的问题
一、command+U报如下错误
单元测试的时候报如下错误:
分析原因
单元测试的覆盖率生成,必须从动态库中获取
解决办法:
修改mach-O Type为动态库
二、framework单元测试报错
找不到framework中的类
project 'MALauncher.xcodeproj'
platform :ios, '8.0'
target 'MALauncher' do
use_frameworks!
target 'MALauncherTests' do
#此target必须注释掉如下代码,否则很多配置不会继承
#inherit! :search_paths
end
end
三、单元测试target配置
问题:
将示例工程的单元测试测试target修改为framework的单元测试target时,总是会编译示例工程的target。
解决办法:
1、Tests单元测试target->General->Testing: 去掉示例工程,选择None
2、Tests单元测试target->build phases->target dependencies: 删掉示例工程
改好之后效果,framework的Target的edit scheme的效果如下:
四、sonar-scaner扫描报错
在sonar-scaner扫描上传的时候,会遇到问题导致不能上传扫描结果。 com.mysql.jdbc.PacketTooBigException: Packet for query is too large (5192684 > 4194304). You can change this value on the server by setting the max_allowed_packet' variable. 详细信息如下。(该错误日志在logs/web.log文件中)
解决方法:
- 找到MySQL的配置文件
my.cnf
, 可能存在的目录/usr/local/etc/my.cnf
、/etc/my.cnf
、~/my.cnf
, 打开该文件修改max_allowed_packet
配置,
默认是4M,修改成10M即可。 (10 * 1024 * 1024)
max_allowed_packet = 10485760
- 重启MySQL服务
五、Caused by: java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)
web.log文件中详细的错误信息如下:
2020.05.07 15:40:21 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: java.sql.SQLException: Cannot create PoolableConnectionFactory (Access denied for user 'root'@'localhost' (using password: YES))
at org.apache.commons.dbcp2.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:2385)
at org.apache.commons.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:2110)
at org.apache.commons.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1563)
at org.sonar.db.profiling.NullConnectionInterceptor.getConnection(NullConnectionInterceptor.java:31)
at org.sonar.db.profiling.ProfiledDataSource.getConnection(ProfiledDataSource.java:317)
at org.sonar.db.DefaultDatabase.checkConnection(DefaultDatabase.java:106)
... 30 common frames omitted
Caused by: java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:965)
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.dbcp2.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:53)
at org.apache.commons.dbcp2.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:291)
at org.apache.commons.dbcp2.BasicDataSource.validateConnectionFactory(BasicDataSource.java:2395)
at org.apache.commons.dbcp2.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:2381)
... 35 common frames omitted
- 描述:
数据库启动正常,sonar服务启动正常后,浏览器打开http://127.0.0.1:9000/about
报错 - 原因:
sonar服务器的配置文件中链接数据库的密码和数据库的真实密码不匹配导致 - 解决办法:
找到sonar服务器的配置文件sonarqube-7.4/conf/sonar.properties
,修改配置文件中的sonar.jdbc.password
密码为数据库的正确的密码即可。我的数据库密码没有设置,所以这里修改成空密码即可。
sonar.jdbc.username=root
sonar.jdbc.password=
sonar.sorceEncoding=UTF-8
sonar.login=admin
sonar.password=admin
#----- Embedded Database (default)
# H2 embedded database server listening port, defaults to 9092
#sonar.embeddedDatabase.port=9092
#----- DEPRECATED
#----- MySQL >=5.6 && <8.0
# Support of MySQL is dropped in Data Center Editions and deprecated in all other editions
# Only InnoDB storage engine is supported (not myISAM).
# Only the bundled driver is supported. It can not be changed.
sonar.jdbc.url=jdbc:mysql://127.0.0.1:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false
此错误在其他场景下的解决方案:参考如下:
https://www.cnblogs.com/xuanbjut/p/10406980.html
六、not authorized . Please check the properties sonar.login and sonar.password
描述:
sonar-scanner
扫描上传到sonar服务器时,报错如标题所示。原因:
电脑中没有在sonar管理端创建对应的项目解决方法:
在sonar管理端创建对应的项目即可