cocoapods-jxedt 0.0.12 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/lib/cocoapods-jxedt/binary/Intergation.rb +18 -13
  3. data/lib/cocoapods-jxedt/binary/config.rb +62 -0
  4. data/lib/cocoapods-jxedt/binary/helper/podfile_post_install_hook.rb +29 -0
  5. data/lib/cocoapods-jxedt/binary/hooks/CocoapodsJxedtHook.rb +6 -9
  6. data/lib/cocoapods-jxedt/binary/hooks/post_install.rb +2 -2
  7. data/lib/cocoapods-jxedt/binary/hooks/pre_install.rb +30 -10
  8. data/lib/cocoapods-jxedt/binary/main.rb +1 -0
  9. data/lib/cocoapods-jxedt/binary/pod-room/framework.rb +40 -0
  10. data/lib/cocoapods-jxedt/binary/pod-room/xcodebuild_command.rb +79 -1
  11. data/lib/cocoapods-jxedt/binary/pod-room/xcodebuild_raw.rb +1 -1
  12. data/lib/cocoapods-jxedt/binary/prebuild.rb +92 -14
  13. data/lib/cocoapods-jxedt/command/binary/binary.rb +36 -0
  14. data/lib/cocoapods-jxedt/command/binary/command/build.rb +84 -0
  15. data/lib/cocoapods-jxedt/command/binary/command/clean.rb +101 -0
  16. data/lib/cocoapods-jxedt/command/binary/command/fetch.rb +36 -0
  17. data/lib/cocoapods-jxedt/command/binary/command/push.rb +41 -0
  18. data/lib/cocoapods-jxedt/command/binary/command/statistics.rb +104 -0
  19. data/lib/cocoapods-jxedt/command/jxedt.rb +1 -1
  20. data/lib/cocoapods-jxedt/command/options/options.rb +85 -2
  21. data/lib/cocoapods-jxedt/gem_version.rb +1 -1
  22. data/lib/cocoapods-jxedt/git_helper/cache_fetcher.rb +34 -0
  23. data/lib/cocoapods-jxedt/git_helper/cache_pucher.rb +42 -0
  24. data/lib/cocoapods-jxedt/git_helper/git_command.rb +48 -0
  25. data/lib/cocoapods-jxedt/git_helper/zip.rb +22 -0
  26. metadata +14 -3
  27. data/lib/cocoapods-jxedt/command/statistics/statistics.rb +0 -98
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad01cd6bd2da4418b03764271caab2236a186ea81f3c9f77a885910d12263d78
4
- data.tar.gz: aa9f410bbbea81420a9d04f01c379428aece86e8449c9ec10a461a79d03825fe
3
+ metadata.gz: ce0b5536dca75bc86d6f3abb3769eb01f71c234d0c2297797c58c08c23d0708d
4
+ data.tar.gz: 3d35dbe1026d3e87251d35dab948d1b9f7ec8d2029b72c12a3689021d476fab8
5
5
  SHA512:
6
- metadata.gz: a0a5d962b702c2fde4f3ac10a81e027ba555f72310b31fee0530e94587eb7e56019ddf0d5e64951dd8f3c0e50626afbf286aa3c15b31a678bbb99413dcc5e8d1
7
- data.tar.gz: 60e70a3f5be60178cf721b4d69b113d065275eb415f70655feb718279b9b2ad9de3bfb8a9ce0a01050b2972a7c2346ef7bbcd723849054d40bf79dc7b84db124
6
+ metadata.gz: 273c9150c1d416861cb7d3e3722a440c5d3a52910cfcafbae3620f824ad7fae09834ff686b1925bfd02baccbbc0405cabd89f51a8484bbcc917771528c994cf5
7
+ data.tar.gz: 5393135f03f3443ee623fd56df1a4411c62d83f5cc2f4d8de5f67f687c9da3cfb6e6ccd45bd9e73fd38045c80fbd9e08fbed10555eafbc4586ad671be2f57be9
@@ -138,7 +138,7 @@ module Pod
138
138
  specs = self.analysis_result.specifications
