Class: Pod::Command::Bin::Code

Inherits:
Pod::Command::Bin show all
Defined in:
lib/cocoapods-bb-bin/command/bin/code.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Pod::Command::Bin

#validate!

Methods included from CBin::SpecFilesHelper

#binary_spec, #binary_spec_files, #binary_template_spec, #binary_template_spec_file, #binary_template_spec_files, #clear_binary_spec_file_if_needed, #code_spec, #code_spec_files, #create_binary_spec_file, #find_spec_file, #spec_files

Methods included from CBin::SourcesHelper

#abc_source, #binary_source, #br_source, #bw_source, #code_source, #custom_business_source, #math_source, #science_source, #sources_manager, #sources_option, #sources_optionV2, #valid_sources, #valid_sourcesV2

Constructor Details

#initialize(argv) ⇒ Code

Returns a new instance of Code.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/cocoapods-bb-bin/command/bin/code.rb', line 27

def initialize(argv)
  @codeSource =  argv.option('source') || nil
  @names = argv.arguments! unless argv.arguments.empty?
  @list = argv.flag?('list', false )
  @all_clean = argv.flag?('all-clean', false )
  @clean = argv.flag?('clean', false )
  @simulator = argv.flag?('simulator', false )

  @config = Pod::Config.instance
  puts "=== pod bin code initialize begin ===".green
  puts "argv.class: #{argv.class}"
  puts "argv.to_s: #{argv}"
  puts "argv.arguments: #{argv.arguments.inspect}"
  puts "argv.options: #{argv.options.inspect if argv.respond_to?(:options)}"
  puts "argv.flags: #{argv.flags.inspect if argv.respond_to?(:flags)}"
  puts "argv.option('source'): #{argv.option('source').inspect}"
  puts "@codeSource: #{@codeSource.inspect}"
  puts "@names: #{@names.inspect}"
  puts "@list: #{@list}, @clean: #{@clean}, @all_clean: #{@all_clean}, @simulator: #{@simulator}"
  puts "=== pod bin code initialize end ===".green
  super
end

Class Method Details

.optionsObject



17
18
19
20
21
22
23
24
25
# File 'lib/cocoapods-bb-bin/command/bin/code.rb', line 17

def self.options
  [
      ['--all-clean', '删除所有已经下载的源码'],
      ['--clean', '删除所有指定下载的源码'],
      ['--list', '展示所有一级下载的源码以及其大小'],
      ['--source', '源码路径,本地路径,会去自动链接本地源码'],
      ['--simulator', '是否模拟器架构,xcframework需要'],# 是否模拟器,默认NO,xcframework需要使用
  ]
end

Instance Method Details

#addObject

begin add ==============


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/cocoapods-bb-bin/command/bin/code.rb', line 74

def add
  if @names == nil
    raise "请输入要调试组件名,多个组件名称用空格分隔"
  end

  @names.each do  |name|
    lib_file = get_lib_path(name)
    unless File.exist?(lib_file)
      raise "找不到 #{lib_file}"
    end
    UI.puts "#{lib_file}"
    if @codeSource
      puts "add name:#{name} local path:#{@codeSource}"
      target_path = @codeSource
    else
      puts "add name:#{name} download_source"
      target_path = download_source(name)
    end
    puts "====add lib_file: #{lib_file} target_path: #{target_path} name: #{name}"
    link(lib_file,target_path,name)
  end
end

#all_cleanObject

clean begin ==============


300
301
302
303
# File 'lib/cocoapods-bb-bin/command/bin/code.rb', line 300

def all_clean
  FileUtils.rm_rf(source_root) if File.directory?(source_root)
  UI.puts "清理完成 #{source_root}"
end

#check(lib_file, dir, basename) ⇒ Object



212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/cocoapods-bb-bin/command/bin/code.rb', line 212

def check(lib_file,dir,basename)
  print <<EOF
  check 源码
  `dwarfdump "#{lib_file}" | grep -E "DW_AT_decl_file.*#{basename}.*\\.m|\\.c" | head -1 | cut -d \\" -f2`
