cocoapods-ybin 0.0.1

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,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5f1f6223b5c5c46f4b4d4a8c9e9f719021748aae3d1c82dcb7fad73cac20df87
4
+ data.tar.gz: ec6dd6b52a577f0f0d2678da3bf66865fe6bcd81768101f50d06bf9d9292e2fb
5
+ SHA512:
6
+ metadata.gz: cf8f987c7cf3d67ec46b0cab7f5d1eb14089e725ba3e69bf02d456c78cdf248735729e65600cf49f602f7c26707db596838f6b5d5c3edeb1c7405ec8589c0449
7
+ data.tar.gz: abc5d9345614640b4ca7ca33ef878563efd56f0bd6b893d854450978b4822f73b68af40e46d3f13d8bea983aa934e722d82979e6aa98bafe32e93b6d9c63888e
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2020 monetking <houmanager@qq.com>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,11 @@
1
+ # cocoapods-ybin
2
+
3
+ A description of cocoapods-ybin.
4
+
5
+ ## Installation
6
+
7
+ $ gem install cocoapods-ybin
8
+
9
+ ## Usage
10
+
11
+ $ pod spec ybin POD_NAME
@@ -0,0 +1 @@
1
+ require 'cocoapods-ybin/gem_version'
@@ -0,0 +1 @@
1
+ require 'cocoapods-ybin/command/ybin'
@@ -0,0 +1,10 @@
1
+ require 'cocoapods-ybin/command/ybin/link'
2
+
3
+ module Pod
4
+ class Command
5
+ class Ybin < Command
6
+ self.abstract_command = true
7
+ self.summary = '将二进制库与源码建立映射,实现断点自动跳入对应源码部分进行调试应用程序。作者: houmanager@qq.com'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,437 @@
1
+ module Pod
2
+ class Command
3
+ class Ybin < Command
4
+ class Link < Ybin
5
+
6
+ autoload :Analyzer, 'cocoapods/installer/analyzer'
7
+ self.summary = '二进制库源码映射工具'
8
+
9
+ self.description = <<-DESC
10
+ 二进制库源码映射工具. 作者: houmanager@qq.com
11
+ DESC
12
+
13
+ self.arguments = [
14
+ CLAide::Argument.new('NAME', false)
15
+ ]
16
+ def self.options
17
+ [
18
+ ['--list', '查询所有已映射源码库'],
19
+ ['--remove', '删除源码映射(多个空格隔开)'],
20
+ ['--remove-all', '删除所有源码映射'],
21
+ ['--lib-version', '查询 Podfile 所有依赖库的版本']
22
+ ]
23
+ end
24
+
25
+ def initialize(argv)
26
+ # @name = argv.shift_argument
27
+
28
+ @names = argv.arguments! unless argv.arguments.empty?
29
+ @list = argv.flag?('list', false)
30
+ @link = argv.flag?('link', false)
31
+ @remove = argv.flag?('remove', false)
32
+ @remove_all = argv.flag?('remove-all', false)
33
+ @lib_version = argv.flag?('lib-version', false)
34
+
35
+ @config = Pod::Config.instance
36
+ super
37
+ end
38
+
39
+ def validate!
40
+ super
41
+ # help! 'A Pod option is required.' unless @name
42
+ banner! if @help
43
+ end
44
+
45
+ def run
46
+
47
+ if @link && @list && @remove && @remove_all && @lib_version
48
+ UI.puts "[Error] 请选择合适的命令, 不支持同时多个Option\n".red
49
+ help!
50
+ return
51
+ end
52
+
53
+ if @list
54
+ analyzerPodFileLock
55
+ linked_list
56
+ elsif @remove
57
+ analyzerPodFileLock
58
+ linked_remove
59
+ elsif @remove_all
60
+ analyzerPodFileLock
61
+ linked_remove_all
62
+ elsif @lib_version
63
+ analyzerPodFileLock
64
+ read_podfile_lock_version
65
+ elsif @names
66
+ analyzerPodFileLock
67
+ linkLibSource
68
+ else
69
+ help!
70
+ end
71
+ end
72
+
73
+ # 映射源码
74
+ def linkLibSource
75
+
76
+ if @names.nil?
77
+ UI.puts "[Error] 请输入需要映射的组件库. 示例: $ pod ybin foo\n".red
78
+ return
79
+ else
80
+ if @names.count > 1
81
+ UI.puts "[Error] 不支持一次映射多个源码. 示例: $ pod ybin foo\n".red
82
+ return
83
+ end
84
+ end
85
+
86
+ user_lib_name = @names.first.chomp.strip
87
+ lib_version = get_lib_version(user_lib_name)
88
+ if lib_version == nil || lib_version == ""
89
+ print "\n[!]Podfile 无法获取".yellow " #{user_lib_name} ".green "版本号, 但仍支持源码映射\n".yellow
90
+ else
91
+
92
+ is_contain_lib = linked_list_contain(user_lib_name)
93
+ if is_contain_lib
94
+ print "\n[Error] #{user_lib_name} 已映射 (#{lib_version}), 如需重新映射,请先删除\n\n".red
95
+ return
96
+ else
97
+ print "\n#{project_name} Using ".green "#{user_lib_name} (#{lib_version})\n".green
98
+ end
99
+ end
100
+
101
+ config = config_with_asker
102
+ lib_path = config["libPath"]
103
+ sourcePath = config["sourcePath"]
104
+
105
+ if lib_path == "" || !File.exist?(lib_path)
106
+ UI.puts "\n[Error] 二进制文件不存在, 请检查文件位置!\n".red
107
+ return
108
+ end
109
+
110
+ if sourcePath == "" || !File.exist?(sourcePath)
111
+ UI.puts "\n[Error] 源码文件不存在, 请检查文件位置!\n".red
112
+ return
113
+ end
114
+
115
+ lib_name = source_lib_name(lib_path)
116
+ link_source_code(lib_path, sourcePath, lib_name)
117
+ end
118
+
119
+ def link_source_code(lib_path, sourcePath, lib_name)
120
+
121
+ comp_dir_path = `dwarfdump "#{lib_path}" | grep "AT_comp_dir" | head -1 | cut -d \\" -f2`
122
+ if comp_dir_path == nil || comp_dir_path == ""
123
+ UI.puts "\n[Error] #{lib_name} 不支持映射源码库\n".red
124
+ return
125
+ end
126
+
127
+ lib_debug_path = comp_dir_path.chomp.strip
128
+ if File.exist?(lib_debug_path) || File.directory?(lib_debug_path) || File.symlink?(lib_debug_path)
129
+ print "源码文件: #{lib_debug_path} 已存在,无法源码映射,防止误删请检查:"
130
+ UI.puts "\n1、源码已映射,无需重复映射 \n2、开发源码(无需映射,即可调试) \n3、其他重复文件, 请手动移动/移除\n".red
131
+
132
+ else
133
+
134
+ begin
135
+ FileUtils.mkdir_p(lib_debug_path)
136
+ rescue SystemCallError
137
+ array = lib_debug_path.split('/')
138
+ if array.length > 3
139
+ root_path = '/' + array[1] + '/' + array[2]
140
+ unless File.exist?(root_path)
141
+ UI.puts "[Error] 无权限创建文件夹,请手动创建#{root_path}文件夹,再重试\n".red
142
+ end
143
+ end
144
+ end
145
+
146
+ FileUtils.rm_rf(lib_debug_path)
147
+ if Pathname.new(lib_path).extname == ".a"
148
+ `ln -s #{sourcePath} #{lib_debug_path}`
149
+ else
150
+ `ln -s #{sourcePath} #{lib_debug_path}/#{lib_name}`
151
+ end
152
+ check_linked(lib_path, lib_debug_path, lib_name)
153
+ end
154
+ end
155
+
156
+ def check_linked(lib_path, sourcePath, lib_name)
157
+
158
+ source_path = `dwarfdump "#{lib_path}" | grep -E "DW_AT_decl_file.*#{lib_name}.*\\.m|\\.c" | head -1 | cut -d \\" -f2`
159
+ source_path = source_path.chomp.strip
160
+ if File.exist?(source_path)
161
+ UI.puts "🍺🍺🍺 Successfully! 源码映射成功\n".green
162
+ recordLinknSuccessLib(lib_name, lib_path, sourcePath)
163
+ else
164
+ UI.puts "[Error] 源码 #{source_path} 不存在, 请检查源码版本 或 存储位置\n".red
165
+ end
166
+ end
167
+
168
+ # 移除单个映射
169
+ def linked_remove
170
+ if @names.nil?
171
+ UI.puts "[Error] 请输入要删除的组件库. 实例: $ pod ybin --remove xxx yyy zzz\n".red
172
+ return
173
+ end
174
+
175
+ @names.each do |name|
176
+
177
+ lib_linked_path = get_lib_linked_path(name)
178
+ if lib_linked_path.nil? || lib_linked_path == ""
179
+ UI.puts "[Error] #{name} 的映射不存在, 无需移除".red
180
+ else
181
+ if File.exist?(lib_linked_path)
182
+ FileUtils.rm_rf(lib_linked_path)
183
+ removeLinkedFileRecord(name)
184
+ UI.puts "#{name} 成功移除".green
185
+ else
186
+ UI.puts "[Error] #{name} 的映射不存在, 请手动核查: #{lib_linked_path}".red
187
+ end
188
+ end
189
+ end
190
+ print "\n"
191
+ end
192
+
193
+ # 移除所有映射
194
+ def linked_remove_all
195
+
196
+ if File.exist?(source_record_file_path)
197
+ records = JSON.parse(File.read(source_record_file_path))
198
+
199
+ if records.count > 0
200
+ records.each.with_index(0) do |record, index|
201
+ lib_linked_path = record["source_path"]
202
+ lib_name = record["lib_name"]
203
+ if File.exist?(lib_linked_path)
204
+ FileUtils.rm_rf(lib_linked_path)
205
+ removeLinkedFileRecord(lib_name)
206
+ UI.puts "#{lib_name} removing...".green
207
+ end
208
+ end
209
+ UI.puts "\n已全部移除\n".green
210
+ else
211
+ UI.puts "无记录\n".green
212
+ end
213
+ end
214
+ end
215
+
216
+ # 查询映射列表
217
+ def linked_list
218
+
219
+ records = JSON.parse(File.read(source_record_file_path))
220
+ if records.count > 0
221
+ records.each.with_index(1) do |record, index|
222
+ UI.puts "#{index}. #{record["lib_name"]}(#{record["lib_version"]}) ".green "Source: #{record["source_path"]}".yellow
223
+ end
224
+ else
225
+ UI.puts "无记录".green
226
+ end
227
+ print "\n"
228
+ end
229
+
230
+ private
231
+
232
+
233
+ def linked_list_contain(lib_name)
234
+
235
+ is_contain_lib = false
236
+ records = JSON.parse(File.read(source_record_file_path))
237
+ records.each.with_index(1) do |record, index|
238
+ if record["lib_name"] == lib_name
239
+ is_contain_lib = true
240
+ break
241
+ end
242
+ end
243
+ is_contain_lib
244
+ end
245
+
246
+ def source_root
247
+ cache_root_dir_name = ".ybin"
248
+ user_home_path = Dir.home
249
+ cache_root_path = File.join(user_home_path, cache_root_dir_name);
250
+ FileUtils.mkdir_p(cache_root_path) unless File.exist? cache_root_path
251
+ cache_root_path
252
+ end
253
+
254
+ def source_record_file_path
255
+ source_r_path = File.join(source_root.to_s, 'ybin_source_links.json')
256
+ source_r_path
257
+ end
258
+
259
+ def source_lib_name(filePath)
260
+ file_name = File.basename(filePath, ".a")
261
+ file_name = file_name[3..file_name.length]
262
+ file_name
263
+ end
264
+
265
+ def project_name
266
+ targets = @aggregate_targets.map(&:user_project_path).compact.uniq
267
+ project_name = ""
268
+ if targets.count == 1
269
+ project_name = targets.first.basename('.xcodeproj')
270
+ end
271
+ project_name
272
+ end
273
+
274
+ def recordLinknSuccessLib(lib_name, lib_path, sourcePath)
275
+
276
+ if File.exist?(source_record_file_path)
277
+ record = JSON.parse(File.read(source_record_file_path))
278
+
279
+ record_libNames = Array.new
280
+ record.each do |sub|
281
+ record_libNames.push(sub['lib_name'])
282
+ end
283
+
284
+ if record_libNames.include?(lib_name)
285
+
286
+ replace_index = record_libNames.index(lib_name)
287
+ record[replace_index] = generate_record_item(lib_name, lib_path, sourcePath)
288
+ record_item_json = JSON.generate(record)
289
+
290
+ FileUtils.rm_rf(source_record_file_path) if File.exist?(source_record_file_path)
291
+ File.open(source_record_file_path, 'w') { |file| file.write(record_item_json)}
292
+ else
293
+
294
+ record.push(generate_record_item(lib_name, lib_path, sourcePath))
295
+ record_item_json = JSON.generate(record)
296
+
297
+ FileUtils.rm_rf(source_record_file_path) if File.exist?(source_record_file_path)
298
+ File.open(source_record_file_path, 'w') { |file| file.write(record_item_json)}
299
+ end
300
+ else
301
+ record_items = Array.new
302
+ record_items.push(generate_record_item(lib_name, lib_path, sourcePath))
303
+ record_item_json = JSON.generate(record_items)
304
+ File.open(source_record_file_path, 'w') { |file| file.write(record_item_json)}
305
+ end
306
+ end
307
+
308
+ def generate_record_item(lib_name, lib_path, source_path)
309
+ lib_version = get_lib_version(lib_name.chomp.strip)
310
+ record_item = {:lib_name => lib_name, :lib_version => lib_version, :lib_path => lib_path, :source_path => source_path}
311
+ record_item
312
+ end
313
+
314
+ def removeLinkedFileRecord(lib_name)
315
+
316
+ if File.exist?(source_record_file_path)
317
+ records = JSON.parse(File.read(source_record_file_path))
318
+
319
+ lib_name_index = -1
320
+ records.each.with_index(0) do |record, index|
321
+ if record["lib_name"] == lib_name
322
+ lib_name_index = index
323
+ break
324
+ end
325
+ end
326
+
327
+ if lib_name_index >= 0
328
+ records.delete_at(lib_name_index)
329
+ record_item_json = JSON.generate(records)
330
+
331
+ FileUtils.rm_rf(source_record_file_path) if File.exist?(source_record_file_path)
332
+ File.open(source_record_file_path, 'w') { |file| file.write(record_item_json)}
333
+ end
334
+ end
335
+ end
336
+
337
+ def analyzerPodFileLock
338
+
339
+ podfile_lock = File.join(Pathname.pwd, "Podfile.lock")
340
+ if File.exist?(podfile_lock)
341
+ else
342
+ UI.puts "[!] 未匹配到 Podfile.lock 文件, 无法获取 Pod 管理信息".red
343
+ return
344
+ end
345
+ @lockfile ||= Lockfile.from_file(Pathname.new(podfile_lock))
346
+
347
+ UI.section "Analyzer Podfile" do
348
+ analyzer = Pod::Installer::Analyzer.new(config.sandbox, config.podfile, @lockfile)
349
+ @analysis_result = analyzer.analyze
350
+ @aggregate_targets = @analysis_result.targets
351
+ @pod_targets = @analysis_result.pod_targets
352
+ end
353
+ end
354
+
355
+ def read_podfile_lock_version
356
+ if @analysis_result.nil?
357
+ return
358
+ end
359
+
360
+ UI.section "#{project_name} 通过 Cocoapods 管理的依赖库(含 dependency)版本:".yellow do
361
+ root_specs = @analysis_result.specifications.map(&:root).uniq
362
+ pods_to_install = @analysis_result.sandbox_state.added | @analysis_result.sandbox_state.changed
363
+ root_specs.sort_by(&:name).each.with_index(1) do |spec, index|
364
+ if pods_to_install.include?(spec.name)
365
+ else
366
+ UI.puts "#{index}. #{spec}".green
367
+ end
368
+ end
369
+ print "\n"
370
+ end
371
+ end
372
+
373
+ def get_lib_version(lib_name)
374
+ if @analysis_result.nil?
375
+ return
376
+ end
377
+
378
+ lib_version = ''
379
+ root_specs = @analysis_result.specifications.map(&:root).uniq
380
+ pods_to_install = @analysis_result.sandbox_state.added | @analysis_result.sandbox_state.changed
381
+ root_specs.sort_by(&:name).each.with_index(1) do |spec, index|
382
+ if pods_to_install.include?(spec.name)
383
+ else
384
+ if spec.name == lib_name
385
+ lib_version = spec.version
386
+ break
387
+ end
388
+ end
389
+ end
390
+ lib_version
391
+ end
392
+
393
+ def get_lib_linked_path(lib_name)
394
+ records = JSON.parse(File.read(source_record_file_path))
395
+ lib_linked_path = ""
396
+ records.each do |record|
397
+ if record["lib_name"] == lib_name
398
+ lib_linked_path = record["source_path"]
399
+ break
400
+ end
401
+ end
402
+ lib_linked_path
403
+ end
404
+
405
+ def template_source
406
+ {
407
+ 'libPath' => { question: '1/2 请输入映射源码的二进制库.a 的路径(如:/Users/xxx/Desktop/Workspace/xxx.a)' },
408
+ 'sourcePath' => { question: '2/2 源码位置(注意版本是否匹配)' },
409
+ }
410
+ end
411
+
412
+ def config_with_asker
413
+ config = {}
414
+ template_source.each do |k, v|
415
+ config[k] = get_require_path(v[:question])
416
+ end
417
+ print "\n"
418
+ config
419
+ end
420
+
421
+ def get_require_path(question)
422
+
423
+ Pod::UI.puts "\n#{question}".yellow
424
+ answer = ''
425
+ loop do
426
+ print "->".green
427
+ answer = STDIN.gets.chomp.strip
428
+ next if answer.empty?
429
+ break
430
+ end
431
+ answer
432
+ end
433
+
434
+ end
435
+ end
436
+ end
437
+ end
@@ -0,0 +1,3 @@
1
+ module CocoapodsYbin
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,8 @@
1
+
2
+ # Pod::HooksManager.register('cocoapods-ybin', :pre_install) do |_context, _|
3
+ #
4
+ # end
5
+
6
+ # Pod::HooksManager.register('cocoapods-ybin', :source_provider) do |context, _|
7
+ #
8
+ # end
@@ -0,0 +1,3 @@
1
+ require 'cocoapods-ybin/command'
2
+ require 'cocoapods-ybin/gem_version'
3
+ require 'cocoapods-ybin/source_provider_hook'
@@ -0,0 +1,12 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Pod
4
+ describe Command::Ybin do
5
+ describe 'CLAide' do
6
+ it 'registers it self' do
7
+ Command.parse(%w{ ybin }).should.be.instance_of Command::Ybin
8
+ end
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,50 @@
1
+ require 'pathname'
2
+ ROOT = Pathname.new(File.expand_path('../../', __FILE__))
3
+ $:.unshift((ROOT + 'lib').to_s)
4
+ $:.unshift((ROOT + 'spec').to_s)
5
+
6
+ require 'bundler/setup'
7
+ require 'bacon'
8
+ require 'mocha-on-bacon'
9
+ require 'pretty_bacon'
10
+ require 'pathname'
11
+ require 'cocoapods'
12
+
13
+ Mocha::Configuration.prevent(:stubbing_non_existent_method)
14
+
15
+ require 'cocoapods_plugin'
16
+
17
+ #-----------------------------------------------------------------------------#
18
+
19
+ module Pod
20
+
21
+ # Disable the wrapping so the output is deterministic in the tests.
22
+ #
23
+ UI.disable_wrap = true
24
+
25
+ # Redirects the messages to an internal store.
26
+ #
27
+ module UI
28
+ @output = ''
29
+ @warnings = ''
30
+
31
+ class << self
32
+ attr_accessor :output
33
+ attr_accessor :warnings
34
+
35
+ def puts(message = '')
36
+ @output << "#{message}\n"
37
+ end
38
+
39
+ def warn(message = '', actions = [])
40
+ @warnings << "#{message}\n"
41
+ end
42
+
43
+ def print(message)
44
+ @output << message
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ #-----------------------------------------------------------------------------#
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cocoapods-ybin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - monetking
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-09-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: cocoapods
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: cocoapods-generate
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: parallel
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: cocoapods-ybin is a plug-in for link source and binary.
84
+ email:
85
+ - houmanager@qq.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - LICENSE.txt
91
+ - README.md
92
+ - lib/cocoapods-ybin.rb
93
+ - lib/cocoapods-ybin/command.rb
94
+ - lib/cocoapods-ybin/command/ybin.rb
95
+ - lib/cocoapods-ybin/command/ybin/link.rb
96
+ - lib/cocoapods-ybin/gem_version.rb
97
+ - lib/cocoapods-ybin/source_provider_hook.rb
98
+ - lib/cocoapods_plugin.rb
99
+ - spec/command/ybin_spec.rb
100
+ - spec/spec_helper.rb
101
+ homepage: https://github.com/monetking/cocoapods-ybin.git
102
+ licenses:
103
+ - MIT
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubygems_version: 3.0.3
121
+ signing_key:
122
+ specification_version: 4
123
+ summary: link source and binary.
124
+ test_files:
125
+ - spec/command/ybin_spec.rb
126
+ - spec/spec_helper.rb