139
139
  prebuilt_specs = (specs.select do |spec|
140
140
  # rmtree
141
- target_prebuild_files = self.sandbox.root + spec.root.name + "_Prebuild"
141
+ target_prebuild_files = self.sandbox.pod_dir(spec.name) + "_Prebuild"
142
142
  target_prebuild_files.rmtree if target_prebuild_files.exist?
143
143
 
144
144
  self.prebuild_pod_names.include? spec.root.name
@@ -149,18 +149,6 @@ module Pod
149
149
  checked_specs[spec.root.name] = [] if checked_specs[spec.root.name].nil?
150
150
  checked_specs[spec.root.name] << spec
151
151
 
152
- # Use the prebuild framworks as vendered frameworks
153
- # get_corresponding_targets
154
- targets = Pod.fast_get_targets_for_pod_name(spec.root.name, self.pod_targets, cache)
155
- targets.each do |target|
156
- # the framework_file_path rule is decided when `install_for_prebuild`,
157
- # as to compitable with older version and be less wordy.
158
- check_sandbox.prebuild_vendored_frameworks(spec.root.name).each do |frame_file_path|
159
- framework_file_path = "_Prebuild/" + frame_file_path
160
- framework_file_path = nil if checked_specs[spec.root.name].size > 1 # spec.root.name相同的只添加一次framework文件
161
- add_vendered_framework(spec, target.platform.name.to_s, framework_file_path)
162
- end
163
- end
164
152
  # Clean the source files
165
153
  # we just add the prebuilt framework to specific platform and set no source files
166
154
  # for all platform, so it doesn't support the sence that 'a pod perbuild for one
@@ -186,8 +174,25 @@ module Pod
186
174
  spec.attributes_hash["resources"] += prebuild_bundles
187
175
  end
188
176
 
177
+ # Use the prebuild framworks as vendered frameworks
178
+ # get_corresponding_targets
179
+ targets = Pod.fast_get_targets_for_pod_name(spec.root.name, self.pod_targets, cache)
180
+ targets.each do |target|
181
+ # the framework_file_path rule is decided when `install_for_prebuild`,
182
+ # as to compitable with older version and be less wordy.
183
+ check_sandbox.prebuild_vendored_frameworks(spec.root.name).each do |frame_file_path|
184
+ framework_file_path = "_Prebuild/" + frame_file_path
185
+ framework_file_path = nil if checked_specs[spec.root.name].size > 1 # spec.root.name相同的只添加一次framework文件
186
+ add_vendered_framework(spec, target.platform.name.to_s, framework_file_path)
187
+ end
188
+
189
+ # clear resource when target is a dynamic framework
190
+ spec.attributes_hash["resources"] = [] if target.build_as_dynamic_framework?
191
+ end
192
+
189
193
  # to avoid the warning of missing license
190
194
  spec.attributes_hash["license"] = {}
195
+ # keep all file in pods
191
196
  spec.attributes_hash["preserve_paths"] = "**/*"
192
197
 
193
198
  end
@@ -24,12 +24,22 @@ module Jxedt
24
24
  :device_build_enabled => "编译真机。默认true",
25
25
  :simulator_build_enabled => "编译模拟器。默认false",
26
26
  :disable_dsym => "禁止编译dsym产物。默认true",
27
+ :disable_resource_compilable_pods => "禁止编译有需要编译的resource文件(xib、xcdatamodeld等)的pod",
27
28
  :build_log_path => "编译的log输出路径",
28
29
  :build_args => "编译的配置。了解xcodebuild命令的可以配置编译参数,例如配置 ARCHS='arm64 armv7'",
30
+ :git_cache => 'git缓存配置,A Hash. 详情查看 GIT_CACHE_CONFIG'
29
31
  }.freeze
30
32
 
33
+ GIT_CACHE_CONFIG = {
34
+ :repo => '配置缓存仓库地址,如:{:remote => "https://github.com/user/cocoapods-cache.git", :local => "~/.cocoapods-jxedt/cocoapods-cache"},或者直接写远程仓库地址"https://github.com/user/cocoapods-cache.git"',
35
+ :branch => 'git cache的branch,默认是master分支',
36
+ :auto_fetch => 'pod install过程是否自动拉取远程的二进制,默认true',
37
+ :auto_push => 'pod install过程是否自动同步二进制结果到远程仓库,默认false',
38
+ }.freeze
39
+
31
40
  def initialize()