EOF
  file = `dwarfdump "#{lib_file}" | grep -E "DW_AT_decl_file.*#{basename}.*\\.m|\\.c" | head -1 | cut -d \\" -f2`
  if File.exist?(file)
    raise Informative, "#{file} 不存在 请检测代码源是否正确~"
  end
  UI.puts "library file: #{lib_file} dwarfdump file: #{file}"
  UI.puts "link successfully!".yellow
  UI.puts "view linked source at path: #{dir}".yellow
end

#cleanObject



305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/cocoapods-bb-bin/command/bin/code.rb', line 305

def clean
  raise "请输入要删除的组件库" if @names.nil?
  @names.each do  |name|
    full_path = File.join(source_root,name)
    if File.directory?(full_path)
      FileUtils.rm_rf(full_path)
    else
      UI.puts "找不到 #{full_path}".yellow
    end
  end
  UI.puts "清理完成 #{@names.to_s}"
end

#download_source(name) ⇒ Object

下载源码到本地



98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/cocoapods-bb-bin/command/bin/code.rb', line 98

def download_source(name)
  target_path =  File.join(source_root, name)
  UI.puts target_path
  FileUtils.rm_rf(target_path)

  find_dependency = find_dependency(name)

  spec = fetch_external_source(find_dependency, @config.podfile,@config.lockfile, @config.sandbox,true )

  download_request = Pod::Downloader::Request.new(:name => name, :spec => spec)
  Downloader.download(download_request, Pathname.new(target_path), :can_cache => true)

  target_path
end

#fetch_external_source(dependency, podfile, lockfile, sandbox, use_lockfile_options) ⇒ Object

获取external_source 下的仓库

Returns:

  • spec



127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/cocoapods-bb-bin/command/bin/code.rb', line 127

def fetch_external_source(dependency ,podfile , lockfile, sandbox,use_lockfile_options)
  # CocoaPods 内部会假定 external_source 是 Hash,这里兜底处理 nil 场景
  if dependency.external_source.nil?
    dependency.instance_variable_set(:@external_source, {})
  end
  installation_options = podfile.installation_options
  source = if use_lockfile_options && lockfile && checkout_options = lockfile.checkout_options_for_pod_named(dependency.root_name)
           ExternalSources.from_params(checkout_options, dependency, podfile.defined_in_file, installation_options.clean?)
         else
           ExternalSources.from_dependency(dependency, podfile.defined_in_file, installation_options.clean?)
         end
  source.fetch(sandbox)
end

#find_dependency(name) ⇒ Object

找出依赖



114
115
116
117
118
119
120
121
122
123
# File 'lib/cocoapods-bb-bin/command/bin/code.rb', line 114

def find_dependency (name)
  find_dependency = nil
  @config.podfile.dependencies.each do |dependency|
    if dependency.root_name.downcase == name.downcase
      find_dependency = dependency
      break
    end
  end
  find_dependency
end

#get_lib_path(name) ⇒ Object



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
# File 'lib/cocoapods-bb-bin/command/bin/code.rb', line 226

def get_lib_path(name)
  dir = Pathname.new(File.join(Pathname.pwd,"Pods",name))
  # 遍历组件目录判断
  Dir.foreach(dir) do |filename|
    if filename != "." and filename != ".."
      filepath = File.join(dir,"#{filename}")
      if File.file?(filepath)
        if File.extname(filepath) == '.a' # .a库
          return filepath
        end
      else
        if File.extname(filepath) == '.framework' # .framework库
          return File.join(filepath,name)
        end
        if File.extname(filepath) == '.xcframework' # .xcframework库
          
          print <<EOF
  获取xcframework架构 ls -al "#{filepath}"
EOF
          # 构建xcframework架构需要根据实际二进制文件进行条件判断
          arm_name = ""
          if @simulator
            arm_name = "ios-arm64_x86_64-simulator" #"ios-arm64_i386_x86_64-simulator"
          else
            arm_name = "ios-arm64" #"ios-arm64_armv7"
          end
          temp_name = "#{arm_name}/#{name}.framework/#{name}"
          return File.join(filepath,temp_name) # TYSecKit.xcframework/ios-arm64_armv7/TYSecKit.framework/TYSecKit
        end
      end
    end
  end
  # 兼容作者代码,默认取.a文件
  lib_name = "lib#{name}.a"
  lib_path = File.join(dir,lib_name)

  unless File.exist?(lib_path)
    lib_path = File.join(dir.children.first,lib_name)
  end

  lib_path
