cocoapods-util 0.0.16 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83da9a9a68fa2cc89f013255846c38e0ff5f7dd8631c96ac21555b4a30d58e14
4
- data.tar.gz: 39a88b6de2d54f2d68a3ae0b84727650a3b89fb006d5a3aa3f03eef7070d0f06
3
+ metadata.gz: ed124ed9b4a0655908453f9b89e4729a3eb97b630467ce449b736854c506b887
4
+ data.tar.gz: 1518420abc20def846321a27d5a593bd32daf39311d051f4e508928fb099ff5f
5
5
  SHA512:
6
- metadata.gz: 17ad6705b93f62ed103cccf0d8c102c684bc662506c682053b2e1c2120aa6f70522c24af830b1e7f8ac5148a6ae4096525889c4de1abab1d254d5f254d0db913
7
- data.tar.gz: '09847e25cdcd0f23b107322a2ab76fb47f792031824bce7d0ef369d161765c144c80c56f9b566cf5374f9e612c21a160c22577c73c863528803a9523bf6c7c2a'
6
+ metadata.gz: 33eaf3e82c99f71d98769fa3fa5490b66719ab02a4b46023ec8216381a127a07a9e73da868bb22797e76c5111789af095120e51043080accbe9ec998738f7e32
7
+ data.tar.gz: 147b2480fa760a6ca5003a9d5cac6a2b4165e6ac1dc02a6358b53c50e7574d6c188b5b00ae177156aae66239a95bc8e4c00f6f7660ec276d08c8afeb69807859
@@ -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,6 @@
1
- require_relative 'pre_install'
2
- require_relative 'post_install'
3
-
4
1
  module CocoapodsUtilHook
5
2
  Pod::HooksManager.register('cocoapods-util', :pre_install) do |installer_context, _|
3
+ require_relative 'pre_install'
6
4
  BinaryPrebuild::PreInstall.new(installer_context).run
7
5
  end
8
6
 
@@ -11,6 +9,7 @@ module CocoapodsUtilHook
11
9
  end
12
10
 
13
11
  Pod::HooksManager.register('cocoapods-util', :post_install) do |context, _|
12
+ require_relative 'post_install'
14
13
  BinaryPrebuild::PostInstall.new(context).run
15
14
  end
16
15
 
@@ -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,11 @@
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
4
+ def config_cocoapods_util(options)
5
+ BinaryPrebuild.config.dsl_config = options
6
+ BinaryPrebuild.config.validate_dsl_config
11
7
 
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)
8
+ require_relative 'helper/podfile_options'
24
9
  end
25
10
  end
26
11
  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.1"
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.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - guojiashuang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-17 00:00:00.000000000 Z
11
+ date: 2023-03-15 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