32
41
  @dsl_config = {}
42
+ @git_config = {}
33
43
  end
34
44
 
35
45
  def self.instance
@@ -108,6 +118,10 @@ module Jxedt
108
118
  @dsl_config[:disable_dsym] || @dsl_config[:disable_dsym].nil?
109
119
  end
110
120
 
121
+ def disable_resource_compilable_pods?
122
+ @dsl_config[:disable_resource_compilable_pods] || false
123
+ end
124
+
111
125
  def device_build_enabled?
112
126
  @dsl_config[:device_build_enabled] || @dsl_config[:device_build_enabled].nil?
113
127
  end
@@ -140,5 +154,53 @@ module Jxedt
140
154
  configurations
141
155
  end
142
156
  end
157
+
158
+ # git配置 ======================================= git配置
159
+ def git_cache_config
160
+ @git_cache ||= @dsl_config[:git_cache] || {}
161
+ end
162
+
163
+ def cache_repo
164
+ @cache_repo ||= begin
165
+ cache_repo = {}
166
+ user_config = git_cache_config[:repo]
167
+ cache_repo[:remote] = user_config if user_config.is_a?(String)
168
+ cache_repo.merge!(user_config) if user_config.is_a?(Hash)
169
+ cache_repo
170
+ end
171
+ end
172
+
173
+ def git_remote_repo
174
+ @remote ||= cache_repo[:remote]
175
+ end
176
+
177
+ def cache_repo_enabled?
178
+ remote = git_remote_repo
179
+ remote && remote.is_a?(String) && remote =~ /.*\.git$/
180
+ end
181
+
182
+ def git_cache_path
183
+ return nil unless cache_repo_enabled?
184
+
185
+ local = cache_repo[:local]
186
+ return File.expand_path(local) if local && local.is_a?(String) && local.split('/').size > 1
187
+
188
+ remote = git_remote_repo
189
+ repo_name = Pathname.new(remote).basename.sub_ext('').to_s
190
+ File.expand_path("~/.cocoapods-jxedt/#{repo_name}")
191
+ end
192
+
193
+ def auto_fetch?
194
+ git_cache_config[:auto_fetch] || git_cache_config[:auto_fetch].nil?
195
+ end
196
+
197
+ def auto_push?
198
+ git_cache_config[:auto_push]
199
+ end
200
+
201
+ def cache_branch
202
+ git_cache_config[:branch] || 'master'
203
+ end
204
+ # git配置 ======================================= git配置
143
205
  end
144
206
  end
@@ -0,0 +1,29 @@
1
+ module Pod
2
+ class Podfile
3
+ if Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.10.0')
4
+ # Calls the post install callback if defined.
5
+ #
6
+ # @param [Pod::Installer] installer
7
+ # the installer that is performing the installation.
8
+ #
9
+ # @return [Bool] whether a post install callback was specified and it was
10
+ # called.
11
+ #
12
+ # This allows the user to customize, for instance, the generated Xcode project _before_ it’s written to disk.
13
+ alias_method :old_post_install!, :post_install!
14
+ def post_install!(installer)
15
+ executed = old_post_install!(installer)
16
+ handle_pods_project_configurations!(installer) unless executed
17
+ executed
18
+ end
19
+
20
+ def handle_pods_project_configurations!(installer)
21
+ installer.pods_project.targets.each do |target|
22
+ target.build_configurations.each do |config|
23
+ config.build_settings["CODE_SIGN_IDENTITY"] = "" if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -6,20 +6,17 @@ module CocoapodsJxedtHook
6
6
  Jxedt::PreInstall.new(installer_context).run
7
7
  end
8
8
 
9
- Pod::HooksManager.register('cocoapods-jxedt', :pre_integrate) do |context, _|
10
-
11
- end
9
+ # Pod::HooksManager.register('cocoapods-jxedt', :pre_integrate) do |context, _|
10
+ # end
12
11
 
13
12
  Pod::HooksManager.register('cocoapods-jxedt', :post_install) do |context, _|
