├── sonar-objective-c-plugin-0.5.0-SNAPSHOT.jar ├── backelite-sonar-objective-c-plugin-0.6.2.jar ├── README.md ├── LICENSE ├── sonar-project.properties ├── run-sonar.sh ├── run-sonar_V2.1.sh ├── profile-oclint.xml ├── run-sonar_V2.sh └── rules-oclint.xml /sonar-objective-c-plugin-0.5.0-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChenTF/iOS-sonarShell/HEAD/sonar-objective-c-plugin-0.5.0-SNAPSHOT.jar -------------------------------------------------------------------------------- /backelite-sonar-objective-c-plugin-0.6.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChenTF/iOS-sonarShell/HEAD/backelite-sonar-objective-c-plugin-0.6.2.jar -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iOS-sonarShell 2 | 3 | 本Git仓库放置修复XCode8之后Sonar兼容需要的文件, 具体的修复步骤与详细说明请看Blog: [[实践]Sonar Xcode8兼容](http://my.oschina.net/ChenTF/blog/708646) 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 陈先生 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | ########################## 2 | # Required configuration # 3 | ########################## 4 | 5 | sonar.projectKey=ios::projectKey 6 | sonar.projectName=ios::profilename 7 | sonar.projectVersion=1.0 8 | sonar.language=objectivec 9 | 10 | # Project description 11 | sonar.projectDescription=Fake description 12 | 13 | # Path to source directories 工程文件目录 14 | sonar.sources= 15 | # Path to test directories (comment if no test) 测试文件目录 16 | sonar.tests= 17 | 18 | # Code Sign 注意是Release版本的前面与描述文件 (V2.1版本已经不需要此设置) 19 | # sonar.objectivec.codesign= 20 | # sonar.objectivec.profilename= 21 | 22 | 23 | # Xcode project configuration (.xcodeproj or .xcworkspace) 24 | # -> If you have a project: configure only sonar.objectivec.project 25 | # -> If you have a workspace: configure sonar.objectivec.workspace and sonar.objectivec.project 26 | # and use the later to specify which project(s) to include in the analysis (comma separated list) 27 | 28 | # !! 以下二选一 !! 29 | sonar.objectivec.project=xx.xcodeproj 30 | sonar.objectivec.workspace=xx.xcworkspace 31 | 32 | # Scheme to build your application 33 | sonar.objectivec.appScheme= 34 | # Scheme to build and run your tests (comment following line of you don't have any tests) 35 | sonar.objectivec.testScheme= 36 | 37 | ########################## 38 | # Optional configuration # 39 | ########################## 40 | 41 | # Encoding of the source code 42 | sonar.sourceEncoding=UTF-8 43 | 44 | # JUnit report generated by run-sonar.sh is stored in sonar-reports/TEST-report.xml 45 | # Change it only if you generate the file on your own 46 | # The XML files have to be prefixed by TEST- otherwise they are not processed 47 | # sonar.junit.reportsPath=sonar-reports/ 48 | sonar.objectivec.junit.reportsPath=TEST-report.xml 49 | 50 | # Cobertura report generated by run-sonar.sh is stored in sonar-reports/coverage.xml 51 | # Change it only if you generate the file on your own 52 | # sonar.objectivec.coverage.reportPattern=sonar-reports/coverage*.xml 53 | sonar.objectivec.cobertura.reportPath=sonar-reports/coverage-SuYun.xml 54 | 55 | # OCLint report generated by run-sonar.sh is stored in sonar-reports/oclint.xml 56 | # Change it only if you generate the file on your own 57 | sonar.objectivec.oclint.reportPath=oclint.xml 58 | 59 | # Paths to exclude from coverage report (tests, 3rd party libraries etc.) 60 | # sonar.objectivec.excludedPathsFromCoverage=pattern1,pattern2 61 | # sonar.objectivec.excludedPathsFromCoverage=.*Tests.* 62 | 63 | # Project SCM settings 64 | sonar.scm.enabled=false 65 | # sonar.scm.url=scm:git:https://... 66 | sonar.host.url= 67 | sonar.scm.provider=svn 68 | 69 | -------------------------------------------------------------------------------- /run-sonar.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## INSTALLATION: script to copy in your Xcode project in the same directory as the .xcodeproj file 3 | ## USAGE: ./run-sonar.sh 4 | ## DEBUG: ./run-sonar.sh -v 5 | ## WARNING: edit your project parameters in sonar-project.properties rather than modifying this script 6 | # 7 | 8 | trap "echo 'Script interrupted by Ctrl+C'; stopProgress; exit 1" SIGHUP SIGINT SIGTERM 9 | 10 | function startProgress() { 11 | while true 12 | do 13 | echo -n "." 14 | sleep 5 15 | done 16 | } 17 | 18 | function stopProgress() { 19 | if [ "$vflag" = "" -a "$nflag" = "" ]; then 20 | kill $PROGRESS_PID &>/dev/null 21 | fi 22 | } 23 | 24 | function testIsInstalled() { 25 | 26 | hash $1 2>/dev/null 27 | if [ $? -eq 1 ]; then 28 | echo >&2 "ERROR - $1 is not installed or not in your PATH"; exit 1; 29 | fi 30 | } 31 | 32 | function readParameter() { 33 | 34 | variable=$1 35 | shift 36 | parameter=$1 37 | shift 38 | 39 | eval $variable="\"$(sed '/^\#/d' sonar-project.properties | grep $parameter | tail -n 1 | cut -d '=' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')\"" 40 | } 41 | 42 | # Run a set of commands with logging and error handling 43 | function runCommand() { 44 | 45 | # 1st arg: redirect stdout 46 | # 2nd arg: command to run 47 | # 3rd..nth arg: args 48 | redirect=$1 49 | shift 50 | 51 | command=$1 52 | shift 53 | 54 | if [ "$nflag" = "on" ]; then 55 | # don't execute command, just echo it 56 | echo 57 | if [ "$redirect" = "/dev/stdout" ]; then 58 | if [ "$vflag" = "on" ]; then 59 | echo "+" $command "$@" 60 | else 61 | echo "+" $command "$@" "> /dev/null" 62 | fi 63 | elif [ "$redirect" != "no" ]; then 64 | echo "+" $command "$@" "> $redirect" 65 | else 66 | echo "+" $command "$@" 67 | fi 68 | 69 | elif [ "$vflag" = "on" ]; then 70 | echo 71 | 72 | if [ "$redirect" = "/dev/stdout" ]; then 73 | set -x #echo on 74 | $command "$@" 75 | returnValue=$? 76 | set +x #echo off 77 | elif [ "$redirect" != "no" ]; then 78 | set -x #echo on 79 | $command "$@" > $redirect 80 | returnValue=$? 81 | set +x #echo off 82 | else 83 | set -x #echo on 84 | $command "$@" 85 | returnValue=$? 86 | set +x #echo off 87 | fi 88 | 89 | if [[ $returnValue != 0 && $returnValue != 5 ]] ; then 90 | stopProgress 91 | echo "ERROR - Command '$command $@' failed with error code: $returnValue" 92 | exit $returnValue 93 | fi 94 | else 95 | 96 | if [ "$redirect" = "/dev/stdout" ]; then 97 | $command "$@" > /dev/null 98 | elif [ "$redirect" != "no" ]; then 99 | $command "$@" > $redirect 100 | else 101 | $command "$@" 102 | fi 103 | 104 | returnValue=$? 105 | if [[ $returnValue != 0 && $returnValue != 5 ]] ; then 106 | stopProgress 107 | echo "ERROR - Command '$command $@' failed with error code: $returnValue" 108 | exit $? 109 | fi 110 | 111 | 112 | echo 113 | fi 114 | } 115 | 116 | ## COMMAND LINE OPTIONS 117 | vflag="" 118 | nflag="" 119 | oclint="on" 120 | while [ $# -gt 0 ] 121 | do 122 | case "$1" in 123 | -v) vflag=on;; 124 | -n) nflag=on;; 125 | -nooclint) oclint="";; 126 | --) shift; break;; 127 | -*) 128 | echo >&2 "Usage: $0 [-v]" 129 | exit 1;; 130 | *) break;; # terminate while loop 131 | esac 132 | shift 133 | done 134 | 135 | # Usage OK 136 | echo "Running run-sonar.sh..." 137 | 138 | ## CHECK PREREQUISITES 139 | 140 | # xctool, gcovr and oclint installed 141 | testIsInstalled xctool 142 | testIsInstalled gcovr 143 | testIsInstalled oclint 144 | 145 | # sonar-project.properties in current directory 146 | if [ ! -f sonar-project.properties ]; then 147 | echo >&2 "ERROR - No sonar-project.properties in current directory"; exit 1; 148 | fi 149 | 150 | ## READ PARAMETERS from sonar-project.properties 151 | 152 | # Your .xcworkspace/.xcodeproj filename 153 | workspaceFile=''; readParameter workspaceFile 'sonar.objectivec.workspace' 154 | projectFile=''; readParameter projectFile 'sonar.objectivec.project' 155 | if [[ "$workspaceFile" != "" ]] ; then 156 | xctoolCmdPrefix="xctool -workspace $workspaceFile -sdk iphonesimulator ARCHS=i386 VALID_ARCHS=i386 CURRENT_ARCH=i386 ONLY_ACTIVE_ARCH=NO" 157 | else 158 | xctoolCmdPrefix="xctool -project $projectFile -sdk iphonesimulator ARCHS=i386 VALID_ARCHS=i386 CURRENT_ARCH=i386 ONLY_ACTIVE_ARCH=NO" 159 | fi 160 | 161 | # Source directories for .h/.m files 162 | srcDirs=''; readParameter srcDirs 'sonar.sources' 163 | # The name of your application scheme in Xcode 164 | appScheme=''; readParameter appScheme 'sonar.objectivec.appScheme' 165 | 166 | # The name of your test scheme in Xcode 167 | testScheme=''; readParameter testScheme 'sonar.objectivec.testScheme' 168 | # The file patterns to exclude from coverage report 169 | excludedPathsFromCoverage=''; readParameter excludedPathsFromCoverage 'sonar.objectivec.excludedPathsFromCoverage' 170 | 171 | # Check for mandatory parameters 172 | if [ -z "$projectFile" -o "$projectFile" = " " ]; then 173 | 174 | if [ ! -z "$workspaceFile" -a "$workspaceFile" != " " ]; then 175 | 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." 176 | else 177 | echo >&2 "ERROR - sonar.objectivec.project parameter is missing in sonar-project.properties (name of your .xcodeproj)" 178 | fi 179 | exit 1 180 | fi 181 | if [ -z "$srcDirs" -o "$srcDirs" = " " ]; then 182 | 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)." 183 | exit 1 184 | fi 185 | if [ -z "$appScheme" -o "$appScheme" = " " ]; then 186 | echo >&2 "ERROR - sonar.objectivec.appScheme parameter is missing in sonar-project.properties. You must specify which scheme is used to build your application." 187 | exit 1 188 | fi 189 | 190 | if [ "$vflag" = "on" ]; then 191 | echo "Xcode workspace file is: $workspaceFile" 192 | echo "Xcode project file is: $projectFile" 193 | echo "Xcode application scheme is: $appScheme" 194 | echo "Xcode test scheme is: $testScheme" 195 | echo "Excluded paths from coverage are: $excludedPathsFromCoverage" 196 | fi 197 | 198 | ## SCRIPT 199 | 200 | # Start progress indicator in the background 201 | if [ "$vflag" = "" -a "$nflag" = "" ]; then 202 | startProgress & 203 | # Save PID 204 | PROGRESS_PID=$! 205 | fi 206 | 207 | # Create sonar-reports/ for reports output 208 | if [[ ! (-d "sonar-reports") && ("$nflag" != "on") ]]; then 209 | if [ "$vflag" = "on" ]; then 210 | echo 'Creating directory sonar-reports/' 211 | fi 212 | mkdir sonar-reports 213 | if [[ $? != 0 ]] ; then 214 | stopProgress 215 | exit $? 216 | fi 217 | fi 218 | 219 | # Extracting project information needed later 220 | echo -n 'Extracting Xcode project information' 221 | runCommand /dev/stdout $xctoolCmdPrefix -scheme "$appScheme" clean 222 | runCommand /dev/stdout $xctoolCmdPrefix -scheme "$appScheme" -reporter json-compilation-database:compile_commands.json build 223 | 224 | # Unit tests and coverage 225 | if [ "$testScheme" = "" ]; then 226 | echo 'Skipping tests as no test scheme has been provided!' 227 | 228 | # Put default xml files with no tests and no coverage... 229 | echo "" > sonar-reports/TEST-report.xml 230 | echo "" > sonar-reports/coverage.xml 231 | else 232 | 233 | echo -n 'Running tests using xctool' 234 | # runCommand sonar-reports/TEST-report.xml $xctoolCmdPrefix -scheme "$testScheme" -reporter junit GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES test 235 | # ctf:这个命令出错, 用下面的命令代替 236 | $xctoolCmdPrefix -scheme "$testScheme" -reporter junit:TEST-report.xml GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES test 237 | 238 | echo -n 'Computing coverage report' 239 | 240 | # We do it for every xcodeproject (in case of workspaces) 241 | 242 | # Extract the path to the .gcno/.gcda coverage files 243 | echo $projectFile | sed -n 1'p' | tr ',' '\n' > tmpFileRunSonarSh 244 | while read projectName; do 245 | 246 | 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) 247 | if [ "$vflag" = "on" ]; then 248 | echo 249 | echo "Path for .gcno/.gcda coverage files is: $coverageFilesPath" 250 | fi 251 | 252 | # Build the --exclude flags 253 | excludedCommandLineFlags="" 254 | if [ ! -z "$excludedPathsFromCoverage" -a "$excludedPathsFromCoverage" != " " ]; then 255 | echo $excludedPathsFromCoverage | sed -n 1'p' | tr ',' '\n' > tmpFileRunSonarSh2 256 | while read word; do 257 | excludedCommandLineFlags+=" --exclude $word" 258 | done < tmpFileRunSonarSh2 259 | rm -rf tmpFileRunSonarSh2 260 | fi 261 | if [ "$vflag" = "on" ]; then 262 | echo "Command line exclusion flags for gcovr is:$excludedCommandLineFlags" 263 | fi 264 | 265 | # Run gcovr with the right options 266 | runCommand "sonar-reports/coverage-${projectName%%.*}.xml" gcovr -r . "$coverageFilesPath" $excludedCommandLineFlags --xml 267 | 268 | done < tmpFileRunSonarSh 269 | rm -rf tmpFileRunSonarSh 270 | 271 | fi 272 | 273 | if [ "$oclint" = "on" ]; then 274 | 275 | # OCLint 276 | echo -n 'Running OCLint...' 277 | 278 | # Build the --include flags 279 | currentDirectory=${PWD##*/} 280 | includedCommandLineFlags="" 281 | echo "$srcDirs" | sed -n 1'p' | tr ',' '\n' > tmpFileRunSonarSh 282 | while read word; do 283 | includedCommandLineFlags+=" --include .*/${currentDirectory}/${word}" 284 | done < tmpFileRunSonarSh 285 | rm -rf tmpFileRunSonarSh 286 | if [ "$vflag" = "on" ]; then 287 | echo 288 | echo -n "Path included in oclint analysis is:$includedCommandLineFlags" 289 | fi 290 | 291 | # Run OCLint with the right set of compiler options 292 | maxPriority=10000 293 | runCommand no oclint-json-compilation-database $includedCommandLineFlags -- -max-priority-1 $maxPriority -max-priority-2 $maxPriority -max-priority-3 $maxPriority -report-type pmd -o sonar-reports/oclint.xml 294 | else 295 | echo 'Skipping OCLint (test purposes only!)' 296 | fi 297 | 298 | # SonarQube 299 | echo -n 'Running SonarQube using SonarQube Runner' 300 | runCommand /dev/stdout sonar-runner 301 | 302 | # Kill progress indicator 303 | stopProgress 304 | 305 | exit 0 306 | -------------------------------------------------------------------------------- /run-sonar_V2.1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## INSTALLATION: script to copy in your Xcode project in the same directory as the .xcodeproj file 3 | ## USAGE: ./run-sonar.sh 4 | ## DEBUG: ./run-sonar.sh -v 5 | ## WARNING: edit your project parameters in sonar-project.properties rather than modifying this script 6 | # 7 | 8 | trap "echo 'Script interrupted by Ctrl+C'; stopProgress; exit 1" SIGHUP SIGINT SIGTERM 9 | 10 | function startProgress() { 11 | while true 12 | do 13 | echo -n "." 14 | sleep 5 15 | done 16 | } 17 | 18 | function stopProgress() { 19 | if [ "$vflag" = "" -a "$nflag" = "" ]; then 20 | kill $PROGRESS_PID &>/dev/null 21 | fi 22 | } 23 | 24 | function testIsInstalled() { 25 | 26 | hash $1 2>/dev/null 27 | if [ $? -eq 1 ]; then 28 | echo >&2 "ERROR - $1 is not installed or not in your PATH"; exit 1; 29 | fi 30 | } 31 | 32 | function readParameter() { 33 | 34 | variable=$1 35 | shift 36 | parameter=$1 37 | shift 38 | 39 | eval $variable="\"$(sed '/^\#/d' sonar-project.properties | grep $parameter | tail -n 1 | cut -d '=' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')\"" 40 | } 41 | 42 | # Run a set of commands with logging and error handling 43 | function runCommand() { 44 | 45 | # 1st arg: redirect stdout 46 | # 2nd arg: command to run 47 | # 3rd..nth arg: args 48 | redirect=$1 49 | shift 50 | 51 | command=$1 52 | shift 53 | 54 | if [ "$nflag" = "on" ]; then 55 | # don't execute command, just echo it 56 | echo 57 | if [ "$redirect" = "/dev/stdout" ]; then 58 | if [ "$vflag" = "on" ]; then 59 | echo "+" $command "$@" 60 | else 61 | echo "+" $command "$@" "> /dev/null" 62 | fi 63 | elif [ "$redirect" != "no" ]; then 64 | echo "+" $command "$@" "> $redirect" 65 | else 66 | echo "+" $command "$@" 67 | fi 68 | 69 | elif [ "$vflag" = "on" ]; then 70 | echo 71 | 72 | if [ "$redirect" = "/dev/stdout" ]; then 73 | set -x #echo on 74 | $command "$@" 75 | returnValue=$? 76 | set +x #echo off 77 | elif [ "$redirect" != "no" ]; then 78 | set -x #echo on 79 | $command "$@" > $redirect 80 | returnValue=$? 81 | set +x #echo off 82 | else 83 | set -x #echo on 84 | $command "$@" 85 | returnValue=$? 86 | set +x #echo off 87 | fi 88 | 89 | if [[ $returnValue != 0 && $returnValue != 5 ]] ; then 90 | stopProgress 91 | echo "ERROR - Command '$command $@' failed with error code: $returnValue" 92 | exit $returnValue 93 | fi 94 | else 95 | echo "--------------------------------" 96 | echo $command 97 | echo "$@" 98 | if [ "$redirect" = "/dev/stdout" ]; then 99 | $command "$@" > /dev/null 100 | elif [ "$redirect" != "no" ]; then 101 | $command "$@" > $redirect 102 | else 103 | $command "$@" 104 | fi 105 | 106 | returnValue=$? 107 | if [[ $returnValue != 0 && $returnValue != 5 ]] ; then 108 | stopProgress 109 | echo "ERROR - Command '$command $@' failed with error code: $returnValue" 110 | exit $? 111 | fi 112 | 113 | 114 | echo 115 | fi 116 | } 117 | 118 | ## COMMAND LINE OPTIONS 119 | vflag="" 120 | nflag="" 121 | oclint="on" 122 | while [ $# -gt 0 ] 123 | do 124 | case "$1" in 125 | -v) vflag=on;; 126 | -n) nflag=on;; 127 | -nooclint) oclint="";; 128 | --) shift; break;; 129 | -*) 130 | echo >&2 "Usage: $0 [-v]" 131 | exit 1;; 132 | *) break;; # terminate while loop 133 | esac 134 | shift 135 | done 136 | 137 | # Usage OK 138 | echo "Running run-sonar.sh..." 139 | 140 | ## CHECK PREREQUISITES 141 | 142 | # xctool, gcovr and oclint installed 143 | # testIsInstalled xctool 144 | testIsInstalled xcpretty 145 | #testIsInstalled gcovr 146 | testIsInstalled oclint 147 | 148 | # sonar-project.properties in current directory 149 | if [ ! -f sonar-project.properties ]; then 150 | echo >&2 "ERROR - No sonar-project.properties in current directory"; exit 1; 151 | fi 152 | 153 | ## READ PARAMETERS from sonar-project.properties 154 | 155 | # Your .xcworkspace/.xcodeproj filename 156 | workspaceFile=''; readParameter workspaceFile 'sonar.objectivec.workspace' 157 | projectFile=''; readParameter projectFile 'sonar.objectivec.project' 158 | # Source directories for .h/.m files 159 | srcDirs=''; readParameter srcDirs 'sonar.sources' 160 | # The name of your application scheme in Xcode 161 | appScheme=''; readParameter appScheme 'sonar.objectivec.appScheme' 162 | 163 | # The name of your test scheme in Xcode 164 | testScheme=''; readParameter testScheme 'sonar.objectivec.testScheme' 165 | # The file patterns to exclude from coverage report 166 | excludedPathsFromCoverage=''; readParameter excludedPathsFromCoverage 'sonar.objectivec.excludedPathsFromCoverage' 167 | 168 | if [ "$vflag" = "on" ]; then 169 | echo "Xcode workspace file is: $workspaceFile" 170 | echo "Xcode project file is: $projectFile" 171 | echo "Xcode application scheme is: $appScheme" 172 | echo "Xcode test scheme is: $testScheme" 173 | echo "Excluded paths from coverage are: $excludedPathsFromCoverage" 174 | fi 175 | 176 | if [[ $projectFile != "" ]]; then 177 | #statements 178 | # 设置XCode的签名方式为手动签名 179 | echo "-----设置自动签名, projectFile: $projectFile \n" 180 | sed -i "" "s%\ProvisioningStyle.*%\ProvisioningStyle = Manual;%g" "${projectFile}/project.pbxproj" 181 | # 删除TeamID设置 182 | sed -i "" "s%\DevelopmentTeam.*%\ %g" "${projectFile}/project.pbxproj" 183 | sed -i "" "s%\DEVELOPMENT_TEAM.*%\ %g" "${projectFile}/project.pbxproj" 184 | fi 185 | 186 | if [[ "$workspaceFile" != "" ]] ; then 187 | # 17/03/01 修改: 将证书描述文件设置改成模拟器设置 188 | xcodebuildCmdPrefix="xcodebuild -workspace $workspaceFile -scheme ${appScheme} -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6' ONLY_ACTIVE_ARCH=NO -configuration Release " 189 | else 190 | xcodebuildCmdPrefix="xcodebuild -project $projectFile -scheme ${appScheme} -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6' ONLY_ACTIVE_ARCH=NO -configuration Release" 191 | fi 192 | 193 | 194 | 195 | # Check for mandatory parameters 196 | if [ -z "$projectFile" -o "$projectFile" = " " ]; then 197 | 198 | if [ ! -z "$workspaceFile" -a "$workspaceFile" != " " ]; then 199 | 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." 200 | else 201 | echo >&2 "ERROR - sonar.objectivec.project parameter is missing in sonar-project.properties (name of your .xcodeproj)" 202 | fi 203 | exit 1 204 | fi 205 | if [ -z "$srcDirs" -o "$srcDirs" = " " ]; then 206 | 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)." 207 | exit 1 208 | fi 209 | if [ -z "$appScheme" -o "$appScheme" = " " ]; then 210 | echo >&2 "ERROR - sonar.objectivec.appScheme parameter is missing in sonar-project.properties. You must specify which scheme is used to build your application." 211 | exit 1 212 | fi 213 | 214 | 215 | 216 | ## SCRIPT 217 | 218 | # Start progress indicator in the background 219 | if [ "$vflag" = "" -a "$nflag" = "" ]; then 220 | startProgress & 221 | # Save PID 222 | PROGRESS_PID=$! 223 | fi 224 | 225 | # Create sonar-reports/ for reports output 226 | if [[ ! (-d "sonar-reports") && ("$nflag" != "on") ]]; then 227 | if [ "$vflag" = "on" ]; then 228 | echo 'Creating directory sonar-reports/' 229 | fi 230 | mkdir sonar-reports 231 | if [[ $? != 0 ]] ; then 232 | stopProgress 233 | exit $? 234 | fi 235 | fi 236 | 237 | # Extracting project information needed later 238 | echo -n 'Extracting Xcode project information' 239 | #runCommand /dev/stdout $xctoolCmdPrefix -scheme "$appScheme" clean 240 | #runCommand /dev/stdout $xctoolCmdPrefix -scheme "$appScheme" -reporter json-compilation-database:compile_commands.json build 241 | #runCommand /dev/stdout $xcodebuildCmdPrefix clean 242 | 243 | xcodebuild clean 244 | 245 | export LC_ALL="en_US.UTF-8" 246 | if [[ "$workspaceFile" != "" ]] ; then 247 | 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 248 | else 249 | 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 250 | fi 251 | 252 | # ---- 单元测试 与 覆盖率 部分 ---- 253 | # Unit tests and coverage 254 | # if [ "$testScheme" = "" ]; then 255 | # echo 'Skipping tests as no test scheme has been provided!' 256 | 257 | # # Put default xml files with no tests and no coverage... 258 | # echo "" > sonar-reports/TEST-report.xml 259 | # echo "" > sonar-reports/coverage.xml 260 | # else 261 | 262 | # echo -n 'Running tests using xctool' 263 | # # runCommand sonar-reports/TEST-report.xml $xctoolCmdPrefix -scheme "$testScheme" -reporter junit GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES test 264 | # # ctf:这个命令出错, 用下面的命令代替 265 | # $xctoolCmdPrefix -scheme "$testScheme" -reporter junit:TEST-report.xml GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES test 266 | 267 | # echo -n 'Computing coverage report' 268 | 269 | # # We do it for every xcodeproject (in case of workspaces) 270 | 271 | # # Extract the path to the .gcno/.gcda coverage files 272 | # echo $projectFile | sed -n 1'p' | tr ',' '\n' > tmpFileRunSonarSh 273 | # while read projectName; do 274 | 275 | # 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) 276 | # if [ "$vflag" = "on" ]; then 277 | # echo 278 | # echo "Path for .gcno/.gcda coverage files is: $coverageFilesPath" 279 | # fi 280 | 281 | # # Build the --exclude flags 282 | # excludedCommandLineFlags="" 283 | # if [ ! -z "$excludedPathsFromCoverage" -a "$excludedPathsFromCoverage" != " " ]; then 284 | # echo $excludedPathsFromCoverage | sed -n 1'p' | tr ',' '\n' > tmpFileRunSonarSh2 285 | # while read word; do 286 | # excludedCommandLineFlags+=" --exclude $word" 287 | # done < tmpFileRunSonarSh2 288 | # rm -rf tmpFileRunSonarSh2 289 | # fi 290 | # if [ "$vflag" = "on" ]; then 291 | # echo "Command line exclusion flags for gcovr is:$excludedCommandLineFlags" 292 | # fi 293 | 294 | # # Run gcovr with the right options 295 | # echo "coverageFilesPath is: $coverageFilesPath" 296 | # echo "excludedCommandLineFlags is: $excludedCommandLineFlags" 297 | # runCommand "sonar-reports/coverage-${projectName%%.*}.xml" gcovr -r . "$coverageFilesPath" $excludedCommandLineFlags --xml 298 | 299 | # done < tmpFileRunSonarSh 300 | # rm -rf tmpFileRunSonarSh 301 | 302 | # fi 303 | 304 | # ---- 单元测试 与 覆盖率 部分 ---- 305 | 306 | if [ "$oclint" = "on" ]; then 307 | 308 | # OCLint 309 | echo -n 'Running OCLint...' 310 | 311 | # Build the --include flags 312 | currentDirectory=${PWD##*/} 313 | includedCommandLineFlags="" 314 | echo "$srcDirs" | sed -n 1'p' | tr ',' '\n' > tmpFileRunSonarSh 315 | while read word; do 316 | includedCommandLineFlags+=" --include .*/${currentDirectory}/${word}" 317 | done < tmpFileRunSonarSh 318 | rm -rf tmpFileRunSonarSh 319 | if [ "$vflag" = "on" ]; then 320 | echo 321 | echo -n "Path included in oclint analysis is:$includedCommandLineFlags" 322 | fi 323 | 324 | # Run OCLint with the right set of compiler options 325 | maxPriority=10000 326 | # 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 327 | oclint-json-compilation-database -- -max-priority-1 $maxPriority -max-priority-2 $maxPriority -max-priority-3 $maxPriority -rc LONG_LINE=150 -report-type pmd -o oclint.xml 328 | 329 | else 330 | echo 'Skipping OCLint (test purposes only!)' 331 | fi 332 | 333 | # SonarQube 334 | echo -n 'Running SonarQube using sonar-scanner' 335 | #runCommand /dev/stdout sonar-runner 336 | sonar-scanner 337 | 338 | # Kill progress indicator 339 | stopProgress 340 | 341 | exit 0 342 | -------------------------------------------------------------------------------- /profile-oclint.xml: -------------------------------------------------------------------------------- 1 | 2 | OCLint 3 | objectivec 4 | 5 | 6 | OCLint 7 | bitwise operator in conditional 8 | 9 | 10 | OCLint 11 | broken nil check 12 | 13 | 14 | OCLint 15 | broken null check 16 | 17 | 18 | OCLint 19 | broken oddness check 20 | 21 | 22 | OCLint 23 | collapsible if statements 24 | 25 | 26 | OCLint 27 | constant conditional operator 28 | 29 | 30 | OCLint 31 | constant if expression 32 | 33 | 34 | OCLint 35 | dead code 36 | 37 | 38 | OCLint 39 | double negative 40 | 41 | 42 | OCLint 43 | for loop should be while loop 44 | 45 | 46 | OCLint 47 | goto statement 48 | 49 | 50 | OCLint 51 | misplaced nil check 52 | 53 | 54 | OCLint 55 | misplaced null check 56 | 57 | 58 | OCLint 59 | multiple unary operator 60 | 61 | 62 | OCLint 63 | return from finally block 64 | 65 | 66 | OCLint 67 | throw exception from finally block 68 | 69 | 70 | OCLint 71 | avoid branching statement as last in loop 72 | 73 | 74 | OCLint 75 | default label not last in switch statement 76 | 77 | 78 | OCLint 79 | inverted logic 80 | 81 | 82 | OCLint 83 | non case label in switch statement 84 | 85 | 86 | OCLint 87 | parameter reassignment 88 | 89 | 90 | OCLint 91 | switch statements should have default 92 | 93 | 94 | OCLint 95 | too few branches in switch statement 96 | 97 | 98 | OCLint 99 | empty catch statement 100 | 101 | 102 | OCLint 103 | empty do/while statement 104 | 105 | 106 | OCLint 107 | empty else block 108 | 109 | 110 | OCLint 111 | empty finally statement 112 | 113 | 114 | OCLint 115 | empty for statement 116 | 117 | 118 | OCLint 119 | empty if statement 120 | 121 | 122 | OCLint 123 | empty switch statement 124 | 125 | 126 | OCLint 127 | empty try statement 128 | 129 | 130 | OCLint 131 | empty while statement 132 | 133 | 134 | OCLint 135 | replace with boxed expression 136 | 137 | 138 | OCLint 139 | replace with container literal 140 | 141 | 142 | OCLint 143 | replace with number literal 144 | 145 | 146 | OCLint 147 | replace with object subscripting 148 | 149 | 150 | OCLint 151 | long variable name 152 | 153 | 154 | OCLint 155 | short variable name 156 | 157 | 158 | OCLint 159 | redundant conditional operator 160 | 161 | 162 | OCLint 163 | redundant if statement 164 | 165 | 166 | OCLint 167 | redundant local variable 168 | 169 | 170 | OCLint 171 | redundant nil check 172 | 173 | 174 | OCLint 175 | unnecessary else statement 176 | 177 | 178 | OCLint 179 | useless parentheses 180 | 181 | 182 | OCLint 183 | high cyclomatic complexity 184 | 185 | 186 | OCLint 187 | long class 188 | 189 | 190 | OCLint 191 | long line 192 | 193 | 194 | OCLint 195 | long method 196 | 197 | 198 | OCLint 199 | high ncss method 200 | 201 | 202 | OCLint 203 | deep nested block 204 | 205 | 206 | OCLint 207 | high npath complexity 208 | 209 | 210 | OCLint 211 | too many fields 212 | 213 | 214 | OCLint 215 | too many methods 216 | 217 | 218 | OCLint 219 | too many parameters 220 | 221 | 222 | OCLint 223 | unused local variable 224 | 225 | 226 | OCLint 227 | unused method parameter 228 | 229 | 230 | OCLint 231 | feature envy 232 | 233 | 234 | OCLint 235 | ivar assignment outside accessors or init 236 | 237 | 238 | OCLint 239 | jumbled incrementer 240 | 241 | 242 | OCLint 243 | missing break in switch statement 244 | 245 | 246 | OCLint 247 | must override hash with isEqual 248 | 249 | 250 | OCLint 251 | switch statements don't need default when fully covered 252 | 253 | 254 | OCLint 255 | use early exits and continue 256 | 257 | 258 | 259 | 260 | OCLint 261 | missing hash method 262 | 263 | 264 | OCLint 265 | missing call to base method 266 | 267 | 268 | OCLint 269 | missing abstract method implementation 270 | 271 | 272 | OCLint 273 | calling prohibited method 274 | 275 | 276 | OCLint 277 | calling protected method 278 | 279 | 280 | OCLint 281 | base class destructor should be virtual or protected 282 | 283 | 284 | OCLint 285 | destructor of virtual class 286 | 287 | 288 | OCLint 289 | prefer early exits and continue 290 | 291 | 292 | OCLint 293 | unnecessary default statement in covered switch statement 294 | 295 | 296 | OCLint 297 | avoid default arguments on virtual methods 298 | 299 | 300 | OCLint 301 | avoid private static members 302 | 303 | 304 | OCLint 305 | use boxed expression 306 | 307 | 308 | OCLint 309 | use container literal 310 | 311 | 312 | OCLint 313 | use number literal 314 | 315 | 316 | OCLint 317 | use object subscripting 318 | 319 | 320 | OCLint 321 | unnecessary null check for dealloc 322 | 323 | 324 | OCLint 325 | missing default in switch statements 326 | 327 | 328 | OCLint 329 | ill-placed default label in switch statement 330 | 331 | 332 | OCLint 333 | continue 334 | 335 | 336 | OCLint 337 | continue 338 | 339 | 340 | OCLint 341 | continue 342 | 343 | 344 | OCLint 345 | continue 346 | 347 | 348 | 349 | -------------------------------------------------------------------------------- /run-sonar_V2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## INSTALLATION: script to copy in your Xcode project in the same directory as the .xcodeproj file 3 | ## USAGE: ./run-sonar.sh 4 | ## DEBUG: ./run-sonar.sh -v 5 | ## WARNING: edit your project parameters in sonar-project.properties rather than modifying this script 6 | # 7 | 8 | trap "echo 'Script interrupted by Ctrl+C'; stopProgress; exit 1" SIGHUP SIGINT SIGTERM 9 | 10 | function startProgress() { 11 | while true 12 | do 13 | echo -n "." 14 | sleep 5 15 | done 16 | } 17 | 18 | function stopProgress() { 19 | if [ "$vflag" = "" -a "$nflag" = "" ]; then 20 | kill $PROGRESS_PID &>/dev/null 21 | fi 22 | } 23 | 24 | function testIsInstalled() { 25 | 26 | hash $1 2>/dev/null 27 | if [ $? -eq 1 ]; then 28 | echo >&2 "ERROR - $1 is not installed or not in your PATH"; exit 1; 29 | fi 30 | } 31 | 32 | function readParameter() { 33 | 34 | variable=$1 35 | shift 36 | parameter=$1 37 | shift 38 | 39 | eval $variable="\"$(sed '/^\#/d' sonar-project.properties | grep $parameter | tail -n 1 | cut -d '=' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')\"" 40 | } 41 | 42 | # Run a set of commands with logging and error handling 43 | function runCommand() { 44 | 45 | # 1st arg: redirect stdout 46 | # 2nd arg: command to run 47 | # 3rd..nth arg: args 48 | redirect=$1 49 | shift 50 | 51 | command=$1 52 | shift 53 | 54 | if [ "$nflag" = "on" ]; then 55 | # don't execute command, just echo it 56 | echo 57 | if [ "$redirect" = "/dev/stdout" ]; then 58 | if [ "$vflag" = "on" ]; then 59 | echo "+" $command "$@" 60 | else 61 | echo "+" $command "$@" "> /dev/null" 62 | fi 63 | elif [ "$redirect" != "no" ]; then 64 | echo "+" $command "$@" "> $redirect" 65 | else 66 | echo "+" $command "$@" 67 | fi 68 | 69 | elif [ "$vflag" = "on" ]; then 70 | echo 71 | 72 | if [ "$redirect" = "/dev/stdout" ]; then 73 | set -x #echo on 74 | $command "$@" 75 | returnValue=$? 76 | set +x #echo off 77 | elif [ "$redirect" != "no" ]; then 78 | set -x #echo on 79 | $command "$@" > $redirect 80 | returnValue=$? 81 | set +x #echo off 82 | else 83 | set -x #echo on 84 | $command "$@" 85 | returnValue=$? 86 | set +x #echo off 87 | fi 88 | 89 | if [[ $returnValue != 0 && $returnValue != 5 ]] ; then 90 | stopProgress 91 | echo "ERROR - Command '$command $@' failed with error code: $returnValue" 92 | exit $returnValue 93 | fi 94 | else 95 | echo "--------------------------------" 96 | echo $command 97 | echo "$@" 98 | if [ "$redirect" = "/dev/stdout" ]; then 99 | $command "$@" > /dev/null 100 | elif [ "$redirect" != "no" ]; then 101 | $command "$@" > $redirect 102 | else 103 | $command "$@" 104 | fi 105 | 106 | returnValue=$? 107 | if [[ $returnValue != 0 && $returnValue != 5 ]] ; then 108 | stopProgress 109 | echo "ERROR - Command '$command $@' failed with error code: $returnValue" 110 | exit $? 111 | fi 112 | 113 | 114 | echo 115 | fi 116 | } 117 | 118 | ## COMMAND LINE OPTIONS 119 | vflag="" 120 | nflag="" 121 | oclint="on" 122 | while [ $# -gt 0 ] 123 | do 124 | case "$1" in 125 | -v) vflag=on;; 126 | -n) nflag=on;; 127 | -nooclint) oclint="";; 128 | --) shift; break;; 129 | -*) 130 | echo >&2 "Usage: $0 [-v]" 131 | exit 1;; 132 | *) break;; # terminate while loop 133 | esac 134 | shift 135 | done 136 | 137 | # Usage OK 138 | echo "Running run-sonar.sh..." 139 | 140 | ## CHECK PREREQUISITES 141 | 142 | # xctool, gcovr and oclint installed 143 | # testIsInstalled xctool 144 | testIsInstalled xcpretty 145 | #testIsInstalled gcovr 146 | testIsInstalled oclint 147 | 148 | # sonar-project.properties in current directory 149 | if [ ! -f sonar-project.properties ]; then 150 | echo >&2 "ERROR - No sonar-project.properties in current directory"; exit 1; 151 | fi 152 | 153 | ## READ PARAMETERS from sonar-project.properties 154 | 155 | # Your .xcworkspace/.xcodeproj filename 156 | workspaceFile=''; readParameter workspaceFile 'sonar.objectivec.workspace' 157 | projectFile=''; readParameter projectFile 'sonar.objectivec.project' 158 | # Source directories for .h/.m files 159 | srcDirs=''; readParameter srcDirs 'sonar.sources' 160 | # The name of your application scheme in Xcode 161 | appScheme=''; readParameter appScheme 'sonar.objectivec.appScheme' 162 | codesign=''; readParameter codesign 'sonar.objectivec.codesign' 163 | #codesign="\'iPhone Distribution: 58 daojia Life Service Co.,Ltd. (SYNJQ6CWNM)\'" 164 | profilename=''; readParameter profilename 'sonar.objectivec.profilename' 165 | 166 | # The name of your test scheme in Xcode 167 | testScheme=''; readParameter testScheme 'sonar.objectivec.testScheme' 168 | # The file patterns to exclude from coverage report 169 | excludedPathsFromCoverage=''; readParameter excludedPathsFromCoverage 'sonar.objectivec.excludedPathsFromCoverage' 170 | 171 | if [ "$vflag" = "on" ]; then 172 | echo "Xcode workspace file is: $workspaceFile" 173 | echo "Xcode project file is: $projectFile" 174 | echo "Xcode application scheme is: $appScheme" 175 | echo "Xcode test scheme is: $testScheme" 176 | echo "Xcode codesign is: $codesign" 177 | echo "Xcode profilename is: $profilename" 178 | echo "Excluded paths from coverage are: $excludedPathsFromCoverage" 179 | fi 180 | 181 | if [[ $projectFile != "" ]]; then 182 | #statements 183 | # 设置XCode的签名方式为手动签名 184 | echo "-----设置自动签名, projectFile: $projectFile \n" 185 | sed -i "" "s%\ProvisioningStyle.*%\ProvisioningStyle = Manual;%g" "${projectFile}/project.pbxproj" 186 | # 删除TeamID设置 187 | sed -i "" "s%\DevelopmentTeam.*%\ %g" "${projectFile}/project.pbxproj" 188 | sed -i "" "s%\DEVELOPMENT_TEAM.*%\ %g" "${projectFile}/project.pbxproj" 189 | fi 190 | 191 | if [[ "$workspaceFile" != "" ]] ; then 192 | #xctoolCmdPrefix="xctool -workspace $workspaceFile -sdk iphonesimulator ARCHS=i386 VALID_ARCHS=i386 CURRENT_ARCH=i386 ONLY_ACTIVE_ARCH=NO" 193 | # 16/12/6 修改: xctool不支持xcode8, 改用xcodebuildbuild 194 | xcodebuildCmdPrefix="xcodebuild -workspace $workspaceFile -scheme ${appScheme} CODE_SIGN_IDENTITY=${codesign} PROVISIONING_PROFILE=${profilename} ONLY_ACTIVE_ARCH=NO -configuration Release " 195 | else 196 | #xctoolCmdPrefix="xctool -project $projectFile -sdk iphonesimulator ARCHS=i386 VALID_ARCHS=i386 CURRENT_ARCH=i386 ONLY_ACTIVE_ARCH=NO" 197 | xcodebuildCmdPrefix="xcodebuild -project $projectFile -scheme ${appScheme} CODE_SIGN_IDENTITY=${codesign} PROVISIONING_PROFILE=${profilename} ONLY_ACTIVE_ARCH=NO -configuration Release" 198 | fi 199 | 200 | 201 | 202 | # Check for mandatory parameters 203 | if [ -z "$projectFile" -o "$projectFile" = " " ]; then 204 | 205 | if [ ! -z "$workspaceFile" -a "$workspaceFile" != " " ]; then 206 | 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." 207 | else 208 | echo >&2 "ERROR - sonar.objectivec.project parameter is missing in sonar-project.properties (name of your .xcodeproj)" 209 | fi 210 | exit 1 211 | fi 212 | if [ -z "$srcDirs" -o "$srcDirs" = " " ]; then 213 | 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)." 214 | exit 1 215 | fi 216 | if [ -z "$appScheme" -o "$appScheme" = " " ]; then 217 | echo >&2 "ERROR - sonar.objectivec.appScheme parameter is missing in sonar-project.properties. You must specify which scheme is used to build your application." 218 | exit 1 219 | fi 220 | 221 | 222 | 223 | ## SCRIPT 224 | 225 | # Start progress indicator in the background 226 | if [ "$vflag" = "" -a "$nflag" = "" ]; then 227 | startProgress & 228 | # Save PID 229 | PROGRESS_PID=$! 230 | fi 231 | 232 | # Create sonar-reports/ for reports output 233 | if [[ ! (-d "sonar-reports") && ("$nflag" != "on") ]]; then 234 | if [ "$vflag" = "on" ]; then 235 | echo 'Creating directory sonar-reports/' 236 | fi 237 | mkdir sonar-reports 238 | if [[ $? != 0 ]] ; then 239 | stopProgress 240 | exit $? 241 | fi 242 | fi 243 | 244 | # Extracting project information needed later 245 | echo -n 'Extracting Xcode project information' 246 | #runCommand /dev/stdout $xctoolCmdPrefix -scheme "$appScheme" clean 247 | #runCommand /dev/stdout $xctoolCmdPrefix -scheme "$appScheme" -reporter json-compilation-database:compile_commands.json build 248 | #runCommand /dev/stdout $xcodebuildCmdPrefix clean 249 | 250 | xcodebuild clean 251 | echo "------------codesign: $codesign" 252 | echo "------------profilename: $profilename" 253 | 254 | export LC_ALL="en_US.UTF-8" 255 | 256 | if [[ "$workspaceFile" != "" ]] ; then 257 | xcodebuild -workspace "${workspaceFile}" -scheme "${appScheme}" CODE_SIGN_IDENTITY="${codesign}" PROVISIONING_PROFILE="${profilename}" ONLY_ACTIVE_ARCH=NO -configuration Release build | tee xcodebuild.log | xcpretty -r json-compilation-database --output compile_commands.json 258 | else 259 | xcodebuild -project "${projectFile}" -scheme "${appScheme}" CODE_SIGN_IDENTITY="${codesign}" PROVISIONING_PROFILE="${profilename}" ONLY_ACTIVE_ARCH=NO -configuration Release build | tee xcodebuild.log | xcpretty -r json-compilation-database --output compile_commands.json 260 | fi 261 | 262 | 263 | # Unit tests and coverage 264 | # if [ "$testScheme" = "" ]; then 265 | # echo 'Skipping tests as no test scheme has been provided!' 266 | 267 | # # Put default xml files with no tests and no coverage... 268 | # echo "" > sonar-reports/TEST-report.xml 269 | # echo "" > sonar-reports/coverage.xml 270 | # else 271 | 272 | # echo -n 'Running tests using xctool' 273 | # # runCommand sonar-reports/TEST-report.xml $xctoolCmdPrefix -scheme "$testScheme" -reporter junit GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES test 274 | # # ctf:这个命令出错, 用下面的命令代替 275 | # $xctoolCmdPrefix -scheme "$testScheme" -reporter junit:TEST-report.xml GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES test 276 | 277 | # echo -n 'Computing coverage report' 278 | 279 | # # We do it for every xcodeproject (in case of workspaces) 280 | 281 | # # Extract the path to the .gcno/.gcda coverage files 282 | # echo $projectFile | sed -n 1'p' | tr ',' '\n' > tmpFileRunSonarSh 283 | # while read projectName; do 284 | 285 | # 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) 286 | # if [ "$vflag" = "on" ]; then 287 | # echo 288 | # echo "Path for .gcno/.gcda coverage files is: $coverageFilesPath" 289 | # fi 290 | 291 | # # Build the --exclude flags 292 | # excludedCommandLineFlags="" 293 | # if [ ! -z "$excludedPathsFromCoverage" -a "$excludedPathsFromCoverage" != " " ]; then 294 | # echo $excludedPathsFromCoverage | sed -n 1'p' | tr ',' '\n' > tmpFileRunSonarSh2 295 | # while read word; do 296 | # excludedCommandLineFlags+=" --exclude $word" 297 | # done < tmpFileRunSonarSh2 298 | # rm -rf tmpFileRunSonarSh2 299 | # fi 300 | # if [ "$vflag" = "on" ]; then 301 | # echo "Command line exclusion flags for gcovr is:$excludedCommandLineFlags" 302 | # fi 303 | 304 | # # Run gcovr with the right options 305 | # echo "coverageFilesPath is: $coverageFilesPath" 306 | # echo "excludedCommandLineFlags is: $excludedCommandLineFlags" 307 | # runCommand "sonar-reports/coverage-${projectName%%.*}.xml" gcovr -r . "$coverageFilesPath" $excludedCommandLineFlags --xml 308 | 309 | # done < tmpFileRunSonarSh 310 | # rm -rf tmpFileRunSonarSh 311 | 312 | # fi 313 | 314 | if [ "$oclint" = "on" ]; then 315 | 316 | # OCLint 317 | echo -n 'Running OCLint...' 318 | 319 | # Build the --include flags 320 | currentDirectory=${PWD##*/} 321 | includedCommandLineFlags="" 322 | echo "$srcDirs" | sed -n 1'p' | tr ',' '\n' > tmpFileRunSonarSh 323 | while read word; do 324 | includedCommandLineFlags+=" --include .*/${currentDirectory}/${word}" 325 | done < tmpFileRunSonarSh 326 | rm -rf tmpFileRunSonarSh 327 | if [ "$vflag" = "on" ]; then 328 | echo 329 | echo -n "Path included in oclint analysis is:$includedCommandLineFlags" 330 | fi 331 | 332 | # Run OCLint with the right set of compiler options 333 | maxPriority=10000 334 | # 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 335 | oclint-json-compilation-database -- -max-priority-1 $maxPriority -max-priority-2 $maxPriority -max-priority-3 $maxPriority -rc LONG_LINE=150 -report-type pmd -o oclint.xml 336 | 337 | else 338 | echo 'Skipping OCLint (test purposes only!)' 339 | fi 340 | 341 | # SonarQube 342 | echo -n 'Running SonarQube using sonar-scanner' 343 | #runCommand /dev/stdout sonar-runner 344 | sonar-scanner 345 | 346 | # Kill progress indicator 347 | stopProgress 348 | 349 | exit 0 350 | -------------------------------------------------------------------------------- /rules-oclint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | bitwise operator in conditional 4 | Bitwise operator in conditional 5 | CRITICAL 6 | Checks for bitwise operations in conditionals. Although being written on purpose in some rare cases, bitwise operations are considered to be too “smart”. Smart code is not easy to understand. 7 | 8 | 9 | broken nil check 10 | Broken nil check 11 | CRITICAL 12 | The broken nil check in Objective-C in some cases returns just the opposite result. 13 | 14 | 15 | broken null check 16 | Broken null check 17 | CRITICAL 18 | The broken null check itself will crash the program. 19 | 20 | 21 | broken oddness check 22 | Broken oddness check 23 | CRITICAL 24 | Checking oddness by x%2==1 won’t work for negative numbers. Use x&1==1, or x%2!=0 instead. 25 | 26 | 27 | collapsible if statements 28 | Collapsible if statements 29 | CRITICAL 30 | This rule detects instances where the conditions of two consecutive if statements can combined into one in order to increase code cleanness and readability. 31 | 32 | 33 | constant conditional operator 34 | Constant conditional operator 35 | CRITICAL 36 | conditionaloperator whose conditionals are always true or always false are confusing. 37 | 38 | 39 | constant if expression 40 | Constant if expression 41 | CRITICAL 42 | if statements whose conditionals are always true or always false are confusing. 43 | 44 | 45 | dead code 46 | Dead code 47 | CRITICAL 48 | Code after return, break, continue, and throw statements are unreachable and will never be executed. 49 | 50 | 51 | double negative 52 | Double negative 53 | CRITICAL 54 | There is no point in using a double negative, it is always positive. 55 | 56 | 57 | for loop should be while loop 58 | For loop should be while loop 59 | CRITICAL 60 | Under certain circumstances, some for loops can be simplified to while loops to make code more concise. 61 | 62 | 63 | goto statement 64 | Goto statement 65 | CRITICAL 66 | “Go To Statement Considered Harmful” 67 | 68 | 69 | misplaced nil check 70 | Misplaced nil check 71 | CRITICAL 72 | The nil check is misplaced. In Objective-C, sending a message to a nil pointer simply does nothing. But code readers may be confused about the misplaced nil check. 73 | 74 | 75 | misplaced null check 76 | Misplaced null check 77 | CRITICAL 78 | The null check is misplaced. In C and C++, sending a message to a null pointer could crash the app. When null is misplaced, either the check is useless or it’s incorrect. 79 | 80 | 81 | multiple unary operator 82 | Multiple unary operator 83 | CRITICAL 84 | Multiple unary operator can always be confusing and should be simplified. 85 | 86 | 87 | return from finally block 88 | Return from finally block 89 | CRITICAL 90 | Returning from a finally block is not recommended. 91 | 92 | 93 | throw exception from finally block 94 | Throw exception from finally block 95 | CRITICAL 96 | Throwing exceptions within a finally block may mask other exceptions or code defects. 97 | 98 | 99 | avoid branching statement as last in loop 100 | Avoid branching statement as last in loop 101 | MAJOR 102 | Having branching statement as the last statement inside a loop is very confusing, and could largely be forgetting of something and turning into a bug. 103 | 104 | 105 | default label not last in switch statement 106 | Default label not last in switch statement 107 | MAJOR 108 | It is very confusing when default label is not the last label in a switch statement. 109 | 110 | 111 | inverted logic 112 | Inverted logic 113 | MAJOR 114 | An inverted logic is hard to understand. 115 | 116 | 117 | non case label in switch statement 118 | Non case label in switch statement 119 | MAJOR 120 | It is very confusing when default label is not the last label in a switch statement. 121 | 122 | 123 | parameter reassignment 124 | Parameter reassignment 125 | MAJOR 126 | Reassigning values to parameters is very problematic in most cases. 127 | 128 | 129 | switch statements should have default 130 | Switch statements should have default 131 | MAJOR 132 | Switch statements should a default statement. 133 | 134 | 135 | too few branches in switch statement 136 | Too few branches in switch statement 137 | MAJOR 138 | To increase code readability, when a switch consists of only a few branches, it’s much better to use if statement. 139 | 140 | 141 | empty catch statement 142 | Empty catch statement 143 | CRITICAL 144 | This rule detects instances where an exception is caught, but nothing is done about it. 145 | 146 | 147 | empty do/while statement 148 | Empty do while statement 149 | CRITICAL 150 | This rule detects instances where a do-while statement does nothing. 151 | 152 | 153 | empty else block 154 | Empty else block 155 | CRITICAL 156 | This rule detects instances where a else statement does nothing. 157 | 158 | 159 | empty finally statement 160 | Empty finally statement 161 | CRITICAL 162 | This rule detects instances where a finally statement does nothing. 163 | 164 | 165 | empty for statement 166 | Empty for statement 167 | CRITICAL 168 | This rule detects instances where a for statement does nothing. 169 | 170 | 171 | empty if statement 172 | Empty if statement 173 | CRITICAL 174 | This rule detects instances where a condition is checked, but nothing is done about it. 175 | 176 | 177 | empty switch statement 178 | Empty switch statement 179 | CRITICAL 180 | This rule detects instances where a switch statement does nothing. 181 | 182 | 183 | empty try statement 184 | Empty try statement 185 | CRITICAL 186 | This rule detects instances where a try statement is empty. 187 | 188 | 189 | empty while statement 190 | Empty while statement 191 | CRITICAL 192 | This rule detects instances where a while statement does nothing. 193 | 194 | 195 | replace with boxed expression 196 | Obj c boxed expressions 197 | MINOR 198 | This rule locates the places that can be migrated to the new Objective-C literals with boxed expressions. 199 | 200 | 201 | replace with container literal 202 | Obj c container literals 203 | MINOR 204 | This rule locates the places that can be migrated to the new Objective-C literals with container literals. 205 | 206 | 207 | replace with number literal 208 | Obj cns number literals 209 | MINOR 210 | This rule locates the places that can be migrated to the new Objective-C literals with number literals. 211 | 212 | 213 | replace with object subscripting 214 | Obj c object subscripting 215 | MINOR 216 | This rule locates the places that can be migrated to the new Objective-C literals with object subscripting. 217 | 218 | 219 | long variable name 220 | Long variable name 221 | MAJOR 222 | Variables with long names harm readability. 223 | 224 | 225 | short variable name 226 | Short variable name 227 | MAJOR 228 | Variable with a short name is hard to understand what it stands for. Variable with name, but the name has number of characters less than the threshold will be emitted. 229 | 230 | 231 | redundant conditional operator 232 | Redundant conditional operator 233 | MINOR 234 | This rule detects three types of redundant conditional operators: 235 | 236 | 237 | redundant if statement 238 | Redundant if statement 239 | MINOR 240 | This rule detects unnecessary if statements. 241 | 242 | 243 | redundant local variable 244 | Redundant local variable 245 | MINOR 246 | This rule detects cases where a variable declaration immediately followed by a return of that variable. 247 | 248 | 249 | redundant nil check 250 | Redundant nil check 251 | MINOR 252 | C/C++-style null check in Objective-C like foo!=nil&&[foobar] is redundant, since sending a message to a nil object in this case simply return a false-y value. 253 | 254 | 255 | unnecessary else statement 256 | Unnecessary else statement 257 | MINOR 258 | When an if statement block ends with a return statement, or all branches in the if statement block end with return statements, then the else statement is unnecessary. The code in the else statement can be run without being in the block. 259 | 260 | 261 | useless parentheses 262 | Useless parentheses 263 | MINOR 264 | This rule detects useless parentheses. 265 | 266 | 267 | high cyclomatic complexity 268 | Cyclomatic complexity 269 | CRITICAL 270 | Cyclomatic complexity is determined by the number of linearly independent paths through a program’s source code. In other words, cyclomatic complexity of a method is measured by the number of decision points, like if, while, and for statements, plus one for the method entry. 271 | 272 | 273 | long class 274 | Long class 275 | MAJOR 276 | Long class generally indicates that this class tries to so many things. Each class should do one thing and one thing well. 277 | 278 | 279 | long line 280 | Long line 281 | MINOR 282 | When number of characters for one line of code is very long, it largely harm the readability. Break long line of code into multiple lines. 283 | 284 | 285 | long method 286 | Long method 287 | MAJOR 288 | Long method generally indicates that this method tries to so many things. Each method should do one thing and one thing well. 289 | 290 | 291 | high ncss method 292 | Ncss method count 293 | CRITICAL 294 | This rule counts number of lines for a method by counting Non Commenting Source Statements (NCSS). NCSS only takes actual statements into consideration, in other words, ignores empty statements, empty blocks, closing brackets or semicolons after closing brackets. Meanwhile, statement that is break into multiple lines contribute only one count. 295 | 296 | 297 | deep nested block 298 | Nested block depth 299 | CRITICAL 300 | This rule indicates blocks nested more deeply than the upper limit. 301 | 302 | 303 | high npath complexity 304 | N path complexity 305 | CRITICAL 306 | NPath complexity is determined by the number of execution paths through that method. Compared to cyclomatic complexity, NPath complexity has two outstanding characteristics: first, it distinguish between different kinds of control flow structures; second, it takes the various type of acyclic paths in a flow graph into consideration. 307 | 308 | 309 | too many fields 310 | Too many fields 311 | CRITICAL 312 | A class with too many fields indicates it does too many things and is lack of proper abstraction. It can be resigned to have fewer fields. 313 | 314 | 315 | too many methods 316 | Too many methods 317 | CRITICAL 318 | A class with too many methods indicates it does too many things and hard to read and understand. It usually contains complicated code, and should be refactored. 319 | 320 | 321 | too many parameters 322 | Too many parameters 323 | CRITICAL 324 | Methods with too many parameters are hard to understand and maintain, and are thirsty for refactorings, like Replace Parameter With method, Introduce Parameter Object, or Preserve Whole Object. 325 | 326 | 327 | unused local variable 328 | Unused local variable 329 | INFO 330 | This rule detects local variables that are declared, but not used. 331 | 332 | 333 | unused method parameter 334 | Unused method parameter 335 | INFO 336 | This rule detects parameters that are not used in the method. 337 | 338 | 339 | feature envy 340 | Feature envy 341 | CRITICAL 342 | Feature envy 343 | 344 | 345 | ivar assignment outside accessors or init 346 | Ivar assignment outside accessors or init 347 | MAJOR 348 | Ivar assignment outside accessors or init 349 | 350 | 351 | jumbled incrementer 352 | Jumbled incrementer 353 | MAJOR 354 | Jumbled incrementer 355 | 356 | 357 | missing break in switch statement 358 | Missing break in switch statement 359 | MAJOR 360 | Missing break in switch statement 361 | 362 | 363 | must override hash with isEqual 364 | Must override hash with isEqual 365 | MINOR 366 | Must override hash with isEqual 367 | 368 | 369 | switch statements don't need default when fully covered 370 | Switch statements don't need default when fully covered 371 | MAJOR 372 | Switch statements don't need default when fully covered 373 | 374 | 375 | use early exits and continue 376 | Use early exits and continue 377 | MAJOR 378 | Use early exits and continue 379 | 380 | 381 | 382 | 383 | 384 | missing hash method 385 | ObjC Verify Is Equal Hash 386 | INFO 387 | When ``isEqual`` method is overridden, ``hash`` method must be overridden, too. 388 | 389 | 390 | missing call to base method 391 | ObjC Verify Must Call Super 392 | INFO 393 | "When a method is declared with " 394 | "``__attribute__((annotate(\"oclint:enforce[base method]\")))`` annotation, " 395 | "all of its implementations (including its own and its sub classes) " 396 | "must call the method implementation in super class." 397 | 398 | 399 | missing abstract method implementation 400 | ObjC Verify Subclass Must Implement 401 | INFO 402 | "Due to the Objective-C language tries to postpone the decision makings " 403 | "to the runtime as much as possible, an abstract method is okay to be declared " 404 | "but without implementations. This rule tries to verify the subclass implement " 405 | "the correct abstract method." 406 | 407 | 408 | calling prohibited method 409 | ObjC Verify Prohibited Call 410 | INFO 411 | "When a method is declared with " 412 | "``__attribute__((annotate(\"oclint:enforce[prohibited method]\")))`` " 413 | "annotation, all of its usages will be prohibited." 414 | 415 | 416 | calling protected method 417 | ObjC Verify Protected Method 418 | INFO 419 | "Even though there is no ``protected`` in Objective-C language level, " 420 | "in a design's perspective, we sometimes hope to enforce a method only be used inside " 421 | "the class itself or by its subclass. This rule mimics the ``protected`` behavior, " 422 | "and alerts developers when a method is called outside its access scope." 423 | 424 | 425 | base class destructor should be virtual or protected 426 | Base Class Destructor Should BeVirtual Or Protected 427 | CRITICAL 428 | Make base class destructor public and virtual, or protected and nonvirtual 429 | 430 | 431 | destructor of virtual class 432 | Destructor Of Virtual Class 433 | CRITICAL 434 | This rule enforces the destructor of a virtual class must be virtual. 435 | 436 | 437 | prefer early exits and continue 438 | Prefer Early Exit 439 | MAJOR 440 | "Early exits can reduce the indentation of a block of code, " 441 | "so that reader do not have to remember all the previous decisions, " 442 | "therefore, makes it easier to understand the code." 443 | 444 | 445 | 446 | unnecessary default statement in covered switch statement 447 | Covered Switch Statements Dont Need Default 448 | MAJOR 449 | "When a switch statement covers all possible cases, " 450 | "a default label is not needed and should be removed. " 451 | "If the switch is not fully covered, " 452 | "the SwitchStatementsShouldHaveDefault rule will report." 453 | 454 | 455 | avoid default arguments on virtual methods 456 | Avoid Default Arguments On Virtual Methods 457 | MAJOR 458 | "Giving virtual functions default argument initializers tends to " 459 | "defeat polymorphism and introduce unnecessary complexity into a class hierarchy." 460 | 461 | 462 | avoid private static members 463 | Avoid Private Static Members 464 | MAJOR 465 | Having static members is easier to harm encapsulation. 466 | 467 | 468 | use boxed expression 469 | ObjC Boxed Expressions 470 | MAJOR 471 | "This rule locates the places that can be migrated to the " 472 | "new Objective-C literals with boxed expressions." 473 | 474 | 475 | 476 | 477 | use container literal 478 | ObjC Container Literals 479 | MAJOR 480 | "This rule locates the places that can be migrated to the " 481 | "new Objective-C literals with container literals." 482 | 483 | 484 | use number literal 485 | ObjC NSNumber Literals 486 | MAJOR 487 | "This rule locates the places that can be migrated to the " 488 | "new Objective-C literals with number literals." 489 | 490 | 491 | use object subscripting 492 | ObjC Object Subscripting 493 | MAJOR 494 | "This rule locates the places that can be migrated to the " 495 | "new Objective-C literals with object subscripting." 496 | 497 | 498 | unnecessary null check for dealloc 499 | Unnecessary Null Check For CXX Dealloc 500 | MAJOR 501 | "``char* p = 0; delete p;`` is valid. " 502 | "This rule locates unnecessary ``if (p)`` checks." 503 | 504 | 505 | missing default in switch statements 506 | Switch Statements Should Have Default Rule 507 | MAJOR 508 | Switch statements should have a default statement. 509 | 510 | 511 | ill-placed default label in switch statement 512 | Switch Statements Misplaced Default Label 513 | MAJOR 514 | Switch Statements Misplaced Default Label. 515 | 516 | 517 | 518 | 519 | --------------------------------------------------------------------------------