-
Notifications
You must be signed in to change notification settings - Fork 4
/
xchelper.sh
275 lines (231 loc) · 6.44 KB
/
xchelper.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
#!/bin/bash
VERSION=0.0.1
ACTIONS=(install run test xcodeproj-schemes swiftlint pod-lib-lint pod-trunk-deploy)
usage() {
cat <<EOF
Usage: A tool for iOS developers to automate tedious tasks like install, run, test.
SYNOPSIS:
xchelper [action ...] [-w] [Build workspace path option]
Actions:
install
Install project dependencies
run
Install project dependencies, and open workspace.
test
Test a scheme from the build root (SYMROOT). This requires specifying a scheme and optionally a destination.
xcodeproj-schemes
To list all available schemes for the project in your current directory.
pod-lib-lint
Validates a Pod.
pod-trunk-deploy
Publish a podspec.
Parameters:
--workspace | -w
Build the workspace name.xcworkspace.
--destination | -d
Use the destination device described by destinationspecifier. Defaults to a destination that is compatible with the
selected scheme. See the Destinations section below for more details.
--scheme | -s
Build the scheme specified by schemename.
Options:
--help | -h
Print complete usage.
--version | -v
Print version info.
LICENSE MIT
Copyright (c) 2021 qiuzhifei <[email protected]>. All rights reserved.
EOF
exit 0
}
version() {
echo "xchelper version ${VERSION}"
exit 0
}
# Color
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
function sh() {
printf "${GREEN}$ $@${NC}\n"
$@
}
function logger_cmd() {
printf "${GREEN}$@${NC}\n"
}
function warning() {
printf "${YELLOW}warning: $@${NC}\n"
}
function info() {
echo "info: $@"
}
function setup_xcodeproj() {
XCODE_DERIVED_DATA_PATH=$PWD/build
get_xcode_destination
get_xcodeproj_workspace
}
function install_project_dependencies() {
get_gemfile_directory
if [ $XCODE_GEMFILE_DIRECTORY ]; then
sh bundle install --verbose
sh bundle exec rake
return
fi
get_podfile_directory
sh pod install --project-directory=${XCODE_PROFILE_DIRECTORY} --verbose
}
function get_xcode_destination() {
if [ -z $XCODE_DESTINATION ]; then
local device_name=`xcrun xctrace list devices 2>&1 | grep -oE 'iPhone.*?[^\(]+' | head -1 | awk '{$1=$1;print}'`
XCODE_DESTINATION="platform=iOS Simulator,name=$device_name"
fi
}
function get_xcodeproj_workspace() {
if [ -z $XCODE_WORKSPACE ]; then
workspaces=($(find $PWD/ -name "*.xcworkspace" | awk '{print length($0), $0}' | sort -n | awk '{print $2}'))
XCODE_WORKSPACE=${workspaces[0]}
fi
}
function get_xcodeproj_schemes() {
if [ -z $XCODE_SCHEMES ]; then
XCODE_SCHEMES=($(echo `xcodebuild -workspace $XCODE_WORKSPACE -list -json` | ruby -e "require 'json'; puts JSON.parse(STDIN.gets)['workspace']['schemes']"))
fi
}
function get_xcodeproj_scheme() {
get_xcodeproj_schemes
if [ -z $XCODE_SCHEME ]; then
# pod repo, scheme 是第二个
XCODE_SCHEME=${XCODE_SCHEMES[0]}
fi
}
function get_xcodeproj_xctest_schemes() {
info "get xcodeproj xctest schemes ..."
get_xcodeproj_schemes
for scheme in ${XCODE_SCHEMES[@]}; do
local test_host_list=( $(echo `xcodebuild -workspace $XCODE_WORKSPACE -scheme $scheme -showBuildSettings -json` | ruby -e "require 'json'; puts JSON.parse(STDIN.gets).map { |value| value['buildSettings']['TEST_HOST'] }.reject { |value| value.to_s.empty? }") )
if [ ${#test_host_list[@]} -gt 0 ]; then
if [ -z $XCODE_XCTEST_SCHEMES ]; then
XCODE_XCTEST_SCHEMES=()
XCODE_XCTEST_SCHEMES[${#XCODE_XCTEST_SCHEMES[@]}]=$scheme
fi
fi
done
}
function get_gemfile_directory() {
gemfile_paths=($(find $PWD/ -name Gemfile | awk '{print length($0), $0}' | sort -n | awk '{print $2}'))
# 默认使用查到到的第一个 Gemfile
if [ ${#gemfile_paths[@]} -gt 0 ]; then
gemfile_path=${gemfile_paths[0]}
XCODE_GEMFILE_DIRECTORY=$(dirname ${gemfile_path})
fi
}
function get_podfile_directory() {
podfile_paths=($(find $PWD/ -name Podfile))
# 默认使用查到到的第一个 Podfile
podfile_path=${podfile_paths[0]}
XCODE_PROFILE_DIRECTORY=$(dirname ${podfile_path})
}
function build_for_testing() {
get_xcodeproj_xctest_schemes
if [ ${#XCODE_XCTEST_SCHEMES[@]} -eq 0 ]; then
warning "No such xctest scheme, skipping ..."
exit 0
fi
for scheme in ${XCODE_XCTEST_SCHEMES[@]}; do
sh set -ox pipefail && xcodebuild build-for-testing -workspace $XCODE_WORKSPACE -scheme $scheme -destination "$XCODE_DESTINATION" -derivedDataPath 'build/' | xcpretty
done
}
function test_without_building() {
local xctestrun_files=( $(find $XCODE_DERIVED_DATA_PATH -name *.xctestrun) )
if [ ${#xctestrun_files[@]} -eq 0 ]; then
warning "No such xctest run file, skipping ..."
exit 0
fi
# 默认使用第一个 xctest run file
local xctestrun_file=${xctestrun_files[0]}
sh set -ox pipefail && xcodebuild test-without-building -xctestrun $xctestrun_file -destination "$XCODE_DESTINATION" | xcpretty
}
######################
## Actions
function install() {
install_project_dependencies
}
function run() {
install_project_dependencies
sh open $XCODE_WORKSPACE
}
function test() {
build_for_testing
test_without_building
}
function xcodeproj-schemes() {
get_xcodeproj_schemes
echo ${XCODE_SCHEMES[@]}
}
function swiftlint() {
if which swiftlint >/dev/null; then
if [ -e .swiftlint.yml ]; then
sh command swiftlint lint --strict
else
warning "No such file or directory: '.swiftlint.yml', skipping ..."
fi
else
warning "SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi
}
function pod-lib-lint() {
if [ -e *.podspec ]; then
sh pod lib lint --allow-warnings --verbose
else
warning "No such file or directory: '*.podspec', skipping ..."
fi
}
function pod-trunk-deploy() {
sh pod trunk push *.podspec --allow-warnings --verbose
}
######################
while [ $# != 0 ]; do
case $1 in
--workspace | -w)
XCODE_WORKSPACE=$2
shift 2
;;
--destination | -d)
XCODE_DESTINATION=$2
shift 2
;;
--scheme | -s)
XCODE_SCHEME=$2
shift 2
;;
--help | -h)
usage
shift
;;
--version | -v)
version
shift
;;
*)
if [ -z $ACTION ]; then
if [[ "${ACTIONS[@]}" =~ $1 ]]; then
ACTION=$1
fi
fi
shift
;;
esac
done
######################
if [ -z $ACTION ]; then
usage
exit 1
fi
function main() {
setup_xcodeproj
echo "------------------------"
logger_cmd "Action: ${ACTION} ..."
echo "------------------------"
${ACTION}
}
main