14
13
  require_relative 'post_install'
15
14
  Jxedt::PostInstall.new(context).run
16
15
  end
17
16
 
18
- Pod::HooksManager.register('cocoapods-jxedt', :post_integrate) do |context, _|
19
-
20
- end
17
+ # Pod::HooksManager.register('cocoapods-jxedt', :post_integrate) do |context, _|
18
+ # end
21
19
 
22
- Pod::HooksManager.register('cocoapods-jxedt', :source_provider) do |context, _|
23
-
24
- end
20
+ # Pod::HooksManager.register('cocoapods-jxedt', :source_provider) do |context, _|
21
+ # end
25
22
  end
@@ -14,7 +14,7 @@ module Jxedt
14
14
  validate_pod_checksum unless @installer_context.sandbox.is_a?(Pod::PrebuildSandbox)
15
15
  end
16
16
 
17
- def validate_pod_checksum
17
+ def validate_pod_checksum
18
18
  original_installer = ObjectSpace.each_object(Pod::Installer).reject {|installer| installer.sandbox.is_a?(Pod::PrebuildSandbox) }.first
19
19
  return if original_installer.nil?
20
20
 
@@ -28,7 +28,7 @@ module Jxedt
28
28
  value2 = source_lockfile.spec_checksums_hash_key(name)
29
29
  validation_failed << name if value1.nil? || value2.nil? || value1 != value2
30
30
  }
31
- Pod::UI.warn "Lockfile文件校验失败,请检查Pod组件: #{validation_failed}"
31
+ Pod::UI.warn "⚠️ ⚠️ ⚠️ Lockfile文件校验失败,请检查Pod组件: #{validation_failed}"
32
32
  end
33
33
  end
34
34
  end
@@ -16,10 +16,8 @@ module Jxedt
16
16
  # check binary switch
17
17
  return unless Jxedt.config.binary_switch?
18
18
 
19
- # [Check Environment]
20
- podfile = @installer_context.podfile
21
- podfile.target_definition_list.each do |target_definition|
22
- raise STDERR.puts "[!] Cocoapods-binary requires `use_frameworks!`".red if not target_definition.uses_frameworks?
19
+ unless Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.10.0')
20
+ raise STDERR.puts "[!] cocoapods-jxedt binary plugin should use cocoapods version greater than '1.10.0'`".red
23
21
  end
24
22
 
25
23
  require_relative '../helper/prebuild_sandbox'
@@ -29,8 +27,8 @@ module Jxedt
29
27
 
30
28
  # 获取原始的installer对象,必须先获取对象
31
29
  original_installer = ObjectSpace.each_object(Pod::Installer).first
32
- sandbox = Pod::PrebuildSandbox.from_standard_sandbox(@installer_context.sandbox)
33
- source_installer = Pod::Installer.new(sandbox, @installer_context.podfile, @installer_context.lockfile)
30
+ prebuild_sandbox = Pod::PrebuildSandbox.from_standard_sandbox(@installer_context.sandbox)
31
+ source_installer = Pod::Installer.new(prebuild_sandbox, @installer_context.podfile, @installer_context.lockfile)
34
32
  # 设置原始的installer携带的参数
35
33
  source_installer.update = original_installer.update
36
34
  source_installer.repo_update = original_installer.repo_update
@@ -38,18 +36,40 @@ module Jxedt
38
36
  source_installer.install!
39
37
 
40
38
  # 保存首次`pod install`的lockfile结果,用来验证二进制文件和后面做结果校验
41
- @installer_context.sandbox.source_lockfile = sandbox.source_lockfile = source_installer.lockfile
39
+ @installer_context.sandbox.source_lockfile = prebuild_sandbox.source_lockfile = source_installer.lockfile
42
40
 
43
41
  require_relative '../helper/podfile_options'
44
42
  require_relative '../prebuild'
45
43
 
