cocoapods-util 0.0.16 → 0.2.0

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: 83da9a9a68fa2cc89f013255846c38e0ff5f7dd8631c96ac21555b4a30d58e14
4
- data.tar.gz: 39a88b6de2d54f2d68a3ae0b84727650a3b89fb006d5a3aa3f03eef7070d0f06
3
+ metadata.gz: 656f35fa8c5fb7c2994fb8b454f010a9c3166b2b3a56ad75b9ccdfba7768829b
4
+ data.tar.gz: 33ff55946a88e29bfaaa0a0112af003702e0e33cee42449af79284fcaa8ebe90
5
5
  SHA512:
6
- metadata.gz: 17ad6705b93f62ed103cccf0d8c102c684bc662506c682053b2e1c2120aa6f70522c24af830b1e7f8ac5148a6ae4096525889c4de1abab1d254d5f254d0db913
7
- data.tar.gz: '09847e25cdcd0f23b107322a2ab76fb47f792031824bce7d0ef369d161765c144c80c56f9b566cf5374f9e612c21a160c22577c73c863528803a9523bf6c7c2a'
6
+ metadata.gz: ed695aae86dc40ab0a1661e4aefbe61c363a2c89eb15b401d238e489570c3a15f048f7e3422060ceff1b2159e5a9c1c07f777e50fc1d324bece09fddbe32234c
7
+ data.tar.gz: b51419985404992c9ddaaa707240c2ce0b61f2fce48cdb98f160e2f71148f1303be14d9b4c1c03b04f103928fef2598234489be674e375aa553fd11543a17ded
@@ -0,0 +1,300 @@
1
+ require_relative 'helper/podfile_options'
2
+ require_relative 'helper/names'
3
+ require_relative 'helper/target_checker'
4
+
5
+
6
+ # NOTE:
7
+ # This file will only be loaded on normal pod install step
8
+ # so there's no need to check is_prebuild_stage
9
+
10
+
11
+
12
+ # Provide a special "download" process for prebuilded pods.
13
+ #
14
+ # As the frameworks is already exsited in local folder. We
15
+ # just create a symlink to the original target folder.
16
+ #
17
+ module Pod
18
+ class Installer
19
+ class PodSourceInstaller
20
+
21
+ def install_for_prebuild!(standard_sanbox)
22
+ prebuild_sandbox = BinaryPrebuild::Sandbox.from_sandbox(standard_sanbox)
23
+ return if prebuild_sandbox.nil?
24
+ target_names = prebuild_sandbox.existed_target_names(self.name)
25
+
26
+ def walk(path, &action)
27
+ return unless path.exist?
28
+ path.children.each do |child|
29
+ result = action.call(child, &action)
30
+ if child.directory?
31
+ walk(child, &action) if result
32
+ end
33
+ end
34
+ end
35
+ def make_link(source, target)
36
+ source = Pathname.new(source)
37
+ target = Pathname.new(target)
38
+ target.parent.mkpath unless target.parent.exist?
39
+ relative_source = source.relative_path_from(target.parent)
40
+ FileUtils.ln_sf(relative_source, target)
41
+ end
42
+ def mirror_with_symlink(source, basefolder, target_folder)
43
+ relative_path = source.relative_path_from(basefolder)
44
+ if relative_path.to_s =~ /^(Debug|Release)\/.*/
45
+ new_relative_path = relative_path.to_s.gsub!(/^(Debug|Release)/) { |match| "#{BinaryPrebuild.config.xcconfig_replace_path}-#{match}" }
46
+ target = Pathname.new("#{target_folder}/#{new_relative_path}")
47
+ make_link(source, target)
48
+ else
49
+ target = Pathname.new("#{target_folder}/#{relative_path}")
50
+ make_link(source, target)
51
+ end
52
+ end
53
+
54
+ target_names.each do |name|
55
+
56
+ # symbol link copy all substructure
57
+ real_file_folder = prebuild_sandbox.framework_folder_path_for_target_name(name)
58
+
59
+ # If have only one platform, just place int the root folder of this pod.
60
+ # If have multiple paths, we use a sperated folder to store different
61
+ # platform frameworks. e.g. AFNetworking/AFNetworking-iOS/AFNetworking.framework
62
+
63
+ target_folder = standard_sanbox.pod_dir(self.name) + "_Prebuild"
64
+ target_folder.rmtree if target_folder.exist?
65
+ target_folder.mkpath
66
+
67
+
68
+ walk(real_file_folder) do |child|
69
+ source = child
70
+ # only make symlink to file and `.framework` folder
71
+ if child.directory? and [".framework", ".xcframework", ".bundle", ".dSYM"].include? child.extname
72
+ mirror_with_symlink(source, real_file_folder, target_folder)
73
+ next false # return false means don't go deeper
74
+ elsif child.file?
75
+ mirror_with_symlink(source, real_file_folder, target_folder)
76
+ next true
77
+ else
78
+ next true
79
+ end
80
+ end
81
+ end # of for each
82
+
83
+ end # of method
84
+
85
+ end
86
+ end
87
+ end
88
+
89
+
90
+ # Let cocoapods use the prebuild framework files in install process.
91
+ #
92
+ # the code only effect the second pod install process.
93
+ #
94
+ module Pod
95
+ class Installer
96
+ # Modify specification to use only the prebuild framework after analyzing
97
+ old_method2 = instance_method(:resolve_dependencies)
98
+ define_method(:resolve_dependencies) do
99
+ # call original
100
+ old_method2.bind(self).()
101
+ # ...
102
+ # ...
103
+ # ...
104
+ # after finishing the very complex orginal function
105
+
106
+ # check the pods
107
+ # Although we have did it in prebuild stage, it's not sufficient.
108
+ # Same pod may appear in another target in form of source code.
109
+ # Prebuild.check_one_pod_should_have_only_one_target(self.prebuild_pod_targets)
110
+ # self.validate_every_pod_only_have_one_form
111
+
112
+ # prepare
113
+ cache = []
114
+
115
+ def add_vendered_framework(spec, platform, added_framework_file_path)
116
+ if spec.attributes_hash[platform] == nil
117
+ spec.attributes_hash[platform] = {}
118
+ end
119
+ vendored_frameworks = spec.attributes_hash[platform]["vendored_frameworks"] || []
120
+ vendored_frameworks = [vendored_frameworks] if vendored_frameworks.kind_of?(String)
121
+ vendored_frameworks += [added_framework_file_path]
122
+ spec.attributes_hash[platform]["vendored_frameworks"] = vendored_frameworks
123
+ end
124
+ def empty_source_files(spec)
125
+ spec.attributes_hash["source_files"] = []
126
+ spec.attributes_hash["public_header_files"] = []
127
+ spec.attributes_hash["private_header_files"] = []
128
+ ["ios", "watchos", "tvos", "osx"].each do |plat|
129
+ if spec.attributes_hash[plat] != nil
130
+ spec.attributes_hash[plat]["source_files"] = []
131
+ spec.attributes_hash[plat]["public_header_files"] = []
132
+ spec.attributes_hash[plat]["private_header_files"] = []
133
+ end
134
+ end
135
+ end
136
+
137
+ prebuild_sandbox = BinaryPrebuild::Sandbox.from_sandbox(self.sandbox)
138
+ return if prebuild_sandbox.nil?
139
+
140
+ specs = self.analysis_result.specifications
141
+ prebuilt_specs = (specs.select do |spec|
142
+ # rmtree
143
+ target_prebuild_files = self.sandbox.root + spec.root.name + "_Prebuild"
144
+ target_prebuild_files.rmtree if target_prebuild_files.exist?
145
+
146
+ self.prebuild_pod_names.include? spec.root.name
147
+ end)
148
+
149
+ prebuilt_specs.each do |spec|
150
+
151
+ # Use the prebuild framworks as vendered frameworks
152
+ # get_corresponding_targets
153
+ targets = Pod.fast_get_targets_for_pod_name(spec.root.name, self.pod_targets, cache)
154
+ targets.each do |target|
155
+ # the framework_file_path rule is decided when `install_for_prebuild`,
156
+ # as to compitable with older version and be less wordy.
157
+ prebuild_sandbox.prebuild_vendored_frameworks(spec.root.name).each do |frame_file_path|
158
+ framework_file_path = "_Prebuild/" + frame_file_path
159
+ add_vendered_framework(spec, target.platform.name.to_s, framework_file_path)
160
+ end
161
+ end
162
+ # Clean the source files
163
+ # we just add the prebuilt framework to specific platform and set no source files
164
+ # for all platform, so it doesn't support the sence that 'a pod perbuild for one
165
+ # platform and not for another platform.'
166
+ empty_source_files(spec)
167
+
168
+ # to remove the resurce bundle target.
169
+ # When specify the "resource_bundles" in podspec, xcode will generate a bundle
170
+ # target after pod install. But the bundle have already built when the prebuit
171
+ # phase and saved in the framework folder. We will treat it as a normal resource
172
+ # file.
173
+ # https://github.com/leavez/cocoapods-binary/issues/29
174
+ if spec.attributes_hash["resource_bundles"]
175
+ # bundle_names = spec.attributes_hash["resource_bundles"].keys
176
+ spec.attributes_hash["resource_bundles"] = nil
177
+ spec.attributes_hash["resources"] ||= []
178
+ resources = spec.attributes_hash["resources"] || []
179
+ resources = [resources] if resources.kind_of?(String)
180
+ spec.attributes_hash["resources"] = resources
181
+ # spec.attributes_hash["resources"] += bundle_names.map{|n| n+".bundle"}
182
+ prebuild_bundles = prebuild_sandbox.prebuild_bundles(spec.root.name).each.map do |bundle_path|
183
+ "_Prebuild/" + bundle_path
184
+ end
185
+ spec.attributes_hash["resources"] += prebuild_bundles
186
+ end
187
+
188
+ # to avoid the warning of missing license
189
+ spec.attributes_hash["license"] = {}
190
+ spec.attributes_hash["preserve_paths"] = "**/*"
191
+
192
+ end
193
+
194
+ end
195
+
196
+
197
+ # Override the download step to skip download and prepare file in target folder
198
+ old_method = instance_method(:install_source_of_pod)
199
+ define_method(:install_source_of_pod) do |pod_name|
200
+
201
+ # copy from original
202
+ pod_installer = create_pod_installer(pod_name)
203
+ # \copy from original
204
+
205
+ # copy from original
206
+ pod_installer.install!
207
+ # \copy from original
208
+
209
+ if self.prebuild_pod_names.include? pod_name
210
+ pod_installer.install_for_prebuild!(self.sandbox)
211
+ end
212
+
213
+ # copy from original
214
+ @installed_specs.concat(pod_installer.specs_by_platform.values.flatten.uniq)
215
+ # \copy from original
216
+ end
217
+
218
+ alias_method :old_create_pod_installer, :create_pod_installer
219
+ def create_pod_installer(pod_name)
220
+ pod_installer = old_create_pod_installer(pod_name)
221
+
222
+ pods_to_install = sandbox_state.added | sandbox_state.changed
223
+ unless pods_to_install.include?(pod_name)
224
+ pod_installer.install_for_prebuild!(self.sandbox) if self.prebuild_pod_names.include? pod_name
225
+ end
226
+ pod_installer
227
+ end
228
+ end
229
+ end
230
+
231
+ # A fix in embeded frameworks script.
232
+ #
233
+ # The framework file in pod target folder is a symblink. The EmbedFrameworksScript use `readlink`
234
+ # to read the read path. As the symlink is a relative symlink, readlink cannot handle it well. So
235
+ # we override the `readlink` to a fixed version.
236
+ #
237
+ module Pod
238
+ module Generator
239
+ class EmbedFrameworksScript
240
+
241
+ old_method = instance_method(:script)
242
+ define_method(:script) do
243
+
244
+ script = old_method.bind(self).()
245
+ patch = <<-SH.strip_heredoc
246
+ #!/bin/sh
247
+
248
+ # ---- this is added by cocoapods-binary ---
249
+ # Readlink cannot handle relative symlink well, so we override it to a new one
250
+ # If the path isn't an absolute path, we add a realtive prefix.
251
+ old_read_link=`which readlink`
252
+ readlink () {
253
+ path=`$old_read_link "$1"`;
254
+ if [ $(echo "$path" | cut -c 1-1) = '/' ]; then
255
+ echo $path;
256
+ else
257
+ echo "`dirname $1`/$path";
258
+ fi
259
+ }
260
+ # ---
261
+ SH
262
+
263
+ # patch the rsync for copy dSYM symlink
264
+ script = script.gsub "rsync --delete", "rsync --copy-links --delete"
265
+
266
+ patch + script
267
+ end
268
+ end
269
+ end
270
+ end
271
+
272
+ module Pod
273
+ module Generator
274
+ class CopyXCFrameworksScript
275
+
276
+ alias_method :old_install_xcframework_args, :install_xcframework_args
277
+ def install_xcframework_args(xcframework, slices)
278
+ args = old_install_xcframework_args(xcframework, slices)
279
+ xcconfig_replace_path = BinaryPrebuild.config.xcconfig_replace_path
280
+ args.gsub!(/#{xcconfig_replace_path}-(Debug|Release)/, "#{xcconfig_replace_path}-${CONFIGURATION}")
281
+ args
282
+ end
283
+ end
284
+ end
285
+ end
286
+
287
+ module Pod
288
+ module Generator
289
+ class CopyResourcesScript
290
+
291
+ alias_method :old_script, :script
292
+ def script
293
+ script = old_script
294
+ xcconfig_replace_path = BinaryPrebuild.config.xcconfig_replace_path
295
+ script.gsub!(/#{xcconfig_replace_path}-(Debug|Release)/, "#{xcconfig_replace_path}-${CONFIGURATION}")
296
+ script
297
+ end
298
+ end
299
+ end
300
+ end
@@ -4,20 +4,49 @@ module BinaryPrebuild
4
4
  end
5
5
 
6
6
  class Config
7
- attr_accessor :enable_all, :enable_targets
8
-
7
+ attr_accessor :dsl_config
8
+
9
+ APPLICABLE_DSL_CONFIG = [
10
+ :all_binary,
11
+ :binary_dir,
12
+ :dev_pods_enabled,
13
+ :xcconfig_replace_path,
14
+ ].freeze
15
+
9
16
  def initialize()
10
- @enable_all = false
11
- @enable_targets = []
17
+ @dsl_config = {}
12
18
  end
13
19
 
14
20
  def self.instance
15
21
  @instance ||= new()
16
22
  end
17
23
 
18
- def add_enable_target(name)
19
- @enable_targets.push name
20
- @enable_targets.uniq!
24
+ def validate_dsl_config
25
+ inapplicable_options = @dsl_config.keys - APPLICABLE_DSL_CONFIG
26
+ return if inapplicable_options.empty?
27
+
28
+ message = <<~HEREDOC
29
+ [WARNING] The following options (in `config_cocoapods_util`) are not correct: #{inapplicable_options}.
30
+ Available options: #{APPLICABLE_DSL_CONFIG}.
31
+ HEREDOC
32
+
33
+ Pod::UI.puts message.yellow
34
+ end
35
+
36
+ def all_binary_enable?
37
+ @dsl_config[:all_binary] || false
38
+ end
39
+
40
+ def dev_pods_enabled?
41
+ @dsl_config[:dev_pods_enabled] || false
42
+ end
43
+
44
+ def binary_dir
45
+ @dsl_config[:binary_dir] || '_Prebuild'
46
+ end
47
+
48
+ def xcconfig_replace_path
49
+ @dsl_config[:xcconfig_replace_path] || "cocoapods-util-binary"
21
50
  end
22
51
  end
23
52
  end
@@ -0,0 +1,78 @@
1
+ # ABOUT NAMES
2
+ #
3
+ # There are many kinds of name in cocoapods. Two main names are widely used in this plugin.
4
+ # - root_spec.name (spec.root_name, targe.pod_name):
5
+ # aka "pod_name"
6
+ # the name we use in podfile. the concept.
7
+ #
8
+ # - target.name:
9
+ # aka "target_name"
10
+ # the name of the final target in xcode project. the final real thing.
11
+ #
12
+ # One pod may have multiple targets in xcode project, due to one pod can be used in mutiple
13
+ # platform simultaneously. So one `root_spec.name` may have multiple coresponding `target.name`s.
14
+ # Therefore, map a spec to/from targets is a little complecated. It's one to many.
15
+ #
16
+
17
+ # Tool to transform Pod_name to target efficiently
18
+ module Pod
19
+ def self.fast_get_targets_for_pod_name(pod_name, targets, cache)
20
+ pod_name_to_targets_hash = nil
21
+ if cache.empty?
22
+ pod_name_to_targets_hash = targets.reduce({}) do |sum, target|
23
+ array = sum[target.pod_name] || []
24
+ array << target
25
+ sum[target.pod_name] = array
26
+ sum
27
+ end
28
+ cache << pod_name_to_targets_hash
29
+ else
30
+ pod_name_to_targets_hash = cache.first
31
+ end
32
+
33
+ pod_name_to_targets_hash[pod_name] || []
34
+ end
35
+ end
36
+
37
+
38
+
39
+
40
+
41
+
42
+ # Target:
43
+
44
+ # def pod_name
45
+ # root_spec.name
46
+ # end
47
+
48
+ # def name
49
+ # pod_name + #{scope_suffix}
50
+ # end
51
+
52
+ # def product_module_name
53
+ # root_spec.module_name
54
+ # end
55
+
56
+ # def framework_name
57
+ # "#{product_module_name}.framework"
58
+ # end
59
+
60
+ # def product_name
61
+ # if requires_frameworks?
62
+ # framework_name
63
+ # else
64
+ # static_library_name
65
+ # end
66
+ # end
67
+
68
+ # def product_basename
69
+ # if requires_frameworks?
70
+ # product_module_name
71
+ # else
72
+ # label
73
+ # end
74
+ # end
75
+
76
+ # def framework_name
77
+ # "#{product_module_name}.framework"
78
+ # end
@@ -0,0 +1,120 @@
1
+
2
+ module Pod
3
+ class Podfile
4
+ class TargetDefinition
5
+ def detect_prebuilt_pod(name, requirements)
6
+ options = requirements.last || {}
7
+
8
+ # prebuild
9
+ @explicit_prebuild_pod_names ||= []
10
+ @reject_prebuild_pod_names ||= []
11
+ @explicit_prebuild_pod_names << Specification.root_name(name) if options.is_a?(Hash) && options[:binary]
12
+ @reject_prebuild_pod_names << Specification.root_name(name) if options.is_a?(Hash) && options.include?(:binary) && !options[:binary]
13
+
14
+ # header search path
15
+ @explicit_header_search_pod_names ||= []
16
+ @reject_header_search_pod_names ||= []
17
+ @explicit_header_search_pod_names << Specification.root_name(name) if options.is_a?(Hash) && options[:framework_search_header]
18
+ @reject_header_search_pod_names << Specification.root_name(name) if options.is_a?(Hash) && options.include?(:framework_search_header) && !options[:framework_search_header]
19
+
20
+ options.delete(:binary) if options.is_a?(Hash)
21
+ options.delete(:framework_search_header) if options.is_a?(Hash)
22
+ requirements.pop if options.empty?
23
+ end
24
+
25
+ # Returns the names of pod targets explicitly declared as prebuilt in Podfile using `:binary => true`.
26
+ def explicit_prebuild_pod_names
27
+ names = @explicit_prebuild_pod_names || []
28
+ names += parent.explicit_prebuild_pod_names if !parent.nil? && parent.is_a?(TargetDefinition)
29
+ names
30
+ end
31
+
32
+ def reject_prebuild_pod_names
33
+ names = @reject_prebuild_pod_names || []
34
+ names += parent.reject_prebuild_pod_names if !parent.nil? && parent.is_a?(TargetDefinition)
35
+ names
36
+ end
37
+
38
+ def explicit_header_search_pod_names
39
+ names = @explicit_header_search_pod_names || []
40
+ names += parent.explicit_header_search_pod_names if !parent.nil? && parent.is_a?(TargetDefinition)
41
+ names
42
+ end
43
+
44
+ def reject_header_search_pod_names
45
+ names = @reject_header_search_pod_names || []
46
+ names += parent.reject_header_search_pod_names if !parent.nil? && parent.is_a?(TargetDefinition)
47
+ names
48
+ end
49
+
50
+ # ---- patch method ----
51
+ # We want modify `store_pod` method, but it's hard to insert a line in the
52
+ # implementation. So we patch a method called in `store_pod`.
53
+ original_parse_inhibit_warnings = instance_method(:parse_inhibit_warnings)
54
+ define_method(:parse_inhibit_warnings) do |name, requirements|
55
+ detect_prebuilt_pod(name, requirements)
56
+ original_parse_inhibit_warnings.bind(self).call(name, requirements)
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ module Pod
63
+ class Installer
64
+ # Returns the names of pod targets detected as prebuilt, including
65
+ # those declared in Podfile and their dependencies
66
+ def prebuild_pod_names
67
+ prebuilt_pod_targets.map(&:name).to_set
68
+ end
69
+
70
+ # Returns the pod targets detected as prebuilt, including
71
+ # those declared in Podfile and their dependencies
72
+ def prebuilt_pod_targets
73
+ @prebuilt_pod_targets ||= begin
74
+ explicit_prebuild_pod_names = aggregate_targets.flat_map { |target|
75
+ target.target_definition.explicit_prebuild_pod_names
76
+ }.uniq
77
+
78
+ reject_prebuild_pod_names = aggregate_targets.flat_map { |target|
79
+ target.target_definition.reject_prebuild_pod_names
80
+ }.uniq
81
+
82
+ available_pod_names = []
83
+ prebuild_sandbox = BinaryPrebuild::Sandbox.from_sandbox(self.sandbox)
84
+ available_pod_names = prebuild_sandbox.target_paths.map {|path| path.basename.to_s } unless prebuild_sandbox.nil?
85
+ if BinaryPrebuild.config.all_binary_enable?
86
+ explicit_prebuild_pod_names = available_pod_names
87
+ else
88
+ explicit_prebuild_pod_names = (explicit_prebuild_pod_names & available_pod_names).uniq
89
+ end
90
+ explicit_prebuild_pod_names -= reject_prebuild_pod_names
91
+
92
+ targets = pod_targets.select { |target|
93
+ explicit_prebuild_pod_names.include?(target.pod_name)
94
+ }
95
+ targets = targets.reject { |target| sandbox.local?(target.pod_name) } unless BinaryPrebuild.config.dev_pods_enabled?
96
+ targets.map { |target| target.use_binary = true }
97
+ targets
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ module Pod
104
+ class Target
105
+ attr_accessor :use_binary
106
+
107
+ def frame_header_search_paths_enable?
108
+ return true if self.use_binary
109
+ header_search_pod_names.include? self.name
110
+ end
111
+
112
+ def header_search_pod_names
113
+ @explicit_header_search_pod_names ||= begin
114
+ target_definitions.flat_map { |target_definition|
115
+ target_definition.explicit_header_search_pod_names - target_definition.reject_header_search_pod_names
116
+ }.uniq
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,49 @@
1
+
2
+ module Pod
3
+ class Prebuild
4
+
5
+ # Check the targets, for the current limitation of the plugin
6
+ #
7
+ # @param [Array<PodTarget>] prebuilt_targets
8
+ def self.check_one_pod_should_have_only_one_target(prebuilt_targets)
9
+
10
+ targets_have_different_platforms = prebuilt_targets.select {|t| t.pod_name != t.name }
11
+
12
+ if targets_have_different_platforms.count > 0
13
+ names = targets_have_different_platforms.map(&:pod_name)
14
+ raw_names = targets_have_different_platforms.map(&:name)
15
+ message = "Oops, you came across a limitation of cocoapods-binary.
16
+
17
+ The plugin requires that one pod should have ONLY ONE target in the 'Pod.xcodeproj'. There are mainly 2 situations \
18
+ causing this problem:
19
+
20
+ 1. One pod integrates in 2 or more different platforms' targets. e.g.
21
+ ```
22
+ target 'iphoneApp' do
23
+ pod 'A', :binary => true
24
+ end
25
+ target 'watchApp' do
26
+ pod 'A'
27
+ end
28
+ ```
29
+
30
+ 2. Use different subspecs in multiple targets. e.g.
31
+ ```
32
+ target 'iphoneApp' do
33
+ pod 'A/core'
34
+ pod 'A/network'
35
+ end
36
+ target 'iphoneAppTest' do
37
+ pod 'A/core'
38
+ end
39
+ ```
40
+
41
+ Related pods: #{names}, target names: #{raw_names}
42
+ "
43
+ raise Informative, message
44
+ end
45
+ end
46
+
47
+
48
+ end
49
+ end
@@ -1,8 +1,8 @@
1
- require_relative 'pre_install'
2
- require_relative 'post_install'
1
+ require_relative '../helper/podfile_options'
3
2
 
4
3
  module CocoapodsUtilHook
5
4
  Pod::HooksManager.register('cocoapods-util', :pre_install) do |installer_context, _|
5
+ require_relative 'pre_install'
6
6
  BinaryPrebuild::PreInstall.new(installer_context).run
7
7
  end
8
8
 
@@ -11,6 +11,7 @@ module CocoapodsUtilHook
11
11
  end
12
12
 
13
13
  Pod::HooksManager.register('cocoapods-util', :post_install) do |context, _|
14
+ require_relative 'post_install'
14
15
  BinaryPrebuild::PostInstall.new(context).run
15
16
  end
16
17
 
@@ -1,5 +1,3 @@
1
- require_relative '../targets/pod_target'
2
-
3
1
  module BinaryPrebuild
4
2
  class PreInstall
5
3
  def initialize(installer_context)
@@ -8,13 +6,16 @@ module BinaryPrebuild
8
6
 
9
7
  def run
10
8
  # [Check Environment]
11
- # podfile = @installer_context.podfile
12
- # podfile.target_definition_list.each do |target_definition|
13
- # if not target_definition.uses_frameworks?
14
- # STDERR.puts "[!] Cocoapods-binary requires `use_frameworks!`".red
15
- # exit
16
- # end
17
- # end
9
+ podfile = @installer_context.podfile
10
+ podfile.target_definition_list.each do |target_definition|
11
+ if not target_definition.uses_frameworks?
12
+ STDERR.puts "[!] Cocoapods-binary requires `use_frameworks!`".red
13
+ exit
14
+ end
15
+ end
16
+
17
+ require_relative '../targets/pod_target'
18
+ require_relative '../Intergation'
18
19
  end
19
20
  end
20
21
  end
@@ -1,26 +1,9 @@
1
1
  module Pod
2
2
  class Podfile
3
3
  module DSL
4
- def self.enable_framework_header_keyword
5
- :enable_framework_header
6
- end
7
-
8
- def enable_all_framework_header!(enable: true)
9
- BinaryPrebuild.config.enable_all = enable
10
- end
11
-
12
- # hook
13
- old_method = instance_method(:pod)
14
- define_method(:pod) do |name, *args|
15
- enable = BinaryPrebuild.config.enable_all
16
- options = args.last
17
- keyword = DSL.enable_framework_header_keyword
18
- if options.is_a?(Hash) && options[keyword] != nil
19
- enable = options.delete(keyword)
20
- args.pop if options.empty?
21
- end
22
- BinaryPrebuild.config.add_enable_target name.to_s.gsub(/\/.*$/, '') if enable
23
- old_method.bind(self).(name, *args)
4
+ def config_cocoapods_util(options)
5
+ BinaryPrebuild.config.dsl_config = options
6
+ BinaryPrebuild.config.validate_dsl_config
24
7
  end
25
8
  end
26
9
  end
@@ -1,3 +1,66 @@
1
1
  module BinaryPrebuild
2
+ class Sandbox
3
+ def initialize(path)
4
+ @sandbox_path = path
5
+ end
2
6
 
7
+ def self.from_sandbox(sandbox)
8
+ root = sandbox.root
9
+ search_path = BinaryPrebuild.config.binary_dir
10
+ if !search_path.nil? && !search_path.empty?
11
+ path = File.expand_path(root + search_path)
12
+ if File.exist? path
13
+ return Sandbox.new(path)
14
+ end
15
+ end
16
+ end
17
+
18
+ def binary_dir
19
+ @binary_dir ||= Pathname.new(@sandbox_path)
20
+ end
21
+
22
+ def target_paths
23
+ return [] unless binary_dir.exist?
24
+ @targets ||= binary_dir.children().map do |target_path|
25
+ if target_path.directory? && (not target_path.children.empty?)
26
+ target_path
27
+ end
28
+ end.reject(&:nil?).uniq
29
+ @targets
30
+ end
31
+
32
+ def existed_target_names(name)
33
+ target_paths.select { |pair| "#{pair.basename}" == "#{name}" }.map { |pair| pair.basename }
34
+ end
35
+
36
+ def framework_folder_path_for_target_name(name)
37
+ target_paths.select { |pair| pair.basename == name }.last
38
+ end
39
+
40
+ def prebuild_vendored_frameworks(name)
41
+ target_path = target_paths.select { |pair| "#{pair.basename}" == "#{name}" }.last
42
+ return [] if target_path.nil?
43
+
44
+ configuration_enable = target_path.children().select { |path| "#{path.basename}" == 'Debug' || "#{path.basename}" == 'Release' }.count == 2
45
+ if configuration_enable
46
+ xcconfig_replace_path = BinaryPrebuild.config.xcconfig_replace_path
47
+ ["#{xcconfig_replace_path}-Release/*.{framework,xcframework}"]
48
+ else
49
+ ["*.{framework,xcframework}"]
50
+ end
51
+ end
52
+
53
+ def prebuild_bundles(name)
54
+ target_path = target_paths.select { |pair| "#{pair.basename}" == "#{name}" }.last
55
+ return [] if target_path.nil?
56
+
57
+ configuration_enable = target_path.children().select { |path| "#{path.basename}" == 'Debug' || "#{path.basename}" == 'Release' }.count == 2
58
+ if configuration_enable
59
+ xcconfig_replace_path = BinaryPrebuild.config.xcconfig_replace_path
60
+ ["#{xcconfig_replace_path}-Release/*.bundle"]
61
+ else
62
+ ["*.bundle"]
63
+ end
64
+ end
65
+ end
3
66
  end
@@ -4,7 +4,7 @@ module Pod
4
4
  class BuildSettings
5
5
  # missing framework header search paths
6
6
  def missing_framework_header_search_path(pt)
7
- return [] unless BinaryPrebuild.config.enable_targets.include? pt.name
7
+ return [] unless pt.frame_header_search_paths_enable?
8
8
 
9
9
  paths = []
10
10
  pt.file_accessors.each do |file_accessor|
@@ -47,9 +47,27 @@ module Pod
47
47
  paths.push "${PODS_ROOT}/#{header_path.relative_path_from(pt.sandbox.root)}"
48
48
  }
49
49
  end
50
+ replace_xcconfig_configuration_paths(paths)
50
51
  paths.uniq
51
52
  end
52
53
 
54
+ # replace different configuration xcconfig
55
+ def replace_xcconfig_configuration_paths(paths)
56
+ xcconfig_replace_path = BinaryPrebuild.config.xcconfig_replace_path
57
+ paths.map! { |path|
58
+ if path =~ /#{xcconfig_replace_path}-(Debug|Release)/
59
+ configuration = @configuration.to_s.downcase
60
+ if configuration == 'debug'
61
+ path.gsub!(/#{xcconfig_replace_path}-(Debug|Release)/, "#{xcconfig_replace_path}-Debug")
62
+ elsif configuration == 'release'
63
+ path.gsub!(/#{xcconfig_replace_path}-(Debug|Release)/, "#{xcconfig_replace_path}-Release")
64
+ end
65
+ end
66
+ path
67
+ }
68
+ paths
69
+ end
70
+
53
71
  # A subclass that generates build settings for a `PodTarget`
54
72
  class AggregateTargetSettings
55
73
  # @return [Array<String>]
@@ -70,6 +88,16 @@ module Pod
70
88
  header_search_paths.concat dependent_targets.flat_map { |pt| missing_framework_header_search_path(pt) } if target.should_build?
71
89
  header_search_paths.uniq
72
90
  end
91
+
92
+ # 按照规则替换framework_search_paths,兼容不同的configuration
93
+ # 从编译上来说,仅仅替换了framework_search_paths的路径就够了
94
+ # @return [Array<String>]
95
+ alias_method :old_raw_framework_search_paths, :_raw_framework_search_paths
96
+ def _raw_framework_search_paths
97
+ framework_search_paths = old_raw_framework_search_paths
98
+ replace_xcconfig_configuration_paths(framework_search_paths)
99
+ framework_search_paths
100
+ end
73
101
  end
74
102
  end
75
103
  end
@@ -15,16 +15,13 @@ module Pod
15
15
 
16
16
  def self.options
17
17
  [
18
- ['--force', '覆盖已经存在的文件'],
19
- ['--create-swiftinterface', '有编译swift文件的framework,如果不包含swiftinterface则无法生成xcframework。
20
- 设置该参数会生成一个swiftinterface文件解决create失败的问题。']
18
+ ['--force', '覆盖已经存在的文件']
21
19
  ]
22
20
  end
23
21
 
24
22
  def initialize(argv)
25
23
  @file_path = argv.shift_argument
26
24
  @force = argv.flag?('force')
27
- @create_swiftinterface = argv.flag?('create-swiftinterface')
28
25
  super
29
26
  end
30
27
 
@@ -55,8 +52,7 @@ module Pod
55
52
 
56
53
  builder = XCFrameworkBuilder.new(
57
54
  framework_name,
58
- source_dir,
59
- @create_swiftinterface
55
+ source_dir
60
56
  )
61
57
  builder.build_static_xcframework
62
58
  end
@@ -1,9 +1,8 @@
1
1
  module Pod
2
2
  class XCFrameworkBuilder
3
- def initialize(name, source_dir, create_swiftinterface)
3
+ def initialize(name, source_dir)
4
4
  @name = name
5
5
  @source_dir = source_dir
6
- @create_swiftinterface = create_swiftinterface
7
6
  end
8
7
 
9
8
  def build_static_xcframework
@@ -57,7 +56,7 @@ module Pod
57
56
  # 2. copy os framework
58
57
  if os_archs.count > 0
59
58
  path = Pathname.new("#{@source_dir}/#{os_target_path}")
60
- path.mkdir unless path.exist?
59
+ FileUtils.mkdir_p(path) unless path.exist?
61
60
  `cp -a #{framework_path} #{path}/`
62
61
 
63
62
  fwk_path = "#{path}/#{@name}.framework"
@@ -67,7 +66,7 @@ module Pod
67
66
  # 3. copy simulation framework
68
67
  if sim_archs.count > 0
69
68
  path = Pathname.new("#{@source_dir}/#{simulator_target_path}")
70
- path.mkdir unless path.exist?
69
+ FileUtils.mkdir_p(path) unless path.exist?
71
70
  `cp -a #{framework_path} #{path}/`
72
71
 
73
72
  fwk_path = "#{path}/#{@name}.framework"
@@ -86,23 +85,8 @@ module Pod
86
85
  def generate_xcframework(framework_paths)
87
86
  UI.puts("Generate #{@name}.xcframework")
88
87
 
89
- framework_paths.each { |framework_path|
90
- # check_swiftmodule
91
- swiftmodule_path = Dir.glob("#{framework_path}/Modules/*.swiftmodule").first
92
- unless swiftmodule_path.nil?
93
- if Dir.glob("#{swiftmodule_path}/*.swiftinterface").empty?
94
- unless @create_swiftinterface
95
- UI.puts "Framework中包含swiftmodule文件,但是没有swiftinterface,无法创建xcframework,请检查Framework文件。或者使用`--create-swiftinterface`参数"
96
- return
97
- end
98
- arm_swiftinterface = Pathname.new("#{swiftmodule_path}/arm.swiftinterface")
99
- File.new(arm_swiftinterface, "w+").close
100
- end
101
- end
102
- }
103
-
104
- # build xcframework
105
- command = "xcodebuild -create-xcframework -framework #{framework_paths.join(' -framework ')} -output #{@source_dir}/#{@name}.xcframework 2>&1"
88
+ # create xcframework
89
+ command = "xcodebuild -create-xcframework -allow-internal-distribution -framework #{framework_paths.join(' -framework ')} -output #{@source_dir}/#{@name}.xcframework 2>&1"
106
90
  output = `#{command}`.lines.to_a
107
91
  result = $?
108
92
  # show error
@@ -115,19 +99,19 @@ module Pod
115
99
 
116
100
  private
117
101
  def clean_intermediate_path
118
- [os_target_path, simulator_target_path].each do |path|
119
- file_path = "#{@source_dir}/#{path}"
120
- if File.exist? file_path
121
- FileUtils.rm_rf(file_path)
122
- end
123
- end
102
+ file_path = "#{@source_dir}/#{temp_intermediate_path}"
103
+ FileUtils.rm_rf(file_path) if File.exist? file_path
104
+ end
105
+
106
+ def temp_intermediate_path
107
+ "__temp_create_xcframework_dir"
124
108
  end
125
109
 
126
110
  def os_target_path
127
- "#{@name}_temp_os"
111
+ "#{temp_intermediate_path}/#{@name}_os"
128
112
  end
129
113
  def simulator_target_path
130
- "#{@name}_temp_simulator"
114
+ "#{temp_intermediate_path}/#{@name}_simulator"
131
115
  end
132
116
  end
133
117
  end
@@ -1,3 +1,3 @@
1
1
  module CocoapodsUtil
2
- VERSION = "0.0.16"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocoapods-util
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.16
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - guojiashuang
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-17 00:00:00.000000000 Z
11
+ date: 2023-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cocoapods
@@ -68,7 +68,11 @@ files:
68
68
  - LICENSE
69
69
  - README.md
70
70
  - lib/cocoapods-util.rb
71
+ - lib/cocoapods-util/binary/Intergation.rb
71
72
  - lib/cocoapods-util/binary/config.rb
73
+ - lib/cocoapods-util/binary/helper/names.rb
74
+ - lib/cocoapods-util/binary/helper/podfile_options.rb
75
+ - lib/cocoapods-util/binary/helper/target_checker.rb
72
76
  - lib/cocoapods-util/binary/hooks/CocoapodsUtilHook.rb
73
77
  - lib/cocoapods-util/binary/hooks/post_install.rb
74
78
  - lib/cocoapods-util/binary/hooks/pre_install.rb
@@ -103,7 +107,7 @@ homepage: https://github.com/CaryGo/cocoapods-util
103
107
  licenses:
104
108
  - MIT
105
109
  metadata: {}
106
- post_install_message:
110
+ post_install_message:
107
111
  rdoc_options: []
108
112
  require_paths:
109
113
  - lib
@@ -119,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
123
  version: '0'
120
124
  requirements: []
121
125
  rubygems_version: 3.1.2
122
- signing_key:
126
+ signing_key:
123
127
  specification_version: 4
124
128
  summary: 一个常用插件功能的集合,致力于解决日常开发中遇到的一些问题。
125
129
  test_files: []