cocoapods-dongjia 1.1.2 → 1.1.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fa6197291c8d0327124cdfe9a152f5a4cddc91a15fb42571ca10c175f96fa730
4
- data.tar.gz: 4e68535d83b1c174b1e01314cf00f4fecd45c0131de4fbb4b37e64ffb4504c10
3
+ metadata.gz: abe6387bbccd1ac19c893b9c384025c976cf5a8975668725670aac190b750abb
4
+ data.tar.gz: 125582ad4f0aa628467990eb2b43e32007f43043044a4a57a17331a1893bd734
5
5
  SHA512:
6
- metadata.gz: 6d3a68721994c607cace3a8bca9bd89832887ef55646f5d9950c71c23099881f7299449cfd37940201a703116819d9173f18f99aaffa4a5dc0272ff7256ef598
7
- data.tar.gz: dc481b20dc7a3505f0a089ef465a513e4e026086df1a89fe7d97563c30accab74cd6492897a8debf79645aae1ffa0ac1241bd4356584cd7b6a5567e115cda484
6
+ metadata.gz: ce36c1a22df3189675dec1775e998fbfdf2a6e413c730db99ea6abfdf90bbf8cb6af04df6d00a90b9b8ce1e7c0c65ee5e4bf1274c2290880b87a03f4b0e44fe6
7
+ data.tar.gz: d9a8b6d5b4496424efb19e4499edacaabf232cdf3069f7ec10cc554de5b2771fe2d63c2596e1e21a5055e3f3197ff3fa7227b9d54b0c31a594e43e852759f93f
@@ -1,5 +1,6 @@
1
1
  require 'cocoapods-dongjia/command/reinstall'
2
2
  require 'cocoapods-dongjia/command/install'
3
+ require 'cocoapods-dongjia/command/release'
3
4
  require 'cocoapods-dongjia/command/demo'
4
5
  require 'cocoapods-dongjia/command/strip'
5
6
  require 'cocoapods-dongjia/command/open'
@@ -1,11 +1,8 @@
1
1
  require 'cocoapods'
2
2
 
3
3
  module Pod
4
-
5
4
  class Command
6
-
7
5
  class Install < Command
8
-
9
6
  alias_method :run_retryable, :run
10
7
  def run
11
8
  begin
@@ -18,9 +15,6 @@ module Pod
18
15
  end
19
16
  end
20
17
  end
21
-
22
18
  end
23
-
24
19
  end
25
-
26
20
  end
@@ -1,11 +1,8 @@
1
1
  require 'cocoapods'
2
2
 
3
3
  module Pod
4
-
5
4
  class Command
6
-
7
5
  class Open < Command
8
-
9
6
  self.summary = '快速打开项目的 .xcworkspace'
10
7
 
11
8
  self.description = <<-DESC
@@ -24,9 +21,6 @@ module Pod
24
21
  def run
25
22
  `open #{@workspace_path}`
26
23
  end
27
-
28
24
  end
29
-
30
25
  end
31
-
32
26
  end
@@ -18,7 +18,14 @@ module Pod
18
18
  CLAide::Argument.new('XCODE_PROJECT', false),
19
19
  ]
20
20
 
21
+ def self.options
22
+ [
23
+ ["--save", "将重新生成的 project.pbxproj 文件保存下来"]
24
+ ]
25
+ end
26
+
21
27
  def initialize(argv)
28
+ @save = argv.flag?("save")
22
29
  path = argv.shift_argument
23
30
  @project_path = Pathname.new(path) if path
24
31
  super
@@ -45,7 +52,7 @@ module Pod
45
52
 
46
53
  deintegrator = Deintegrator.new
47
54
  deintegrator.deintegrate_project(@project)
48
- @project.save
55
+ @project.save if @save
49
56
 
50
57
  verify_podfile_exists!
51
58
  installer = installer_for_config
@@ -0,0 +1,40 @@
1
+ require 'cocoapods'
2
+
3
+ module Pod
4
+
5
+ class Podfile
6
+ @@is_release_mode = false
7
+ def self.set_is_release_mode(mode)
8
+ @@is_release_mode = mode
9
+ end
10
+ def self.is_release_mode?
11
+ @@is_release_mode
12
+ end
13
+ end
14
+
15
+ class Command
16
+
17
+ class Release < Command
18
+
19
+ self.summary = '以 release 模式集成 pods'
20
+
21
+ self.description = <<-DESC
22
+
23
+ 以 release 模式集成 Pods
24
+
25
+ 可以在 Podfile 中通过 @@debug_only_pods = [pod_name] 的方式指定 debug 模式下的 Pod
26
+
27
+ 当执行 pod release 时,会自动剔除 @@debug_only_pods 内所定义的 Pod
28
+
29
+ DESC
30
+
31
+ def run
32
+ Pod::Podfile::set_is_release_mode(true)
33
+ installer_for_config.install!
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+
40
+ end
@@ -111,7 +111,7 @@ module Pod
111
111
  'AlipaySDK.bundle',