44
+ # fetch cache and sync
45
+ if Jxedt.config.cache_repo_enabled? && Jxedt.config.auto_fetch?
46
+ log_section "🚗 Fetch git cache"
47
+ pods = prebuild_sandbox.source_lockfile.internal_data["SPEC CHECKSUMS"].keys
48
+ binary_hash = pods.reduce({}) do |hash, name|
49
+ checksum = prebuild_sandbox.source_lockfile.spec_checksums_hash_key(name)
50
+ hash.update(name => checksum) unless checksum.nil?
51
+ end
52
+
53
+ require 'cocoapods-jxedt/git_helper/cache_fetcher'
54
+ binary_dir = @installer_context.sandbox.root + Jxedt.config.binary_dir
55
+ Jxedt::CacheFetcher.sync(binary_hash, binary_dir)
56
+ end
57
+
46
58
  # prebuild_job
47
- sandbox.link_source_project!
59
+ prebuild_sandbox.link_source_project!
48
60
  if Jxedt.config.prebuild_job?
49
61
  log_section "🚀 Prebuild frameworks"
50
- Jxedt::Prebuild.new(source_installer).build
62
+ build_targets = Jxedt::Prebuild.new(source_installer).build
63
+
64
+ # cache push
65
+ if Jxedt.config.cache_repo_enabled? && Jxedt.config.auto_push? && build_targets && build_targets.size > 0
66
+ log_section "🚄 Push git cache"
67
+ require 'cocoapods-jxedt/git_helper/cache_pucher'
68
+ output_dir = prebuild_sandbox.root + Jxedt.config.binary_dir
69
+ Jxedt::CachePucher.push(output_dir, build_targets, false)
70
+ end
51
71
  end
52
- sandbox.clean_source_project!
72
+ prebuild_sandbox.clean_source_project!
53
73
 
54
74
  log_section "🤖 Resume pod installation"
55
75
  require_relative '../targets/pod_target'
@@ -1,3 +1,4 @@
1
1
  require_relative 'config'
2
2
  require_relative 'podfile_dsl'
3
3
  require_relative 'hooks/CocoapodsJxedtHook'
4
+ require_relative 'helper/podfile_post_install_hook'
@@ -0,0 +1,40 @@
1
+ module StaticFramework
2
+ class Tree
3
+ attr_reader :headers_path
4
+ attr_reader :private_headers_path
5
+ attr_reader :module_map_path
6
+ attr_reader :root_path
7
+ attr_reader :fwk_path
8
+
9
+ def initialize(name, at_path)
10
+ @name = name
11
+ @at_path = at_path
12
+ make
13
+ end
14
+
15
+ def make
16
+ make_root
17
+ make_framework
18
+ end
19
+
20
+ private
21
+ def make_framework
22
+ @fwk_path = @root_path + Pathname.new(@name + '.framework')
23
+ @fwk_path.rmtree if @fwk_path.exist?
24
+ @fwk_path.mkdir
25
+
26
+ @module_map_path = @fwk_path + Pathname.new('Modules')
27
+
28
+ @headers_path = @fwk_path + Pathname.new('Headers')
29
+ @headers_path.mkpath unless @headers_path.exist?
30
+
31
+ @private_headers_path = @fwk_path + Pathname.new('PrivateHeaders')
32
+ end
33
+
34
+ def make_root
35
+ @root_path = Pathname.new(@at_path)
36
+ @root_path.mkpath unless @root_path.exist?
37
+ end
38
+ end
39
+ end
40
+
@@ -19,9 +19,15 @@ module Jxedt
19
19
  end
20
20
 
21
21
  def run
22
- sdks.each { |sdk| build_for_sdk(sdk) }
22
+ sdks.each { |sdk|
23
+ build_for_sdk(sdk)
24
+ @options[:clean_build] = false # 如果需要编译真机和模拟器,那么第二次编译的时候不能clean
25
+ }
23
26
 
24
27
  targets.each do |target|
28
+ # create static framework with library
29
+ create_framework_from_library(target) if target.build_as_library?
30
+
25
31
  if Jxedt.config.xcframework?
26
32
  create_xcframework(target)
27
33
  elsif sdks.count > 1
@@ -83,10 +89,78 @@ module Jxedt
83
89
  sdk: sdk,
84
90
  deployment_target: targets.map { |t| t.platform.deployment_target }.max.to_s,
85
91
  log_path: log_path(sdk),
