cocoapods-dev-env 2.1.8 → 2.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,406 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cocoapods'
4
+ require 'file_processer'
5
+ require 'luna-binary-uploader'
6
+ require 'dev_env_utils'
7
+
8
+ Pod::HooksManager.register('cocoapods-dev-env', :pre_install) do |installer|
9
+ # puts installer.instance_variables
10
+ # forbidden submodule not cloned
11
+ # 会引起submodule HEAD回滚,不靠谱,先注释掉
12
+ # `
13
+ # git submodule update --init --recursive
14
+ # `
15
+ end
16
+
17
+ Pod::HooksManager.register('cocoapods-dev-env', :post_install) do |installer|
18
+ # puts installer.instance_variables
19
+ end
20
+
21
+
22
+ $processedPodsState = Hash.new
23
+ $processedPodsOptions = Hash.new
24
+
25
+ $podFileContentPodNameHash = Hash.new
26
+
27
+ $devEnvUseBinaryHash = Hash.new
28
+
29
+ # for universal dependency 子库引用父文件夹中的podFile或lock文件的相对路径
30
+ $parrentPath = '../../../'
31
+
32
+
33
+ module Pod
34
+
35
+ class DevEnv
36
+ def self.keyword
37
+ :dev_env # 'dev'/'beta'/'release'
38
+ end
39
+ def self.binary_key
40
+ :dev_env_use_binary # true / false
41
+ end
42
+ UI.puts "🎉 plugin cocoapods-dev-env loaded 🎉".green
43
+ end
44
+ class Podfile
45
+
46
+ class TargetDefinition
47
+ attr_reader :binary_repo_url
48
+ attr_reader :binary_source
49
+
50
+ ## --- hook的入口函数 ---
51
+ def parse_pod_dev_env(name, requirements)
52
+ options = requirements.last
53
+ pod_name = Specification.root_name(name)
54
+ last_options = $processedPodsOptions[pod_name]
55
+ $podFileContentPodNameHash[pod_name] = true
56
+
57
+ if (last_options != nil)
58
+ UI.message "#{name.green} use last_options: #{last_options.to_s.green}"
59
+ if options != nil && options.is_a?(Hash)
60
+ requirements[requirements.length - 1] = last_options
61
+ else
62
+ requirements.push(last_options)
63
+ end
64
+ elsif options.is_a?(Hash)
65
+ use_binary = options.delete(Pod::DevEnv::binary_key)
66
+ dev_env = options.delete(Pod::DevEnv::keyword)
67
+
68
+ # 主功能,根据dev_env标记来管理使用代码的方式
69
+ deal_dev_env_with_options(dev_env, options, pod_name, name, requirements)
70
+
71
+ # 处理二进制
72
+ if dev_env != 'dev'
73
+ binary_processer(dev_env, pod_name, use_binary, options, requirements)
74
+ end
75
+
76
+
77
+ if dev_env || use_binary
78
+ $processedPodsOptions[pod_name] = options.clone
79
+ requirements.pop if options.empty?
80
+ end
81
+ end
82
+ end
83
+
84
+ ## --- 主功能函数 ---
85
+ def deal_dev_env_with_options(dev_env, options, pod_name, name, requirements)
86
+ if dev_env == nil
87
+ return
88
+ end
89
+
90
+ defaultLocalPath = "./developing_pods/#{pod_name}"
91
+ UI.message "pod #{name.green} dev-env: #{dev_env.green}"
92
+ isFromSubProject = false
93
+ if dev_env == 'parent'
94
+ parentPodInfo = $parentPodlockDependencyHash[pod_name]
95
+ if parentPodInfo != nil
96
+ if parentPodInfo.external_source != nil
97
+ git = parentPodInfo.external_source[:git]
98
+ if git != nil
99
+ options[:git] = git
100
+ end
101
+ tag = parentPodInfo.external_source[:tag]
102
+ if tag != nil
103
+ options[:tag] = tag
104
+ end
105
+ elsif (parentPodInfo.podspec_repo.start_with?("http") || parentPodInfo.podspec_repo.start_with?("git"))
106
+ #UI.puts 'XXXXXXXXXXXXXXXX123' + parentPodInfo.inspect
107
+ requirements.insert(0, parentPodInfo.requirement.to_s)
108
+ options[:source] = parentPodInfo.podspec_repo
109
+ end
110
+ end
111
+ return
112
+ elsif options[:git] == nil
113
+ podfilePath = $parrentPath + '/Podfile'
114
+ temp = `grep \\'#{pod_name}\\' #{podfilePath} | grep ':dev_env'`
115
+ if temp != nil && temp.length > 0
116
+ UI.puts temp
117
+ git = /(:git.*?').*?(?=')/.match(temp)[0]
118
+ git = git.gsub(/:git.*?'/, '')
119
+ branch = /(:branch.*?').*?(?=')/.match(temp)[0]
120
+ branch = branch.gsub(/:branch.*?'/, '')
121
+ tag = /(:tag.*?').*?(?=')/.match(temp)[0]
122
+ tag = tag.gsub(/:tag.*?'/, '')
123
+ path = /(:path.*?').*?(?=')/.match(temp)
124
+ if path != nil
125
+ path = path[0]
126
+ path = path.gsub(/:path.*?'/, '')
127
+ end
128
+ options[:git] = git
129
+ options[:branch] = branch
130
+ options[:tag] = tag
131
+ if path != nil
132
+ options[:path] = path
133
+ else
134
+ options[:path] = defaultLocalPath
135
+ end
136
+ UI.puts "#{pod_name.green}采用了父组件的配置,并修改开发状态为#{dev_env.green}"
137
+ isFromSubProject = true
138
+ end
139
+ end
140
+
141
+
142
+
143
+ git = options.delete(:git)
144
+ branch = options.delete(:branch)
145
+ tag = options.delete(:tag)
146
+ path = options.delete(:path) # 执行命令用的path
147
+ if path == nil
148
+ path = defaultLocalPath
149
+ end
150
+ realpath = path
151
+ if isFromSubProject
152
+ realpath = $parrentPath + path
153
+ end
154
+
155
+ if git == nil || git.length == 0
156
+ raise "💔 #{pod_name.yellow} 未定义:git => 'xxx'库地址"
157
+ end
158
+ if branch == nil || branch.length == 0
159
+ raise "💔 #{pod_name.yellow} 未定义:branch => 'xxx'"
160
+ end
161
+ if tag == nil || tag.length == 0
162
+ raise "💔 #{pod_name.yellow} 未定义:tag => 'xxx', tag 将会作为 dev模式下载最新代码检查的依据,beta模式引用的tag 以及 release模式引用的版本号"
163
+ end
164
+
165
+ if dev_env == 'subtree'
166
+ if isFromSubProject
167
+ raise "💔 子项目不支持subtree"
168
+ end
169
+ if !File.directory?(path)
170
+ _toplevelDir = `git rev-parse --show-toplevel`
171
+ _currentDir = `pwd`
172
+ _subtreeDir = path
173
+ if _currentDir != _toplevelDir
174
+ Dir.chdir(_toplevelDir)
175
+ _end = path
176
+ if _end[0,2] == './'
177
+ _end = _end[1, _end.length - 1]
178
+ else
179
+ _end = '/' + _end
180
+ end
181
+ _subtreeDir = './' + _currentDir[_toplevelDir.length, _currentDir.length - _toplevelDir.length] + path
182
+ end
183
+ _cmd = "git subtree add --prefix #{_subtreeDir} #{git} #{branch} --squash"
184
+ UI.puts _cmd
185
+ system(_cmd)
186
+ Dir.chdir(_currentDir)
187
+ end
188
+ options[:path] = realpath
189
+ if requirements.length >= 2
190
+ requirements.delete_at(0)
191
+ end
192
+ UI.message "pod #{pod_name.green} enabled #{"subtree".green}-mode 🍺"
193
+ elsif dev_env == 'dev'
194
+ # 开发模式,使用path方式引用本地的submodule git库
195
+ if !File.directory?(realpath)
196
+ UI.puts "add submodule for #{pod_name.green}".yellow
197
+ curProjectDir = `pwd`
198
+ if isFromSubProject
199
+ # 进入父目录,避免当前工程目录是个submodule,当在submudle中执行addsubmodule时路径会不正确
200
+ Dir.chdir($parrentPath)
201
+ end
202
+ _cmd = "git submodule add --force -b #{branch} #{git} #{path}"
203
+ UI.puts _cmd
204
+ system(_cmd)
205
+ if isFromSubProject
206
+ Dir.chdir(curProjectDir)
207
+ end
208
+ _currentDir = Dir.pwd
209
+ Dir.chdir(path)
210
+
211
+ curGitRemoteUrl = `git remote get-url origin`.rstrip()
212
+ if curGitRemoteUrl == git
213
+ _cmd = "git reset --hard"
214
+ UI.puts _cmd
215
+ system(_cmd)
216
+ _cmd = "git pull"
217
+ UI.puts _cmd
218
+ system(_cmd)
219
+ end
220
+ Dir.chdir(_currentDir)
221
+
222
+ # if DevEnvUtils.inputNeedJumpForReson("本地库#{pod_name} 开发模式加载完成,是否自动打开Example工程")
223
+ # DevEnvUtils.searchAndOpenLocalExample(path)
224
+ # end
225
+ if !DevEnvUtils.checkTagIsEqualToHead(tag, path) && !DevEnvUtils.checkTagIsEqualToHead("#{tag}_beta", path)
226
+ raise "💔 #{pod_name.yellow} branch:#{branch.yellow} 与 tag:#{tag.yellow}[_beta] 内容不同步,请自行确认所用分支和tag后重新执行 pod install"
227
+ end
228
+ else
229
+ # if DevEnvUtils.inputNeedJumpForReson("本地库#{pod_name} 处于开发模式,是否自动打开Example工程")
230
+ # DevEnvUtils.searchAndOpenLocalExample(path)
231
+ # end
232
+ end
233
+ options[:path] = realpath
234
+ if requirements.length >= 2
235
+ requirements.delete_at(0)
236
+ end
237
+ UI.message "pod #{pod_name.green} enabled #{"dev".green}-mode 🍺"
238
+ elsif dev_env == 'beta'
239
+ # Beta模式,使用tag引用远端git库的代码
240
+ originTag = tag
241
+ tag = "#{tag}_beta"
242
+ if File.directory?(path)
243
+ # 从Dev模式刚刚切换过来,需要打tag并且push
244
+ UI.puts "try to release beta-version for #{pod_name.green}".yellow
245
+ _currentDir = Dir.pwd
246
+ Dir.chdir(path)
247
+ # 已经进入到podspec的文件夹中了
248
+ DevEnvUtils.checkGitStatusAndPush(pod_name) # push一下
249
+ isRemoteTagExist = DevEnvUtils.checkRemoteTagExist(tag)
250
+ if isRemoteTagExist == true
251
+ # tag已经存在,要么没改动,要么已经手动打过tag,要么是需要引用老版本tag的代码
252
+ if DevEnvUtils.checkTagOrBranchIsEqalToHead(tag, "./")
253
+ UI.puts "#{pod_name.green} 检测到未做任何调整,或已手动打过Tag,直接引用远端库"
254
+ else
255
+ if !DevEnvUtils.inputNeedJumpForReson("#{pod_name.green} 检测到已经存在#{tag.yellow}的tag,且与当前本地节点不同,是否跳过beta发布并删除本地submodule(直接引用远端库)")
256
+ raise "💔 #{pod_name.yellow} tag:#{tag.yellow} 已存在, 且与当前Commit不对应. 请确认拉到本地之后已经在podfile中手动修改tag版本号"
257
+ end
258
+ end
259
+ else
260
+ # tag不存在,
261
+ DevEnvUtils.checkIsOnTrankBrach()
262
+ DevEnvUtils.changeVersionInCocoapods(pod_name, originTag)
263
+ DevEnvUtils.checkGitStatusAndPush(pod_name) # 再push一下
264
+ DevEnvUtils.addGitTagAndPush(tag, pod_name)
265
+ end
266
+ Dir.chdir(_currentDir)
267
+ DevEnvUtils.checkAndRemoveSubmodule(path)
268
+ if !isRemoteTagExist
269
+ UI.puts "🍺🍺 #{pod_name.green} #{tag.green} release successfully!!"
270
+ end
271
+ end
272
+ options[:git] = git
273
+ options[:tag] = tag
274
+ if requirements.length >= 2
275
+ requirements.delete_at(0)
276
+ end
277
+ UI.message "enabled #{"beta".green}-mode for #{pod_name.green}"
278
+ elsif dev_env == 'release'
279
+ # Release模式,直接使用远端对应的版本
280
+ if File.directory?(path)
281
+ UI.puts "release release-version for #{pod_name.green}".yellow
282
+ _currentDir = Dir.pwd
283
+ Dir.chdir(path)
284
+ verboseParamStr = ""
285
+ if Config.instance.verbose
286
+ verboseParamStr = " --verbose"
287
+ end
288
+ ret = system("pod lib lint --skip-import-validation --fail-fast --allow-warnings#{getReposStrForLint()}#{verboseParamStr}")
289
+ if ret != true
290
+ raise "💔 #{pod_name.yellow} lint 失败"
291
+ end
292
+ DevEnvUtils.checkGitStatusAndPush(pod_name)
293
+ DevEnvUtils.changeVersionInCocoapods(pod_name, tag)
294
+ DevEnvUtils.checkGitStatusAndPush(pod_name)
295
+ ret = DevEnvUtils.addGitTagAndPush(tag, pod_name)
296
+ if ret == false
297
+ if DevEnvUtils.checkTagOrBranchIsEqalToHead(tag, "./")
298
+ UI.puts "#{pod_name.green} 已经打过tag".yellow
299
+ else
300
+ raise "💔 #{pod_name.yellow} tag:#{tag.yellow} 已存在, 请确认已经手动修改tag版本号"
301
+ end
302
+ end
303
+ ## TODO:: 发布到的目标库名称需要用变量设置
304
+ repoAddrs = getUserRepoAddress()
305
+ cmd = "pod repo push #{repoAddrs} #{pod_name}.podspec --skip-import-validation --allow-warnings --use-modular-headers#{getReposStrForLint()}#{verboseParamStr}"
306
+ UI.puts cmd.green
307
+ ret = system(cmd)
308
+ if ret != true
309
+ raise "💔 #{pod_name.yellow} 发布失败"
310
+ end
311
+ ## 到最后统一执行,判断如果当次release过
312
+ `pod repo update`
313
+ Dir.chdir(_currentDir)
314
+ DevEnvUtils.checkAndRemoveSubmodule(path)
315
+ end
316
+ if requirements.length < 2
317
+ requirements.insert(0, "#{DevEnvUtils.get_pure_version(tag)}")
318
+ end
319
+ UI.message "enabled #{"release".green}-mode for #{pod_name.green}"
320
+ else
321
+ raise "💔 :dev_env 必须要设置成 dev/beta/release之一,不接受其他值"
322
+ end
323
+ end
324
+
325
+ def binary_processer(dev_env, pod_name, use_binary, options, requirements)
326
+ if use_binary && use_binary == true
327
+ if options[:tag] != nil
328
+ begin
329
+ version = DevEnvUtils.get_pure_version(options[:tag])
330
+ spec = binary_source.specification_path(pod_name, Version.new(version))
331
+ if spec
332
+ if requirements.length < 2
333
+ options.delete(:git)
334
+ options.delete(:path)
335
+ options.delete(:tag)
336
+ options[:source] = binary_repo_url
337
+ requirements.insert(0, "#{version}")
338
+ UI.puts "pod '#{pod_name.green}' 使用了二进制"
339
+ else
340
+ UI.puts "pod '#{pod_name}' :tag => #{options[:tag]} version: #{version} 对应的版本,但是已经标记版本号#{requirements}, 不知道用哪个".red
341
+ end
342
+ else
343
+ UI.puts "pod '#{pod_name}' :tag => #{options[:tag]} version: #{version} 没有找到: tag 对应的版本".red
344
+ end
345
+ rescue => exception
346
+ UI.puts "pod '#{pod_name}' :tag => #{options[:tag]} version: #{version} 没有找到: tag 对应的版本".red
347
+ else
348
+
349
+ end
350
+ else
351
+ UI.puts "pod '#{pod_name.green}使用了二进制"
352
+ ## TODO:: 这里不适合处理,在这里处理的时候还不知道最终的版本号,
353
+ ## 无法拿到准确的版本,就不能确定二进制库里是否有对应的framework
354
+ ## 或者在这边预处理后,在后边的reslove的过程中找不到时再拯救一下??
355
+ options.delete(:git)
356
+ options.delete(:path)
357
+ options.delete(:tag)
358
+ options[:source] = binary_repo_url
359
+ end
360
+ end
361
+ UI.message "#{pod_name.green} :source=> #{options[:source].green} by cocoapods-dev-env" if options[:source] != nil
362
+ UI.message "#{pod_name.yellow} options #{options} by cocoapods-dev-env" if options[:source] != nil
363
+ UI.message "#{pod_name.yellow} requirements #{requirements} by cocoapods-dev-env" if options[:source] != nil
364
+ end
365
+
366
+ def binary_repo_url
367
+ if @binary_repo_url == nil
368
+ @binary_repo_url = Luna::Binary::Common.instance.binary_repo_url #从luna-binary-uploader里获取binary_repo_url
369
+ end
370
+ return @binary_repo_url
371
+ end
372
+
373
+ def binary_source
374
+ if @binary_source == nil
375
+ @binary_source = Pod::Config.instance.sources_manager.all.detect{|item| item.url.downcase == binary_repo_url.downcase}
376
+ end
377
+ return @binary_source
378
+ end
379
+
380
+ def find_pod_repos(pod_name) #等同pod search
381
+ sets = Pod::Config.instance.sources_manager.search_by_name(pod_name)
382
+ if sets.count == 1
383
+ set = sets.first
384
+ elsif sets.map(&:name).include?(pod_name)
385
+ set = sets.find { |s| s.name == pod_name }
386
+ else
387
+ names = sets.map(&:name) * ', '
388
+ raise Informative, "More than one spec found for '#{pod_name}':\n#{names}"
389
+ end
390
+ return set
391
+ end
392
+
393
+ # ---- patch method ----
394
+ # We want modify `store_pod` method, but it's hard to insert a line in the
395
+ # implementation. So we patch a method called in `store_pod`.
396
+ old_method = instance_method(:parse_inhibit_warnings)
397
+
398
+ define_method(:parse_inhibit_warnings) do |name, requirements|
399
+ parse_pod_dev_env(name, requirements)
400
+ old_method.bind(self).(name, requirements)
401
+ end
402
+
403
+ end
404
+ end
405
+ end
406
+
@@ -0,0 +1,169 @@
1
+ require 'cocoapods'
2
+
3
+ class DevEnvUtils
4
+ def self.searchAndOpenLocalExample(path)
5
+ _currentDir = Dir.pwd
6
+ Dir.chdir(path)
7
+ Dir.chdir('Example')
8
+ `pod install`
9
+ projPaths = Dir.glob('*.xcworkspace')
10
+ if projPaths.count > 0
11
+ `open -a Terminal ./`
12
+ `open #{projPaths[0]}`
13
+ end
14
+ Dir.chdir(_currentDir)
15
+ end
16
+
17
+ def self.checkAndRemoveSubmodule(path)
18
+ _currentDir = Dir.pwd
19
+ Dir.chdir(path)
20
+ output = `git status -s`
21
+ puts output
22
+ if output.length == 0
23
+ output = `git status`
24
+ raise "submodule #{path} 移除失败,有推送的修改" if output.include?('push')
25
+ else
26
+ raise "submodule #{path} 移除失败,有未提交的修改"
27
+ end
28
+ Dir.chdir(_currentDir)
29
+ `
30
+ git submodule deinit #{path}
31
+ rm -rf #{path}
32
+ git rm #{path}
33
+ `
34
+ end
35
+
36
+ def self.checkTagIsEqualToHead(tag, path)
37
+ _currentDir = Dir.pwd
38
+ Dir.chdir(path)
39
+ result = `git describe --abbrev=4 HEAD`
40
+ Dir.chdir(_currentDir)
41
+ if result.include?(tag)
42
+ true
43
+ else
44
+ checkTagOrBranchIsEqalToHead(tag, path)
45
+ end
46
+ end
47
+
48
+ # 这个函数有问题有时候拿不到相同的commit id
49
+ def self.checkTagOrBranchIsEqalToHead(branchOrTag, path)
50
+ _currentDir = Dir.pwd
51
+ Dir.chdir(path)
52
+ headCommitID = `git rev-parse HEAD`
53
+ tagCommitID = `git rev-parse #{branchOrTag}`
54
+ Pod::UI.puts "#{`pwd`} headCommitID:#{headCommitID} \n #{branchOrTag}ComitID:#{tagCommitID}"
55
+ Dir.chdir(_currentDir)
56
+ (headCommitID.length > 0 && headCommitID == tagCommitID)
57
+ end
58
+
59
+ def self.checkGitStatusAndPush(pod_name)
60
+ output = `git status -s`
61
+ puts output
62
+ if output.length == 0
63
+ output = `git status`
64
+ if output.include?('push')
65
+ ret = system('git push')
66
+ raise "💔 #{pod_name.yellow} push 失败" if ret != true
67
+ end
68
+ else
69
+ raise "💔 #{pod_name.yellow} 有未提交的数据"
70
+ end
71
+ end
72
+
73
+ def self.checkRemoteTagExist(tag)
74
+ `git push --tags`
75
+ system("git ls-remote --exit-code origin refs/tags/#{tag}")
76
+ end
77
+
78
+ def self.addGitTagAndPush(tag, pod_name)
79
+ ret = system("git tag #{tag}")
80
+ if ret == true
81
+ ret = system("git push origin #{tag}")
82
+ raise "💔 #{pod_name.yellow} push tag 失败" if ret != true
83
+ end
84
+ ret
85
+ end
86
+
87
+ def self.inputNeedJumpForReson(str)
88
+ return false if ARGV.include? '--silent'
89
+
90
+ puts str.green
91
+ puts '是(Y), 任意其他输入或直接回车跳过'.green
92
+ input = STDIN.gets
93
+ input[0, 1] == 'Y'
94
+ end
95
+
96
+ # 检查是否在主分支上(main / master)
97
+ def self.checkIsOnTrankBrach()
98
+ branch = `git branch --show-current`.chomp
99
+ isOK = (branch == 'main' || branch == 'master')
100
+ if !isOK
101
+ puts ('💔 当前分支是: '.red + branch.green + ' 没在主分支,不符合规范,是否继续发布?'.red)
102
+ if !inputNeedJumpForReson("")
103
+ raise "已取消发布, 请切换子库分支到 master / main 后重新 pod install"
104
+ end
105
+ end
106
+ end
107
+
108
+ def self.changeVersionInCocoapods(name, newVersion)
109
+ if newVersion.nil?
110
+ Pod::UI.puts '💔 传入的修改目标版本号为空,无法设置版本号'.yellow
111
+ return
112
+ end
113
+ newVersion = get_pure_version(newVersion)
114
+ specName = name + '.podspec'
115
+ FileProcesserManager.new(specName,
116
+ [
117
+ FileProcesser.new(lambda { |fileContent|
118
+ return fileContent.gsub(/(\.version *= *')(.*')/,
119
+ '\\1' + newVersion + "'")
120
+ }),
121
+ FileProcesser.new(lambda { |fileContent|
122
+ return fileContent.gsub(/(\.version *= *")(.*")/,
123
+ '\\1' + newVersion + '"')
124
+ })
125
+ ]).process
126
+ `git add #{specName}
127
+ git commit -m "Mod: 修改版本号为:#{newVersion} by cocoapods_dev_env plugin"`
128
+ end
129
+
130
+ def self.get_pure_version(version)
131
+ version.split.last.scan(/\d+/).join('.')
132
+ end
133
+ end
134
+
135
+ module Pod
136
+ class Podfile
137
+ class TargetDefinition
138
+ def getReposStrForLint
139
+ return '' if podfile.sources.size == 0
140
+
141
+ str = ' --sources='
142
+ podfile.sources.each do |source|
143
+ str += source
144
+ str += ','
145
+ end
146
+ Pod::UI.puts str
147
+ str
148
+ end
149
+
150
+ def getUserRepoAddress
151
+ raise "💔 发布release必须配置仓库的地址, e.g.: source 'https://github.com/CocoaPods/Specs.git'" if podfile.sources.size == 0
152
+
153
+ index = nil
154
+ begin
155
+ Pod::UI.puts "\n\n⌨️ 请输入要发布到的cocoapods仓库序号, 按回车确认: ".yellow
156
+ num = 1
157
+ podfile.sources.each do |source|
158
+ Pod::UI.puts "#{num.to_s.yellow}. #{source.green}"
159
+ num += 1
160
+ end
161
+ index = STDIN.gets.to_i - 1
162
+ end until (index >= 0 && index < podfile.sources.size)
163
+ source = podfile.sources[index]
164
+ Pod::UI.puts "#{'选择了发布到: '.yellow}. #{source.green}(#{index + 1})"
165
+ source
166
+ end
167
+ end
168
+ end
169
+ end