end

链接,.a文件位置, 源码目录,工程名=IMYFoundation



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
# File 'lib/cocoapods-bb-bin/command/bin/code.rb', line 145

def link(lib_file,target_path,basename)
  print <<EOF
  link 源码
  `dwarfdump "#{lib_file}" | grep "AT_comp_dir" | head -1 | cut -d \\" -f2 `
EOF
  dir = (`dwarfdump "#{lib_file}" | grep "AT_comp_dir" | head -1 | cut -d \\" -f2 `)
  UI.puts "lib_file = #{lib_file}"
  UI.puts "dwarfdump dir = #{dir} type:#{dir.class}"
  if dir.empty?
    msg = "Unknown dwarfdump data for `#{basename}` 请找hm确认,当前组件是否二进制静态库?动态库不支持"
    raise Informative, msg
  end
  # if Pathname.new(lib_file).extname == ".a"
  #   sub_path = "#{basename}/bin-archive/#{basename}"
  # else
  #   sub_path = "#{basename}"
  # end
  sub_path = "#{basename}/bin-archive/#{basename}"
  UI.puts "sub_path = #{sub_path}"
  dir = dir.gsub(sub_path, "").chomp
  UI.puts "Binary dir = #{dir}"

  unless File.exist?(dir)
    # UI.puts "不存在 = #{dir}"
    begin
      unless File.exist?(dir)
        require "fileutils"
        FileUtils.mkdir_p(dir)
      end
      # FileUtils.mkdir_p(dir) unless File.exists?(dir) # require 'fileutils'
    rescue SystemCallError
      # mkdir: _fzzfm3x4y17bm6psx9yhbs00000gn: Permission denied
      unless File.exist?(dir)
        user_name_array = Dir.home.split('/') # Dir.home = /Users/xx,xx表示当前用户名称
        user_name = "501"
        user_name_array.each do |name|
          user_name = name
        end
        UI.puts "user_name = #{user_name}".yellow
        `sudo mkdir -p #{dir} && sudo chown -R #{user_name}:wheel #{dir}`
      end
      #判断用户目录是否存在
      array = dir.split('/')
      if array.length > 5
        root_path = '/' + array[1] + '/' + array[2] + '/' + array[3] + '/' + array[4]
        UI.puts "root_path = #{root_path}"
        unless File.exist?(root_path)
          raise "由于权限不足,请手动创建#{root_path} 后重试"
        end
      end
    end
  end
  unless File.exist?(dir) 
    raise Informative, "【切换源码】由于权限不足,请手动创建目录: #{dir} 授权mobile权限后重试"
  end

  if Pathname.new(lib_file).extname == ".a"
    FileUtils.rm_rf(File.join(dir,basename))
    `ln -s #{target_path} #{dir}`
  else
    FileUtils.rm_rf(File.join(dir,basename))
    `ln -s #{target_path} #{dir}/#{basename}`
  end

  check(lib_file,dir,basename)
end

#listObject

list begin ==============


291
292
293
294
295
296
# File 'lib/cocoapods-bb-bin/command/bin/code.rb', line 291

def list
  Dir.entries(source_root).each do |sub|
    UI.puts "- #{sub}" unless sub.include?('.')
  end
  UI.puts "加载完成"
end

#runObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/cocoapods-bb-bin/command/bin/code.rb', line 51

def run

  podfile_lock = File.join(Pathname.pwd,"Podfile.lock")
  raise "podfile.lock,不存在,请先pod install/update" unless File.exist?(podfile_lock)
  @lockfile ||= Lockfile.from_file(Pathname.new(podfile_lock) )

  if @list
    list
  elsif @clean
    clean
  elsif @all_clean
    all_clean
  elsif @names
    add
  end

  if @list && @clean && @names
    raise "请选择您要执行的命令。"
  end
end