92
+ clean_build: clean_build?,
86
93
  args: sdk == simulator ? @build_args[:simulator] : @build_args[:device]
87
94
  )
88
95
  end
89
96
 
97
+ def create_framework_from_library(target)
98
+ require_relative 'framework'
99
+
100
+ sdks.each do |sdk|
101
+ procuct_dir = Pathname.new(target_products_dir_of(target, sdk))
102
+ # make static framework
103
+ fwk = StaticFramework::Tree.new(target.product_module_name, procuct_dir.to_s)
104
+
105
+ # copy library
106
+ lib_output = fwk.fwk_path + target.product_module_name
107
+ lib_file = procuct_dir + "lib#{target.name}.a"
108
+ `lipo -create -output #{lib_output} #{lib_file}` if lib_file.exist?
109
+
110
+ # copy public headers
111
+ headers_source = target.sandbox.headers_root + 'Public' + target.product_module_name
112
+ Dir.glob("#{headers_source}/**/*.h").each { |h| `ditto #{h} #{fwk.headers_path}/#{File.basename(h)}` }
113
+
114
+ # target support module
115
+ if target.defines_module?
116
+ # create modulemap path
117
+ fwk.module_map_path.mkpath unless fwk.module_map_path.exist?
118
+
119
+ # check and copy umbrella headers
120
+ umbrella_headers = Dir.glob("#{procuct_dir}/*-umbrella.h")
121
+ umbrella_headers.each { |h| FileUtils.cp_r(h.to_s, fwk.headers_path) }
122
+
123
+ # check and copy swift headers
124
+ swift_headers = Dir.glob("#{procuct_dir}/*/*-Swift.h")
125
+ swift_headers.each { |h| FileUtils.cp_r(h.to_s, fwk.headers_path) }
126
+
127
+ # check and copy swiftmodule files
128
+ swiftmodule_path = procuct_dir + "#{target.product_module_name}.swiftmodule"
129
+ FileUtils.cp_r(swiftmodule_path, fwk.module_map_path) if swiftmodule_path.exist?
130
+
131
+ # umbrella header name
132
+ header_name = "#{target.name}"
133
+ header_name = "#{target.name}-umbrella" if File.exist? "#{fwk.headers_path}/#{target.name}-umbrella.h"
134
+
135
+ # make modulemap
136
+ if File.exist?("#{fwk.headers_path}/#{header_name}.h")
137
+ module_map = <<MODULE_MAP
138
+ framework module #{target.product_module_name} {
139
+ umbrella header "#{header_name}.h"
140
+
141
+ export *
142
+ module * { export * }
143
+ }
144
+ MODULE_MAP
145
+ unless swift_headers.empty?
146
+ module_map << swift_module_map = <<SWIFT_MODULE_MAP
147
+ module #{target.product_module_name}.Swift {
148
+ header "#{target.product_module_name}-Swift.h"
149
+ requires objc
150
+ }
151
+ SWIFT_MODULE_MAP
152
+ end
153
+ File.write("#{fwk.module_map_path}/module.modulemap", module_map) unless module_map.nil?
154
+ end
155
+ end
156
+
157
+ # remove library product
158
+ procuct_dir.children.each do |child|
159
+ FileUtils.rm_rf(child) if ['.h', '.modulemap', '.a', '.swiftmodule'].include?(child.extname) || "#{child.basename}" == 'Swift Compatibility Header'
160
+ end
161
+ end
162
+ end
163
+
90
164
  def create_xcframework(target)
91
165
  non_framework_paths = Dir[target_products_dir_of(target, preferred_sdk) + "/*"] \
92
166
  - [framework_path_of(target, preferred_sdk)] \
@@ -261,5 +335,9 @@ module Jxedt
261
335
  def log_path(sdk)
262
336
  @options[:log_path].nil? ? nil : "#{@options[:log_path]}_#{sdk}"
263
337
  end
338
+
339
+ def clean_build?
340
+ @options[:clean_build]
341
+ end
264
342
  end
265
343
  end
@@ -34,7 +34,7 @@ module Jxedt
34
34
  end
35
35
  end
36
36
  cmd += options[:args] if options[:args]