112
112
  'AppIcon.appiconset',
113
113
  'KPCameraImages.xcassets',
114
- 'Umeng',
114
+ 'UMSocialSDKResources.bundle',
115
115
  'LaunchResource'
116
116
  ]
117
117
  except_files = [
@@ -168,15 +168,16 @@ module Pod
168
168
 
169
169
  def run
170
170
  images = analyze(get_source_files, get_images)
171
- puts "无效资源文件:"
172
- images.each do |img|
173
- path = Pathname.new(img.fullpath).relative_path_from(Dir.pwd).to_s
174
- puts " #{path}"
171
+ if images.empty?
172
+ puts "未找到无效资源"
173
+ else
174
+ puts "无效资源文件:"
175
+ images.each do |img|
176
+ path = Pathname.new(img.fullpath).relative_path_from(Dir.pwd).to_s
177
+ puts " #{path}"
178
+ end
175
179
  end
176
180
  end
177
-
178
181
  end
179
-
180
182
  end
181
-
182
183
  end
@@ -1,7 +1,7 @@
1
1
  module CocoapodsDongjia
2
- VERSION = "1.1.2"
2
+ VERSION = "1.1.7"
3
3
  UPDATE_DESC = <<-EOS
4
- - 修复路由抓取错误
5
- - 修复 pod strip
4
+ - 修复源码和二进制切换后的集成依赖问题
5
+ - 修复一些导致 crash 的问题
6
6
  EOS
7
7
  end
@@ -1,19 +1,31 @@
1
1
  require 'cocoapods-dongjia/command'
2
2
  require_relative 'dongjia_source'
3
- require_relative 'dongjia_branch_inspector'
4
3
  require_relative 'dongjia_enterprise_inspector'
5
4
  require_relative 'dongjia_pods_iterator'
6
5
  require_relative 'dongjia_router'
7
- require_relative 'dongjia_scheme_manager'
6
+ require_relative 'dongjia_binarization'
8
7
 
9
- require_relative 'helper/podfile_local_importer'
8
+ require_relative 'helper/podfile'
10
9
  require_relative 'helper/podfile_options'
11
- require_relative 'helper/podfile_warnings'
10
+ require_relative 'helper/installer'
11
+ require_relative 'helper/Core/podfile/dsl'
12
12
 
13
13
  module Dongjia
14
14
 
15
15
  Pod::HooksManager.register('cocoapods-dongjia', :pre_install) do |ctx, params|
16
16
 
17
+ private_config_path = ctx.podfile.defined_in_file.dirname.join("PrivateConfig.yml")
18
+ if private_config_path.exist?
19
+ private_config = YAML.load(File.read(private_config_path))
20
+ if private_config.is_a?(Hash)
21
+ binary = private_config["binary"]
22
+ if binary.is_a?(Hash)
23
+ Binarization.load_private_config(ctx, binary)
24
+ Binarization.remove_dirty_pod_projects()
25
+ end
26
+ end
27
+ end
28
+
17
29
  podfile = ctx.podfile
18
30
 
19
31
  # 禁用集成完后的反馈
@@ -24,7 +36,6 @@ module Dongjia
24
36
 
25
37
  # 关闭静态框架依赖传递的校验
26
38
  Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {}
27
-
28
39
  end
29
40
 
30
41
  Pod::HooksManager.register('cocoapods-dongjia', :post_install) do |ctx, params|
@@ -32,17 +43,8 @@ module Dongjia
32
43
  # 关闭警告 / 检查 LTO
33
44
  PodsIterator.iterate(params, ctx.sandbox_root)
34
45
 
35
- # 处理 appspec 配置
36
- SchemeManager.setup(ctx, params)
37
-
38
- # 企业版文件引用校验
39
- files = EnterpriseInspector.inspect()
40
- Pod::UI.warn "文件未加入企业版:#{files}" if files.count > 0
41
-
42
46
  # 抓取所有路由汇总至
43
- router = Router.new
44
- router.scrape_routers(ctx.sandbox_root, params[:scrap_routers])
45
-
47
+ # router = Router.new
48
+ # router.scrape_routers(ctx.sandbox_root, params[:scrap_routers])
46
49
  end
47
-
48
50
  end
@@ -0,0 +1,642 @@
1
+ require 'xcodeproj'
2
+ require 'fileutils'
3
+ require 'archive/zip'
4
+ require 'net/http'
5
+ require 'json'
6
+ require 'yaml'
7
+ require 'down'
8
+ require 'pry'
9
+ require 'uri'
10
+
11
+ module Dongjia
12
+ class Binarization
13
+
14
+ @@ctx = nil
15
+ @@pod_cfg = {}
16
+ @@enabled = false
17
+ @@submodules = {}
18
+ @@server_host = ""
19
+
20
+ @@target_name = "dongjia" # 项目的 target 名
21
+ @@pods_proj = nil # Pods.xcodeproj
22
+ @@pods_target = nil # Pods.xcodeproj 中的 target 对象
23
+
24
+ class << self
25
+ # 加载配置
26
+ def load_private_config(ctx, binary)
27
+ @@ctx = ctx
28
+
29
+ submodule_info = load_submodules_info
30
+ @@submodules = submodule_info.to_h { |s|
31
+ [
32
+ s[:name],
33
+ { sha: s[:sha], binary: s[:binary], }
34
+ ]
35
+ }
36
+
37
+ @@enabled ||= binary["enabled"]
38
+ @@server_host = binary["server_host"]
39
+ @@target_name = (binary["target_name"] || "").strip
40
+ ignores = binary["ignores"] || []
41
+
42
+ if @@enabled
43
+ @@submodules = query_components_existing(submodule_info).to_h { |s|
44
+ [
45
+ s["name"],
46
+ { sha: s["sha"], binary: s["binary"], }
47
+ ]
48
+ }.each { |k, v|
49
+ ignored = ignores.include?(k)
50
+ v[:binary] &&= !ignored && @@enabled
51
+ v[:ignored] = ignored
52
+ }
53
+ end
54
+ rescue => e
55
+ puts "Binarization error: #{e}"
56
+ end
57
+
58
+ # 移除脏工程
59
+ def remove_dirty_pod_projects
60
+ if @@enabled
61
+ @@submodules
62
+ .filter { |k,v| !v[:binary] }
63
+ .map { |k,v| k }
64
+ .each { |name|
65
+ path = File.join(@@ctx.sandbox_root, "#{name}.xcodeproj")
66
+ next unless File.exist?(path)
67
+ proj = Xcodeproj::Project.open(path)
68
+ if proj.targets.map(&:name).include?("#{name}-Binary")
69
+ FileUtils.rm_rf(path)
70
+ end
71
+ }
72
+ else
73
+ # 不启用,清除所有包含 -Binary 的工程
74
+ removing_paths = []
75
+ Dir.foreach(@@ctx.sandbox_root) { |filename|
76
+ next if File.extname(filename) != '.xcodeproj'
77
+ pod_name = filename.delete_suffix('.xcodeproj')
78
+ next if pod_name == "Pods"
79
+ process_pod_xcconfig(pod_name)
80
+ path = File.join(@@ctx.sandbox_root, filename)
81
+ proj = Xcodeproj::Project.open(path)
82
+ included_binary_target = proj.targets.map(&:name).any? { |target_name|
83
+ target_name.end_with?("-Binary")
84
+ }
85
+ removing_paths << path if included_binary_target
86
+ }
87
+ removing_paths.each { |path| FileUtils.rm_rf(path) }
88
+ end
89
+ end
90
+
91
+ # 开始处理二进制
92
+ def process(installer)
93
+ return if @@ctx == nil || @@ctx.sandbox_root == nil
94
+
95
+ path = File.join(@@ctx.sandbox_root, "Pods.xcodeproj")
96
+ @@pods_proj = Xcodeproj::Project.open(path) if File.exist?(path)
97
+ @@pods_target = (@@target_name.empty?) ? @@pods_proj.targets.first : @@pods_proj.target_by_name("Pods-#{@@target_name}")
98
+ if @@pods_target.nil?
99
+ Pod::UI.warn("[Binarization] 未完成二进制转换,target_name 配置错误")
100
+ return
101
+ end
102
+
103
+ setup_pod_cfg(installer)
104
+
105
+ download_frameworks
106
+
107
+ each_pod_proj do |name, cfg|
108
+ process_pods_project_dependencies(name)
109
+
110
+ # 处理 Binary Group
111
+ process_binary_group(name)
112
+
113
+ # 处理 XXX-xcframeworks.sh 脚本
114
+ process_xcframeworks_shell(name)
115
+
116
+ process_pod_xcconfig(name)
117
+ end
118
+
119
+ # 更新依赖关系
120
+ each_pod_proj do |name, cfg|
121
+ target = cfg[:target]
122
+ next if target.nil?
123
+ delete_list = []
124
+ add_list = []
125
+ target.dependencies.each { |dep|
126
+ dep_pod_name = real_name(dep.name)
127
+ dep_cfg = @@pod_cfg[dep_pod_name]
128
+ next if dep_cfg.nil?
129
+ if dep_cfg[:target].name != dep.name
130
+ add_list << dep_cfg[:target]
131
+ delete_list << dep
132
+ end
133
+ }
134
+ target.dependencies.delete_if { |dep| delete_list.include?(dep) }
135
+ add_list.each { |t| target.add_dependency(t) }
136
+ cfg[:save] ||= !delete_list.empty? || !add_list.empty?
137
+ end
138
+
139
+ # 保存
140
+ save_projects
141
+
142
+ process_aggregate_target_xcconfig(installer.aggregate_targets.first.name)
143
+ end
144
+
145
+ private
146
+
147
+ # 加载配置
148
+ def setup_pod_cfg(installer)
149
+ installer.analysis_result.podfile_dependency_cache.podfile_dependencies.each { |dep|
150
+ name = dep.name.split('/').first
151
+ cfg = @@submodules[name] || {}
152
+ cfg[:binary] = false unless cfg[:binary]
153
+ cfg[:save] = false unless cfg[:save]
154
+ cfg[:project] = Xcodeproj::Project.open(File.join(@@ctx.sandbox_root, "#{name}.xcodeproj"))
155
+ @@pod_cfg[name] = cfg
156
+ }
157
+ end
158
+
159
+ # 获取实际的 pod 名,如果有 -Binary 后缀,则去除后缀
160
+ def real_name(name)
161
+ name = name.delete_suffix("-Binary") if name.end_with?("-Binary")
162
+ return name
163
+ end
164
+
165
+ def save_projects
166
+ if Pod::Config.instance.verbose == true
167
+ pods_should_save = @@pod_cfg.filter { |k, v| v[:save] }.keys
168
+ Pod::UI.notice "Saving Pods project" unless pods_should_save.empty?
169
+ pods_should_save.each { |name|
170
+ puts " #{name}"
171
+ }
172
+ end
173
+
174
+ should_save = false
175
+ each_pod_proj do |name, cfg|
176
+ cfg[:project].save if cfg[:save]
177
+ should_save ||= cfg[:save]
178
+ end
179
+ @@pods_proj.save if !@@pods_proj.nil? && should_save
180
+ end
181
+
182
+ # 遍历 Pods 目录下的 xcodeproj
183
+ def each_pod_proj
184
+ Dir.foreach(@@ctx.sandbox_root) do |filename|
185
+ next if File.extname(filename) != '.xcodeproj'
186
+
187
+ name = File.basename(filename, '.xcodeproj')
188
+ next if name == 'Pods'
189
+
190
+ cfg = @@pod_cfg[name]
191
+ next if cfg.nil?
192
+
193
+ yield(name, cfg) if block_given?
194
+ end
195
+ end
196
+
197
+ # 向服务器查询哪些 Pod 需要打包
198
+ def query_components_existing(components)
199
+ return components unless @@enabled
200
+ result = components
201
+ begin
202
+ uri = URI.parse(URI::join(@@server_host, 'api/binary/checkup').to_s)
203
+ headers = {
204
+ 'Content-Type': 'application/json'
205
+ }
206
+ req = Net::HTTP::Post.new(uri, headers)
207
+ req.body = {components: components}.to_json
208
+ resp = Net::HTTP.start(uri.host, uri.port) do |http|
209
+ http.request(req)
210
+ end
211
+ result = JSON.parse(resp.body).dig('res', 'components')
212
+ rescue => e
213
+ puts "Binarization error: #{e}"
214
+ end
215
+ return result
216
+ end
217
+
218
+ # 加载子模块信息
219
+ def load_submodules_info
220
+ return [] unless File.exist?("./componentsOnRemote")
221
+
222
+ # 获取子模块的哈希值
223
+ def git_sha_value(component_name)
224
+ git_dir = ".git/modules/componentsOnRemote/#{component_name}"
225
+ git_sha = File.read(File.join(git_dir, "HEAD")).strip
226
+ if git_sha.start_with?("ref: ")
227
+ head_file = git_sha[5, git_sha.length]
228
+ head_path = File.join(git_dir, head_file)
229
+ if File.exist?(head_path)
230
+ git_sha = File.read(head_path).strip
231
+ else
232
+ git_sha = nil
233
+ end
234
+ end
235
+ git_sha
236
+ end
237
+
238
+ Dir.foreach("./componentsOnRemote").to_a
239
+ .delete_if { |x| x.start_with?('.') }
240
+ .delete_if { |x|
241
+ # 如果子模块初始化错误,会导致目录下没有内容,需要排除掉
242
+ Dir.foreach("./componentsOnRemote/#{x}").to_a.all? { |f| f.start_with?(".") }
243
+ }
244
+ .map { |comp|
245
+ {
246
+ name: comp,
247
+ sha: git_sha_value(comp),
248
+ binary: false,
249
+ }
250
+ }
251
+ end
252
+
253
+ # 处理 Pods.xcodeproj 的依赖
254
+ def process_pods_project_dependencies(name)
255
+ cfg = @@pod_cfg[name]
256
+ proj = cfg[:project]
257
+ changed = false
258
+
259
+ latest_target = nil
260
+ removing_target_name = nil
261
+
262
+ if cfg[:binary] == true
263
+ # 使用 Binary 版本的 target,如果不存在则创建一个
264
+ binary_target = proj.target_by_name("#{name}-Binary")
265
+ if binary_target == nil
266
+ binary_target = add_binary_target(proj, name)
267
+ changed = true
268
+ end
269
+
270
+ latest_target = binary_target
271
+ removing_target_name = name
272
+ else
273
+ # 使用源码版本的 target
274
+ source_target = proj.target_by_name(name)
275
+ source_target.build_configurations.each { |cfg|
276
+ if cfg.build_settings["BUILD_LIBRARY_FOR_DISTRIBUTION"] != "YES"
277
+ cfg.build_settings["BUILD_LIBRARY_FOR_DISTRIBUTION"] = "YES"
278
+ changed = true
279
+ end
280
+ }
281
+
282
+ latest_target = source_target
283
+ removing_target_name = "#{name}-Binary"
284
+ end
285
+
286
+ cfg[:target] = latest_target
287
+
288
+ # 更新依赖
289
+ changed = update_pods_target_dependency(removing_target_name, latest_target) || changed
290
+ changed = proj.targets.map(&:name).include?(removing_target_name) || changed
291
+ proj.targets.delete_if { |t| t.name == removing_target_name }
292
+
293
+ cfg[:save] = changed
294
+ end
295
+
296
+ # 处理组件 pod 的 xcconfig
297
+ def process_pod_xcconfig(name)
298
+ # 根据 pod 是源码还是二进制包,切换路径为 PODS_CONFIGURATION_BUILD_DIR 或 PODS_XCFRAMEWORKS_BUILD_DIR
299
+ ["debug", "release"].each { |cfg_name|
300
+ cfg_path = Pathname(File.join(@@ctx.sandbox_root, "Target Support Files", name, "#{name}.#{cfg_name}.xcconfig"))
301
+ next if not File.exist?(cfg_path)
302
+ cfg = Xcodeproj::Config.new(cfg_path)
303
+ fsp_str = cfg.attributes["FRAMEWORK_SEARCH_PATHS"] || "$(inherited)"
304
+ fsp = fsp_str.split(" ")
305
+
306
+ # 源码的 prefix
307
+ source_prefix = "\"${PODS_CONFIGURATION_BUILD_DIR}/"
308
+ # 二进制包的 prefix
309
+ binary_prefix = "\"${PODS_XCFRAMEWORKS_BUILD_DIR}/"
310
+
311
+ fsp.map! { |path|
312
+ if path.start_with?(source_prefix)
313
+ pod_name = path[source_prefix.length, path.length].delete_suffix("\"")
314
+ sm = @@submodules[pod_name]
315
+ if !sm.nil? && sm[:binary]
316
+ path = path.gsub("PODS_CONFIGURATION_BUILD_DIR", "PODS_XCFRAMEWORKS_BUILD_DIR")
317
+ end
318
+ elsif path.start_with?(binary_prefix)
319
+ pod_name = path[binary_prefix.length, path.length].delete_suffix("\"")
320
+ sm = @@submodules[pod_name]
321
+ if !sm.nil? && !sm[:binary]
322
+ path = path.gsub("PODS_XCFRAMEWORKS_BUILD_DIR", "PODS_CONFIGURATION_BUILD_DIR")
323
+ end
324
+ end
325
+ path
326
+ }
327
+ cfg.attributes["FRAMEWORK_SEARCH_PATHS"] = fsp.flatten.uniq.join(" ")
328
+ cfg.save_as(cfg_path)
329
+ }
330
+ end
331
+
332
+ # 处理集成对象的 xcconfig(项目的 xcconfig)
333
+ def process_aggregate_target_xcconfig(aggregate_target_name)
334
+ # 处理 Pods/Target Support Files/Pods-项目名/Pods-项目名.debug(release).xcconfig
335
+ # 所有被二进制化的 pod,增加 "${PODS_XCFRAMEWORKS_BUILD_DIR}/#{pod_name}"
336
+ ["debug", "release"].each { |cfg_name|
337
+ cfg_path = Pathname(File.join(@@ctx.sandbox_root, "Target Support Files", aggregate_target_name, "#{aggregate_target_name}.#{cfg_name}.xcconfig"))
338
+ next if not File.exist?(cfg_path)
339
+ cfg = Xcodeproj::Config.new(cfg_path)
340
+ fsp = cfg.attributes["FRAMEWORK_SEARCH_PATHS"].split(" ") || ["$(inherited)"]
341
+ @@submodules.each { |k, v|
342
+ path = "\"${PODS_XCFRAMEWORKS_BUILD_DIR}/#{k}\""
343
+ if v[:binary] == true
344
+ fsp << path if not fsp.include?(path)
345
+ else
346
+ fsp.delete_if { |x| x == path }
347
+ end
348
+ }
349
+ cfg.attributes["FRAMEWORK_SEARCH_PATHS"] = fsp.flatten.uniq.join(" ")
350
+ cfg.save_as(cfg_path)
351
+ }
352
+ end
353
+
354
+ def add_binary_target(proj, name)
355
+ source_target = proj.target_by_name(name)
356
+ bin_target = proj.new_aggregate_target("#{name}-Binary", [], :ios, '10.0')
357
+
358
+ # 处理 xcconfig 引用
359
+ cfg_list0 = source_target.build_configuration_list
360
+ cfg_list1 = bin_target.build_configuration_list
361
+ cfg_list1["Debug"].base_configuration_reference ||= cfg_list0["Debug"].base_configuration_reference
362
+ cfg_list1["Release"].base_configuration_reference ||= cfg_list0["Release"].base_configuration_reference
363
+
364
+ # 处理 Build Phases
365
+ phase = bin_target.new_shell_script_build_phase("[CP] Copy XCFrameworks")
366
+ phase.shell_script = "\"${PODS_ROOT}/Target Support Files/#{name}/#{name}-xcframeworks.sh\""
367
+
368
+ # 添加依赖
369
+ bin_target.dependencies.replace(source_target.dependencies)
370
+
371
+ return bin_target
372
+ end
373
+
374
+ # 更新 Pods.xcodeproj 中 target 的依赖关系
375
+ def update_pods_target_dependency(removing_target_name, new_target)
376
+ dep_names = @@pods_target.dependencies.map(&:name)
377
+ changed = false
378
+
379
+ index = dep_names.index(removing_target_name)
380
+ if index
381
+ @@pods_target.dependencies.delete_at(index)
382
+ changed = true
383
+ end
384
+
385
+ index = dep_names.index(new_target.name)
386
+ unless index
387
+ @@pods_target.add_dependency(new_target)
388
+ changed = true
389
+ end
390
+
391
+ return changed
392
+ end
393
+
394
+ # 下载 framework 到 Pods/_Frameworks 目录下
395
+ def download_frameworks
396
+ return unless @@enabled
397
+ framework_root = File.join(@@ctx.sandbox_root, "_Frameworks")
398
+ cache_root = File.join(framework_root, "Caches")
399
+ FileUtils.mkdir_p(cache_root) unless File.exist?(cache_root)
400
+
401
+ @@submodules.each { |k, v|
402
+ if !v[:binary] || !v[:sha]
403
+ puts "#{k} 未发现二进制版本" if @@enabled && !v[:ignored]
404
+ next
405
+ end
406
+
407
+ module_cache_dir = File.join(cache_root, k)
408
+ FileUtils.mkdir_p(module_cache_dir) unless File.exist?(module_cache_dir)
409
+
410
+ filename = "#{v[:sha]}.zip"
411
+ binary_dir = File.join(module_cache_dir, v[:sha])
412
+ if not File.exist?(binary_dir)
413
+ # 目录不存在,下载 zip 包并解压
414
+ binary_zip_path = File.join(module_cache_dir, filename)
415
+ puts "Downloading #{k} (#{v[:sha]})"
416
+ url = URI::join(@@server_host, "binary/#{k}/#{filename}")
417
+ Down.download(url, destination: binary_zip_path)
418
+ Archive::Zip.extract(binary_zip_path, binary_dir)
419
+ FileUtils.rm_f(binary_zip_path)
420
+ end
421
+ target = File.expand_path(File.join(binary_dir, "#{k}.xcframework"))
422
+ FileUtils.ln_s(target, framework_root, force: true)
423
+ }
424
+ end
425
+
426
+ def process_binary_group(name)
427
+ cfg = @@pod_cfg[name]
428
+ proj = cfg[:project]
429
+ binary_group = proj.groups.find { |g| g.name == "Binary" }
430
+ if cfg[:binary] == true
431
+ if binary_group == nil
432
+ binary_group = proj.new_group("Binary")
433
+ binary_group.new_reference("_Frameworks/#{name}.xcframework")
434
+ proj.sort
435
+ end
436
+ else
437
+ if binary_group != nil
438
+ binary_group.remove_from_project
439
+ end
440
+ end
441
+ end
442
+
443
+ def process_xcframeworks_shell(name)
444
+ cfg = @@pod_cfg[name]
445
+ return if cfg[:binary] != true
446
+ script_path = File.join(@@ctx.sandbox_root, "Target Support Files", name, "#{name}-xcframeworks.sh")
447
+ File.open(script_path, 'w') do |f|
448
+ f.write(xcframeworks_shell(name))
449
+ end
450
+ FileUtils.chmod('a+x', script_path)
451
+ end
452
+
453
+ # 获取当前 Wi-Fi 的 SSID
454
+ def get_wifi_ssid
455
+ lines = `/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I`.split("\n").map { |line| line.strip }
456
+ target = lines.find { |x| x.start_with?("SSID: ") }
457
+ target.nil? ? "" : target.delete_prefix("SSID: ")
458
+ end
459
+ end
460
+ end
461
+ end
462
+
463
+ module Dongjia
464
+ class Binarization
465
+ def self.xcframeworks_shell(pod_name)
466
+ <<-DESC
467
+ #!/bin/sh
468
+ set -e
469
+ set -u
470
+ set -o pipefail
471
+
472
+ function on_error {
473
+ echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
474
+ }
475
+ trap 'on_error $LINENO' ERR
476
+
477
+
478
+ # This protects against multiple targets copying the same framework dependency at the same time. The solution
479
+ # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
480
+ RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
481
+
482
+
483
+ copy_dir()
484
+ {
485
+ local source="$1"
486
+ local destination="$2"
487
+
488
+ # Use filter instead of exclude so missing patterns don't throw errors.
489
+ echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \\"- CVS/\\" --filter \\"- .svn/\\" --filter \\"- .git/\\" --filter \\"- .hg/\\" \\"${source}\\" \\"${destination}\\""
490
+ rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" "${source}" "${destination}"
491
+ }
492
+
493
+ SELECT_SLICE_RETVAL=""
494
+
495
+ select_slice() {
496
+ local paths=("$@")
497
+ # Locate the correct slice of the .xcframework for the current architectures
498
+ local target_path=""
499
+
500
+ # Split archs on space so we can find a slice that has all the needed archs
501
+ local target_archs=$(echo $ARCHS | tr " " "\\n")
502
+
503
+ local target_variant=""
504
+ if [[ "$PLATFORM_NAME" == *"simulator" ]]; then
505
+ target_variant="simulator"
506
+ fi
507
+ if [[ ! -z ${EFFECTIVE_PLATFORM_NAME+x} && "$EFFECTIVE_PLATFORM_NAME" == *"maccatalyst" ]]; then
508
+ target_variant="maccatalyst"
509
+ fi
510
+ for i in ${!paths[@]}; do
511
+ local matched_all_archs="1"
512
+ for target_arch in $target_archs
513
+ do
514
+ if ! [[ "${paths[$i]}" == *"$target_variant"* ]]; then
515
+ matched_all_archs="0"
516
+ break
517
+ fi
518
+
519
+ # Verifies that the path contains the variant string (simulator or maccatalyst) if the variant is set.
520
+ if [[ -z "$target_variant" && ("${paths[$i]}" == *"simulator"* || "${paths[$i]}" == *"maccatalyst"*) ]]; then
521
+ matched_all_archs="0"
522
+ break
523
+ fi
524
+
525
+ # This regex matches all possible variants of the arch in the folder name:
526
+ # Let's say the folder name is: ios-armv7_armv7s_arm64_arm64e/CoconutLib.framework
527
+ # We match the following: -armv7_, _armv7s_, _arm64_ and _arm64e/.
528
+ # If we have a specific variant: ios-i386_x86_64-simulator/CoconutLib.framework
529
+ # We match the following: -i386_ and _x86_64-
530
+ # When the .xcframework wraps a static library, the folder name does not include
531
+ # any .framework. In that case, the folder name can be: ios-arm64_armv7
532
+ # We also match _armv7$ to handle that case.
533
+ local target_arch_regex="[_\\-]${target_arch}([\\/_\\-]|$)"
534
+ if ! [[ "${paths[$i]}" =~ $target_arch_regex ]]; then
535
+ matched_all_archs="0"
536
+ break
537
+ fi
538
+ done
539
+
540
+ if [[ "$matched_all_archs" == "1" ]]; then
541
+ # Found a matching slice
542
+ echo "Selected xcframework slice ${paths[$i]}"
543
+ SELECT_SLICE_RETVAL=${paths[$i]}
544
+ break
545
+ fi
546
+ done
547
+ }
548
+
549
+ install_library() {
550
+ local source="$1"
551
+ local name="$2"
552
+ local destination="${PODS_XCFRAMEWORKS_BUILD_DIR}/${name}"
553
+
554
+ # Libraries can contain headers, module maps, and a binary, so we'll copy everything in the folder over
555
+
556
+ local source="$binary"
557
+ echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \\"- CVS/\\" --filter \\"- .svn/\\" --filter \\"- .git/\\" --filter \\"- .hg/\\" \\"${source}/*\\" \\"${destination}\\""
558
+ rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" "${source}/*" "${destination}"
559
+ }
560
+
561
+ # Copies a framework to derived data for use in later build phases
562
+ install_framework()
563
+ {
564
+ local source="$1"
565
+ local name="$2"
566
+ local destination="${PODS_XCFRAMEWORKS_BUILD_DIR}/${name}"
567
+
568
+ if [ ! -d "$destination" ]; then
569
+ mkdir -p "$destination"
570
+ fi
571
+
572
+ copy_dir "$source" "$destination"
573
+ echo "Copied $source to $destination"
574
+ }
575
+
576
+ install_xcframework_library() {
577
+ local basepath="$1"
578
+ local name="$2"
579
+ local paths=("$@")
580
+
581
+ # Locate the correct slice of the .xcframework for the current architectures
582
+ select_slice "${paths[@]}"
583
+ local target_path="$SELECT_SLICE_RETVAL"
584
+ if [[ -z "$target_path" ]]; then
585
+ echo "warning: [CP] Unable to find matching .xcframework slice in '${paths[@]}' for the current build architectures ($ARCHS)."
586
+ return
587
+ fi
588
+
589
+ install_framework "$basepath/$target_path" "$name"
590
+ }
591
+
592
+ install_xcframework() {
593
+ local basepath="$1"
594
+ local name="$2"
595
+ local package_type="$3"
596
+ local paths=("$@")
597
+
598
+ # Locate the correct slice of the .xcframework for the current architectures
599
+ select_slice "${paths[@]}"
600
+ local target_path="$SELECT_SLICE_RETVAL"
601
+ if [[ -z "$target_path" ]]; then
602
+ echo "warning: [CP] Unable to find matching .xcframework slice in '${paths[@]}' for the current build architectures ($ARCHS)."
603
+ return
604
+ fi
605
+ local source="$basepath/$target_path"
606
+
607
+ local destination="${PODS_XCFRAMEWORKS_BUILD_DIR}/${name}"
608
+
609
+ if [ ! -d "$destination" ]; then
610
+ mkdir -p "$destination"
611
+ fi
612
+
613
+ copy_dir "$source/" "$destination"
614
+
615
+ echo "Copied $source to $destination"
616
+ }
617
+
618
+ install_xcframework "${PODS_ROOT}/_Frameworks/#{pod_name}.xcframework" "#{pod_name}" "framework" "ios-arm64_armv7" "ios-x86_64-simulator"
619
+ DESC
620
+ end
621
+ end
622
+ end
623
+
624
+ module Xcodeproj
625
+ class Project
626
+ def target_by_name(name)
627
+ targets.find { |t| t.name == name }
628
+ end
629
+
630
+ def group_by_name(name)
631
+ groups.find { |g| g.name == name }
632
+ end
633
+
634
+ module Object
635
+ class PBXGroup
636
+ def group_by_name(name)
637
+ groups.find { |g| g.name == name }
638
+ end
639
+ end
640
+ end
641
+ end
642
+ end