Mac-Sonar系统执行代码分析
Posted 小溪彼岸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mac-Sonar系统执行代码分析相关的知识,希望对你有一定的参考价值。
Mac-Sonar系统配置可以参考Mac-Sonar系统配置
一、JS/Java代码扫描配置
1、在sonar创建项目
2、在项目根目录创建sonar-project.properties
2.1 js 的项目配置
js/sonar-project.properties
# 项目key配置
sonar.projectKey=com.xx.jstest
# 项目工程名称
sonar.projectName=jstest
# 工程版本号
sonar.projectVersion=1.0
# 需要扫描的目录,也可以是制定文件'src/person2.js,src/person3.js'
sonar.sources=src
# sonar地址,sonar-scanner中配置了就行,此处配不配置都行
#sonar.host.url=http://127.0.0.1:9000
# 不设置则默认分析多种语言, 此处为js
sonar.language = js
2.2 android 的项目配置
android/sonar-project.properties
# 项目key配置
sonar.projectKey=com.xx.android
# 项目名称
sonar.projectName=android
# 工程版本号
sonar.projectVersion=1.0
# 需要扫描的目录,也可以是制定文件
sonar.sources=app/src/main/java/com/example/zw/androidlearndemo/MainActivity.java
# 二进制文件
sonar.java.binaries=app/build/intermediates
# sonar地址,sonar-scanner中配置了就行,此处配不配置都行
#sonar.host.url=http://127.0.0.1:9000
# 不设置则默认分析多种语言
sonar.language = java
3、进入项目根目录执行
sonar-scanner
二、 ios 代码扫描配置
1、iOS 代码扫描需要一些工具
1.1、OCLint 的下载和安装(Issues-代码规则)
brew tap oclint/formulae
brew install oclint
1.2、xcpretty(Tests-测试)
xctool现已被xcodebuild和xcpretty取代
安装步骤如下
git clone [https://github.com/Backelite/xcpretty.git](https://github.com/Backelite/xcpretty.git) --找一个文件夹存放xcpretty的源码
cd xcpretty
git checkout fix/duration_of_failed_tests_workaround
gem build xcpretty.gemspec
sudo gem install --both xcpretty-0.2.2.gem
1.3、slather (Code coverage-代码覆盖率)
要求安装版本高于 2.1.0 (Xcode7之前的版本使用gcovr,Xcode7以后选用 slather
)
gem install slather --如果ruby版本低于2.1.0,则需要更新ruby
1.4、lizard(Complexity-复杂性)
lizard(ci上的版本1.12.15)
sudo pip install lizard
2、 iOS 的项目配置
ios/sonar-project.properties
# 目录名称最好和项目名称保持一致 Test -> Test.xcodeproj,否则会出现检测不出来问题代码的问题
sonar.projectKey=com.xx.ios
# 决定了在sonar服务器上显示的名称
sonar.projectName=ios
sonar.projectVersion=1.0
sonar.language=objc
# Project description
sonar.projectDescription=Fake description
# Path to source directories 工程文件目录, 也可以是制定文件
sonar.sources=ios/ViewController.h,ios/ViewController.m
# Path to test directories (comment if no test) 测试文件目录
#sonar.tests=
#sonar.objectivec.simulator=platform=iOS Simulator,name=iPhone 6,OS=9.2
# 二选一
sonar.objectivec.project=ios.xcodeproj
#sonar.objectivec.workspace=xx.xcworkspace
# Scheme to build your application
sonar.objectivec.appScheme=ios
# Scheme to build and run your tests (comment following line of you don't have any tests)
sonar.objectivec.testScheme=iosTests
# 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/
#sonar.objectivec.junit.reportsPath=TEST-report.xml
# 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
#sonar.objectivec.cobertura.reportPath=sonar-reports/coverage-SuYun.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.reportPath=sonar-reports/oclint.xml
sonar.objectivec.oclint.report=build/sonar-reports/oclint.xml
# Paths to exclude from coverage report (tests, 3rd party libraries etc.)
# sonar.objectivec.excludedPathsFromCoverage=pattern1,pattern2
# 排除的路径,使用正则匹配
sonar.objectivec.excludedPathsFromCoverage=.*Tests.*,.*Specs.*
#,*.plist,*.json,.*Specs.*
# Project SCM settings
#sonar.scm.enabled=true
# sonar.scm.url=scm:git:https://...
# sonar地址,sonar-scanner中配置了就行,此处配不配置都行
#sonar.host.url=http://127.0.0.1:9000
#sonar.scm.provider=svn
3、 执行检查
run-sonar.sh
#!/bin/bash
## INSTALLATION: script to copy in your Xcode project in the same directory as the .xcodeproj file
## USAGE: ./run-sonar.sh
## DEBUG: ./run-sonar.sh -v
## WARNING: edit your project parameters in sonar-project.properties rather than modifying this script
#
trap "echo 'Script interrupted by Ctrl+C'; stopProgress; exit 1" SIGHUP SIGINT SIGTERM
function startProgress()
while true
do
echo -n "."
sleep 5
done
function stopProgress()
if [ "$vflag" = "" -a "$nflag" = "" ]; then
kill $PROGRESS_PID &>/dev/null
fi
function testIsInstalled()
hash $1 2>/dev/null
if [ $? -eq 1 ]; then
echo >&2 "ERROR - $1 is not installed or not in your PATH"; exit 1;
fi
function readParameter()
variable=$1
shift
parameter=$1
shift
eval $variable="\\"$(sed '/^\\#/d' sonar-project.properties | grep $parameter | tail -n 1 | cut -d '=' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')\\""
# Run a set of commands with logging and error handling
function runCommand()
# 1st arg: redirect stdout
# 2nd arg: command to run
# 3rd..nth arg: args
redirect=$1
shift
command=$1
shift
if [ "$nflag" = "on" ]; then
# don't execute command, just echo it
echo
if [ "$redirect" = "/dev/stdout" ]; then
if [ "$vflag" = "on" ]; then
echo "+" $command "$@"
else
echo "+" $command "$@" "> /dev/null"
fi
elif [ "$redirect" != "no" ]; then
echo "+" $command "$@" "> $redirect"
else
echo "+" $command "$@"
fi
elif [ "$vflag" = "on" ]; then
echo
if [ "$redirect" = "/dev/stdout" ]; then
set -x #echo on
$command "$@"
returnValue=$?
set +x #echo off
elif [ "$redirect" != "no" ]; then
set -x #echo on
$command "$@" > $redirect
returnValue=$?
set +x #echo off
else
set -x #echo on
$command "$@"
returnValue=$?
set +x #echo off
fi
if [[ $returnValue != 0 && $returnValue != 5 ]] ; then
stopProgress
echo "ERROR - Command '$command $@' failed with error code: $returnValue"
exit $returnValue
fi
else
echo "--------------------------------"
echo $command
echo "$@"
if [ "$redirect" = "/dev/stdout" ]; then
$command "$@" > /dev/null
elif [ "$redirect" != "no" ]; then
$command "$@" > $redirect
else
$command "$@"
fi
returnValue=$?
if [[ $returnValue != 0 && $returnValue != 5 ]] ; then
stopProgress
echo "ERROR - Command '$command $@' failed with error code: $returnValue"
exit $?
fi
echo
fi
## COMMAND LINE OPTIONS
vflag=""
nflag=""
oclint="on"
while [ $# -gt 0 ]
do
case "$1" in
-v) vflag=on;;
-n) nflag=on;;
-nooclint) oclint="";;
--) shift; break;;
-*)
echo >&2 "Usage: $0 [-v]"
exit 1;;
*) break;; # terminate while loop
esac
shift
done
# Usage OK
echo "Running run-sonar.sh..."
## CHECK PREREQUISITES
# xctool, gcovr and oclint installed
# testIsInstalled xctool
testIsInstalled xcpretty
#testIsInstalled gcovr
testIsInstalled oclint
# sonar-project.properties in current directory
if [ ! -f sonar-project.properties ]; then
echo >&2 "ERROR - No sonar-project.properties in current directory"; exit 1;
fi
## READ PARAMETERS from sonar-project.properties
# Your .xcworkspace/.xcodeproj filename
workspaceFile=''; readParameter workspaceFile 'sonar.objectivec.workspace'
projectFile=''; readParameter projectFile 'sonar.objectivec.project'
# Source directories for .h/.m files
srcDirs=''; readParameter srcDirs 'sonar.sources'
# The name of your application scheme in Xcode
appScheme=''; readParameter appScheme 'sonar.objectivec.appScheme'
# The name of your test scheme in Xcode
testScheme=''; readParameter testScheme 'sonar.objectivec.testScheme'
# The file patterns to exclude from coverage report
excludedPathsFromCoverage=''; readParameter excludedPathsFromCoverage 'sonar.objectivec.excludedPathsFromCoverage'
if [ "$vflag" = "on" ]; then
echo "Xcode workspace file is: $workspaceFile"
echo "Xcode project file is: $projectFile"
echo "Xcode application scheme is: $appScheme"
echo "Xcode test scheme is: $testScheme"
echo "Excluded paths from coverage are: $excludedPathsFromCoverage"
fi
if [[ $projectFile != "" ]]; then
#statements
# 设置XCode的签名方式为手动签名
echo "-----设置自动签名, projectFile: $projectFile \\n"
sed -i "" "s%\\ProvisioningStyle.*%\\ProvisioningStyle = Manual;%g" "$projectFile/project.pbxproj"
# 删除TeamID设置
sed -i "" "s%\\DevelopmentTeam.*%\\ %g" "$projectFile/project.pbxproj"
sed -i "" "s%\\DEVELOPMENT_TEAM.*%\\ %g" "$projectFile/project.pbxproj"
fi
if [[ "$workspaceFile" != "" ]] ; then
# 17/03/01 修改: 将证书描述文件设置改成模拟器设置
xcodebuildCmdPrefix="xcodebuild -workspace $workspaceFile -scheme $appScheme -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6' ONLY_ACTIVE_ARCH=NO -configuration Release "
else
xcodebuildCmdPrefix="xcodebuild -project $projectFile -scheme $appScheme -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6' ONLY_ACTIVE_ARCH=NO -configuration Release"
fi
# Check for mandatory parameters
if [ -z "$projectFile" -o "$projectFile" = " " ]; then
if [ ! -z "$workspaceFile" -a "$workspaceFile" != " " ]; then
echo >&2 "ERROR - sonar.objectivec.project parameter is missing in sonar-project.properties. You must specify which projects (comma-separated list) are application code within the workspace $workspaceFile."
else
echo >&2 "ERROR - sonar.objectivec.project parameter is missing in sonar-project.properties (name of your .xcodeproj)"
fi
exit 1
fi
if [ -z "$srcDirs" -o "$srcDirs" = " " ]; then
echo >&2 "ERROR - sonar.sources parameter is missing in sonar-project.properties. You must specify which directories contain your .h/.m source files (comma-separated list)."
exit 1
fi
if [ -z "$appScheme" -o "$appScheme" = " " ]; then
echo >&2 "ERROR - sonar.objectivec.appScheme parameter is missing in sonar-project.properties. You must specify which scheme is used to build your application."
exit 1
fi
## SCRIPT
# Start progress indicator in the background
if [ "$vflag" = "" -a "$nflag" = "" ]; then
startProgress &
# Save PID
PROGRESS_PID=$!
fi
# Create sonar-reports/ for reports output
if [[ ! (-d "build/sonar-reports") && ("$nflag" != "on") ]]; then
if [ "$vflag" = "on" ]; then
echo 'Creating directory sonar-reports/'
fi
mkdir build/sonar-reports
if [[ $? != 0 ]] ; then
stopProgress
exit $?
fi
fi
# Extracting project information needed later
echo -n 'Extracting Xcode project information'
#runCommand /dev/stdout $xctoolCmdPrefix -scheme "$appScheme" clean
#runCommand /dev/stdout $xctoolCmdPrefix -scheme "$appScheme" -reporter json-compilation-database:compile_commands.json build
#runCommand /dev/stdout $xcodebuildCmdPrefix clean
xcodebuild clean
export LC_ALL="en_US.UTF-8"
if [[ "$workspaceFile" != "" ]] ; then
xcodebuild -workspace "$workspaceFile" -scheme "$appScheme" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6' ONLY_ACTIVE_ARCH=NO -configuration Release build | tee xcodebuild.log | xcpretty -r json-compilation-database --output compile_commands.json
else
echo "$projectFile--$appScheme"
xcodebuild -project "$projectFile" -scheme "$appScheme" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6' ONLY_ACTIVE_ARCH=NO -configuration Release build | tee xcodebuild.log | xcpretty -r json-compilation-database --output compile_commands.json
fi
# ---- 单元测试 与 覆盖率 部分 ----
# Unit tests and coverage
# if [ "$testScheme" = "" ]; then
# echo 'Skipping tests as no test scheme has been provided!'
# # Put default xml files with no tests and no coverage...
# echo "<?xml version='1.0' encoding='UTF-8' standalone='yes'?><testsuites name='AllTestUnits'></testsuites>" > sonar-reports/TEST-report.xml
# echo "<?xml version='1.0' ?><!DOCTYPE coverage SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-03.dtd'><coverage><sources></sources><packages></packages></coverage>" > sonar-reports/coverage.xml
# else
# echo -n 'Running tests using xctool'
# # runCommand sonar-reports/TEST-report.xml $xctoolCmdPrefix -scheme "$testScheme" -reporter junit GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES test
# # ctf:这个命令出错, 用下面的命令代替
# $xctoolCmdPrefix -scheme "$testScheme" -reporter junit:TEST-report.xml GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES test
# echo -n 'Computing coverage report'
# # We do it for every xcodeproject (in case of workspaces)
# # Extract the path to the .gcno/.gcda coverage files
# echo $projectFile | sed -n 1'p' | tr ',' '\\n' > tmpFileRunSonarSh
# while read projectName; do
# coverageFilesPath=$(grep 'command' compile_commands.json | sed 's#^.*-o \\\\/#\\/#;s#",##' | grep "$projectName%%.*.build" | awk 'NR<2' | sed 's/\\\\\\//\\//g' | sed 's/\\\\\\\\//g' | xargs -0 dirname)
# if [ "$vflag" = "on" ]; then
# echo
# echo "Path for .gcno/.gcda coverage files is: $coverageFilesPath"
# fi
# # Build the --exclude flags
# excludedCommandLineFlags=""
# if [ ! -z "$excludedPathsFromCoverage" -a "$excludedPathsFromCoverage" != " " ]; then
# echo $excludedPathsFromCoverage | sed -n 1'p' | tr ',' '\\n' > tmpFileRunSonarSh2
# while read word; do
# excludedCommandLineFlags+=" --exclude $word"
# done < tmpFileRunSonarSh2
# rm -rf tmpFileRunSonarSh2
# fi
# if [ "$vflag" = "on" ]; then
# echo "Command line exclusion flags for gcovr is:$excludedCommandLineFlags"
# fi
# # Run gcovr with the right options
# echo "coverageFilesPath is: $coverageFilesPath"
# echo "excludedCommandLineFlags is: $excludedCommandLineFlags"
# runCommand "sonar-reports/coverage-$projectName%%.*.xml" gcovr -r . "$coverageFilesPath" $excludedCommandLineFlags --xml
# done < tmpFileRunSonarSh
# rm -rf tmpFileRunSonarSh
# fi
# ---- 单元测试 与 覆盖率 部分 ----
if [ "$oclint" = "on" ]; then
# OCLint
echo -n 'Running OCLint...'
# Build the --include flags
currentDirectory=$PWD##*/
includedCommandLineFlags=""
echo "$srcDirs" | sed -n 1'p' | tr ',' '\\n' > tmpFileRunSonarSh
while read word; do
includedCommandLineFlags+=" --include .*/$currentDirectory/$word"
done < tmpFileRunSonarSh
rm -rf tmpFileRunSonarSh
if [ "$vflag" = "on" ]; then
echo
echo -n "Path included in oclint analysis is:$includedCommandLineFlags"
fi
# Run OCLint with the right set of compiler options
maxPriority=10000
# runCommand no oclint-json-compilation-database $includedCommandLineFlags -- -max-priority-1 $maxPriority -max-priority-2 $maxPriority -max-priority-3 $maxPriority -rc LONG_LINE=150 -report-type pmd -o sonar-reports/oclint.xml
oclint-json-compilation-database \\
-v \\
-- \\
-report-type pmd -o build/sonar-reports/oclint.xml \\
-max-priority-1=10000 -max-priority-2=10000 -max-priority-3=10000 \\
-rc LONG_METHOD=300 \\
-rc LONG_VARIABLE_NAME=50 \\
-rc LONG_CLASS=3000 \\
-rc NCSS_METHOD=300 \\
-rc NESTED_BLOCK_DEPTH=8 \\
#oclint-json-compilation-database -e Pods -- -stats -verbose -report-type=html -o=oclint.html -max-priority-1=99999 -max-priority-2=99999 -max-priority-3=99999 -rc LONG_LINE=200 -rc LONG_METHOD=100 -rc LONG_VARIABLE_NAME=40 -disable-rule=BrokenOddnessCheck -disable-rule=VerifyProhibitedCall -disable-rule=VerifyProtectedMethod -disable-rule=SubclassMustImplement -disable-rule=BaseClassDestructorShouldBeVirtualOrProtected -disable-rule=DestructorOfVirtualClass -disable-rule=ParameterReassignment -disable-rule=AvoidDefaultArgumentsOnVirtualMethods -disable-rule=AvoidPrivateStaticMembers -disable-rule=TooManyParameters
else
echo 'Skipping OCLint (test purposes only!)'
fi
# SonarQube
echo -n 'Running SonarQube using sonar-scanner'
#runCommand /dev/stdout sonar-runner
sonar-scanner
# Kill progress indicator
stopProgress
exit 0
直接进入项目根目录执行 sh run-sonar.sh
即可
最后感谢大佬的帮助: https://github.com/ChenTF/iOS-sonarShell
以上是关于Mac-Sonar系统执行代码分析的主要内容,如果未能解决你的问题,请参考以下文章
EntityFramework的多种记录日志方式,记录错误并分析执行时间过长原因(系列4)