37
- cmd += "clean" if options[:clean_build]
37
+ cmd << "clean" if options[:clean_build]
38
38
  cmd << "build"
39
39
 
40
40
  if options[:log_path].nil?
@@ -22,12 +22,19 @@ module Jxedt
22
22
  return [] if @sandbox_path.nil?
23
23
  return [] unless binary_dir.exist?
24
24
  return [] if @sandbox.source_lockfile.nil?
25
- @targets ||= binary_dir.children().map do |target_path|
26
- if target_path.directory? && (not target_path.children.empty?)
27
- hash_key = @sandbox.source_lockfile.spec_checksums_hash_key(target_path.basename.to_s)
28
- target_path if !(hash_key.nil?) && (target_path + "#{hash_key}.checksum").exist?
29
- end
30
- end.reject(&:nil?).uniq
25
+ @targets ||= begin
26
+ prebuild_targets = binary_dir.children().map do |target_path|
27
+ if target_path.directory? && (not target_path.children.empty?)
28
+ hash_key = @sandbox.source_lockfile.spec_checksums_hash_key(target_path.basename.to_s)
29
+ next if hash_key.nil?
30
+
31
+ checksum_files = target_path.children().select { |path| path.extname == '.checksum' }
32
+ checksum_exists = (target_path + "#{hash_key}.checksum").exist?
33
+ target_path if checksum_files.count == 1 && checksum_exists
34
+ end
35
+ end.reject(&:nil?).uniq
36
+ prebuild_targets
37
+ end
31
38
  @targets
32
39
  end
33
40
 
@@ -80,21 +87,44 @@ module Jxedt
80
87
  target.target_definition.reject_prebuild_pod_names
81
88
  }.uniq
82
89
 
90
+ targets = all_supports_targets.select { |target|
91
+ next if reject_prebuild_pod_names.include?(target.pod_name)
92
+ explicit_prebuild_pod_names.include?(target.pod_name) || Jxedt.config.all_binary_enabled?
93
+ }
94
+ targets
95
+ end
96
+
97
+ def all_supports_targets
83
98
  targets = @source_installer.pod_targets.select { |target|
99
+ # 排除不需要编译
84
100
  next unless target.should_build?
101
+ # 排除target name和pod name不一致的(有两种情况)
102
+ # 1. 同一个pod,在两个target下使用了不同的subspec
103
+ # 2. 同一个pod,在两个不同ios版本的target种引用
85
104
  next unless target.name == target.pod_name
86
- next if reject_prebuild_pod_names.include?(target.pod_name)
87
- explicit_prebuild_pod_names.include?(target.pod_name) || Jxedt.config.all_binary_enabled?
105
+ true
88
106
  }
107
+ # 排除本地pod
89
108
  targets.reject! { |target| @source_installer.sandbox.local?(target.pod_name) } unless Jxedt.config.dev_pods_enabled?
109
+ # 配置中排除的pods
90
110
  targets.reject! { |target| Jxedt.config.excluded_pods.include?(target.pod_name) }
111
+ # target中可能存在需要编译的resource文件
112
+ Jxedt.config.disable_resource_compilable_pods? && targets.reject! { |target|
113
+ # 因为编译library静态库会把需要编译的文件拷贝到宿主工程编译,后面我们要把静态库组装成framework,所以需要过滤掉
114
+ resource_extension_compilable = false
115
+ target.resource_paths.each {|name, resources|
116
+ resources.each {|resource_file|
117
+ resource_extname = Pathname.new(resource_file).basename.extname
118
+ resource_extension_compilable = target.class.resource_extension_compilable?(resource_extname)
119
+ break if resource_extension_compilable
120
+ }
121
+ break if resource_extension_compilable
122
+ }
123
+ resource_extension_compilable
124
+ }
91
125
  targets
92
126
  end
93
127
 
94
- def pods_to_prebuild
95
- targets_to_prebuild.map(&:name).to_a
96
- end
97
-
98
128
  def build
99
129
  check_sandbox = Jxedt::Sandbox.from_sandbox(@source_installer.sandbox)
100
130
  existed_target_names = check_sandbox.target_paths.map { |pair| pair.basename.to_s }
@@ -102,7 +132,7 @@ module Jxedt
102
132
 
103
133
  Pod::UI.puts "Prebuild total count: #{targets.size}"
104
134
  Pod::UI.puts "Prebuild targets: #{ targets.map(&:name)}"
105
- return if targets.empty?
135
+ return [] if targets.empty?
106
136
 
107
137
  require_relative 'pod-room/xcodebuild_command'
108
138
 
@@ -135,15 +165,63 @@ module Jxedt
135
165
 
136
166
  make_prebuild(targets)
137
167
  clear_output_path
168
+
169
+ targets.map(&:pod_name).to_a
170
+ end
171
+
172
+ def build_targets(names: nil, binary_output: nil)
173
+ targets = all_supports_targets
174
+ targets.select! { |target| names.include?(target.pod_name) } if names && names.is_a?(Array) && names.size > 0
175
+
176
+ Pod::UI.puts "Prebuild total count: #{targets.size}"
177
+ Pod::UI.puts "Prebuild targets: #{ targets.map(&:name)}"
178
+ return [] if targets.empty?
179
+
180
+ require_relative 'pod-room/xcodebuild_command'
181
+
182
+ clear_output_path
183
+ case targets[0].platform.name
184
+ when :ios, :tvos, :watchos
185
+ Jxedt.config.support_configurations.each do |configuration|
186
+ Pod::UI.puts "Prebuild configuration: #{configuration}"
187
+ options = make_options
188
+ options[:configuration] = configuration
189
+ options[:targets] = targets
190
+ options[:output_path] = output_path + configuration
191
+ Jxedt::XcodebuildCommand.new(options).run
192
+ end
193
+ when :osx
194
+ Jxedt.config.support_configurations.each do |configuration|
195
+ Pod::UI.puts "Prebuild configuration: #{configuration}"
196
+ options = make_options
197
+ xcodebuild(
198
+ sandbox: options[:sandbox],
199
+ targets: targets,
200
+ configuration: configuration,
201
+ sdk: "macosx",
202
+ clean_build: Jxedt.config.clean_build?,
203
+ args: options[:args]
204
+ )
205
+ end
206
+ else
207
+ raise "Unsupported platform for '#{targets[0].name}': '#{targets[0].platform.name}'"
208
+ end
209
+
210
+ binary_output = Pathname.new(binary_output)
211
+ make_prebuild(targets, binary_output)
212
+ clear_output_path
213
+
214
+ targets.map(&:pod_name).to_a
138
215
  end
139
216
 
140
- def make_prebuild(targets)
217
+ def make_prebuild(targets, binary_output=nil)
141
218
  lockfile = @source_installer.lockfile
142
219
  checksums = lockfile.internal_data["SPEC CHECKSUMS"] || {}
143
220
  checkout_options = lockfile.internal_data["CHECKOUT OPTIONS"] || {}
144
221
 
145
222
  # 目标binary路径
146
223
  binary_path = output_path.parent
224
+ binary_path = binary_output if binary_output && binary_output.parent.exist?
147
225
  prebuild_targets = targets.map(&:name).to_a
148
226
  prebuild_targets.map {|target_name|
149
227
  target_path = binary_path + target_name
@@ -0,0 +1,36 @@
1
+ require_relative 'command/statistics'
2
+ require_relative 'command/build'
3
+ require_relative 'command/fetch'
4
+ require_relative 'command/push'
5
+ require_relative 'command/clean'
6
+
7
+ module Pod
8
+ class Command
9
+ class JxedtCommand < Command
10
+ class Binary < JxedtCommand
11
+ self.summary = '二进制相关操作,二进制build、fetch、clean、statistics'
12
+ self.description = <<-DESC
13
+ 二进制相关操作,二进制build、fetch、push、statistics
14
+ DESC
15
+ self.command = 'binary'
16
+ self.abstract_command = true
17
+
18
+ self.arguments = [
19
+ ]
20
+ def self.options
21
+ []
22
+ end
23
+ def initialize(argv)
24
+ super
25
+ end
26
+
27
+ def validate!
28
+ super
29
+ end
30
+
31
+ def run
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end