cocoapods-hd 0.0.3 → 0.1.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.
@@ -0,0 +1,130 @@
1
+ module Pod
2
+
3
+ class Prebuild
4
+ def self.keyword
5
+ :binary
6
+ end
7
+ end
8
+
9
+ class Podfile
10
+ class TargetDefinition
11
+
12
+ ## --- option for setting using prebuild framework ---
13
+ def parse_prebuild_framework(name, requirements)
14
+ should_prebuild = Pod::Podfile::DSL.is_all_binary
15
+
16
+ options = requirements.last
17
+ if options.is_a?(Hash) && options[Pod::Prebuild.keyword] != nil
18
+ should_prebuild = options.delete(Pod::Prebuild.keyword)
19
+ requirements.pop if options.empty?
20
+ end
21
+
22
+ pod_name = Specification.root_name(name)
23
+ set_prebuild_for_pod(pod_name, should_prebuild)
24
+ end
25
+
26
+ def set_prebuild_for_pod(pod_name, should_prebuild)
27
+
28
+ if should_prebuild == true
29
+ @prebuild_framework_pod_names ||= []
30
+ Pod::UI.puts "prebuild_framework_pod_names -------- :#{@prebuild_framework_pod_names}"
31
+ @prebuild_framework_pod_names.push pod_name
32
+ else
33
+ @should_not_prebuild_framework_pod_names ||= []
34
+ @should_not_prebuild_framework_pod_names.push pod_name
35
+ end
36
+ end
37
+
38
+ def prebuild_framework_pod_names
39
+ names = @prebuild_framework_pod_names || []
40
+ if parent != nil and parent.kind_of? TargetDefinition
41
+ names += parent.prebuild_framework_pod_names
42
+ end
43
+ names
44
+ end
45
+ def should_not_prebuild_framework_pod_names
46
+ names = @should_not_prebuild_framework_pod_names || []
47
+ if parent != nil and parent.kind_of? TargetDefinition
48
+ names += parent.should_not_prebuild_framework_pod_names
49
+ end
50
+ names
51
+ end
52
+
53
+ # ---- patch method ----
54
+ # We want modify `store_pod` method, but it's hard to insert a line in the
55
+ # implementation. So we patch a method called in `store_pod`.
56
+ # old_method = instance_method(:parse_inhibit_warnings)
57
+ #
58
+ # define_method(:parse_inhibit_warnings) do |name, requirements|
59
+ # parse_prebuild_framework(name, requirements)
60
+ # old_method.bind(self).(name, requirements)
61
+ # end
62
+
63
+ end
64
+ end
65
+ end
66
+
67
+
68
+ module Pod
69
+ class Installer
70
+
71
+ def prebuild_pod_targets
72
+ @prebuild_pod_targets ||= (
73
+ all = []
74
+
75
+ aggregate_targets = self.aggregate_targets
76
+ aggregate_targets.each do |aggregate_target|
77
+ target_definition = aggregate_target.target_definition
78
+ targets = aggregate_target.pod_targets || []
79
+
80
+ # filter prebuild
81
+ prebuild_names = target_definition.prebuild_framework_pod_names
82
+ if not Podfile::DSL.is_all_binary
83
+ targets = targets.select { |pod_target| prebuild_names.include?(pod_target.pod_name) }
84
+ end
85
+ dependency_targets = targets.map {|t| t.recursive_dependent_targets }.flatten.uniq || []
86
+ targets = (targets + dependency_targets).uniq
87
+
88
+ # filter should not prebuild
89
+ explict_should_not_names = target_definition.should_not_prebuild_framework_pod_names
90
+ targets = targets.reject { |pod_target| explict_should_not_names.include?(pod_target.pod_name) }
91
+
92
+ all += targets
93
+ end
94
+
95
+ all = all.reject {|pod_target| sandbox.local?(pod_target.pod_name) }
96
+ all.uniq
97
+ )
98
+ end
99
+
100
+ # the root names who needs prebuild, including dependency pods.
101
+ def prebuild_pod_names
102
+ @prebuild_pod_names ||= self.prebuild_pod_targets.map(&:pod_name)
103
+ end
104
+
105
+
106
+ def validate_every_pod_only_have_one_form
107
+
108
+ multi_targets_pods = self.pod_targets.group_by do |t|
109
+ t.pod_name
110
+ end.select do |k, v|
111
+ v.map{|t| t.platform.name }.count > 1
112
+ end
113
+
114
+ multi_targets_pods = multi_targets_pods.reject do |name, targets|
115
+ contained = targets.map{|t| self.prebuild_pod_targets.include? t }
116
+ contained.uniq.count == 1 # all equal
117
+ end
118
+
119
+ return if multi_targets_pods.empty?
120
+
121
+ warnings = "One pod can only be prebuilt or not prebuilt. These pod have different forms in multiple targets:\n"
122
+ warnings += multi_targets_pods.map{|name, targets| " #{name}: #{targets.map{|t|t.platform.name}}"}.join("\n")
123
+ raise Informative, warnings
124
+ end
125
+
126
+ end
127
+ end
128
+
129
+
130
+
@@ -0,0 +1,73 @@
1
+ require_relative "names"
2
+
3
+ module Pod
4
+ class PrebuildSandbox < Sandbox
5
+
6
+ # [String] standard_sandbox_path
7
+ def self.from_standard_sanbox_path(path)
8
+ prebuild_sandbox_path = Pathname.new(path).realpath + "_Prebuild"
9
+ self.new(prebuild_sandbox_path)
10
+ end
11
+
12
+ def self.from_standard_sandbox(sandbox)
13
+ self.from_standard_sanbox_path(sandbox.root)
14
+ end
15
+
16
+ def standard_sanbox_path
17
+ self.root.parent
18
+ end
19
+
20
+ def generate_framework_path
21
+ self.root + "GeneratedFrameworks"
22
+ end
23
+
24
+ # @param name [String] pass the target.name (may containing platform suffix)
25
+ # @return [Pathname] the folder containing the framework file.
26
+ def framework_folder_path_for_target_name(name)
27
+ self.generate_framework_path + name
28
+ end
29
+
30
+ def exsited_framework_target_names
31
+ exsited_framework_name_pairs.map { |pair| pair[0] }.uniq
32
+ end
33
+
34
+ def exsited_framework_pod_names
35
+ exsited_framework_name_pairs.map { |pair| pair[1] }.uniq
36
+ end
37
+
38
+ def existed_target_names_for_pod_name(pod_name)
39
+ exsited_framework_name_pairs.select { |pair| pair[1] == pod_name }.map { |pair| pair[0] }
40
+ end
41
+
42
+ def save_pod_name_for_target(target)
43
+ folder = framework_folder_path_for_target_name(target.name)
44
+ return unless folder.exist?
45
+ # flag_file_path: /Users/xingyong/Desktop/debug-binary/HDTestKit/Example/Pods/_Prebuild/GeneratedFrameworks/SVProgressHUD/SVProgressHUD.pod_name
46
+ flag_file_path = folder + "#{target.pod_name}.pod_name"
47
+
48
+ File.write(flag_file_path.to_s, "")
49
+ end
50
+
51
+ private
52
+
53
+ def pod_name_for_target_folder(target_folder_path)
54
+ name = Pathname.new(target_folder_path).children.find do |child|
55
+ child.to_s.end_with? ".pod_name"
56
+ end
57
+ name = name.basename(".pod_name").to_s unless name.nil?
58
+ name ||= Pathname.new(target_folder_path).basename.to_s # for compatibility with older version
59
+ end
60
+
61
+ # Array<[target_name, pod_name]>
62
+ def exsited_framework_name_pairs
63
+ return [] unless generate_framework_path.exist?
64
+ generate_framework_path.children().map do |framework_path|
65
+ if framework_path.directory? && (not framework_path.children.empty?)
66
+ [framework_path.basename.to_s, pod_name_for_target_folder(framework_path)]
67
+ else
68
+ nil
69
+ end
70
+ end.reject(&:nil?).uniq
71
+ end
72
+ end
73
+ 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
@@ -0,0 +1,226 @@
1
+ # encoding: UTF-8
2
+ require_relative 'helper/podfile_options'
3
+ require_relative 'tool/tool'
4
+
5
+ module Pod
6
+ class Podfile
7
+ module DSL
8
+
9
+ # Enable prebuiding for all pods
10
+ # it has a lower priority to other binary settings
11
+ def hd_all_binary!
12
+ DSL.is_all_binary = true
13
+ end
14
+
15
+ def hd_use_source_pods(pods)
16
+ DSL.source_pods = Array(pods)
17
+ end
18
+
19
+ # Enable bitcode for prebuilt frameworks
20
+ def enable_bitcode_for_prebuilt_frameworks!
21
+ DSL.bitcode_enabled = true
22
+ end
23
+
24
+ # Don't remove source code of prebuilt pods
25
+ # It may speed up the pod install if git didn't
26
+ # include the `Pods` folder
27
+ def keep_source_code_for_prebuilt_frameworks!
28
+ DSL.dont_remove_source_code = true
29
+ end
30
+
31
+ # Add custom xcodebuild option to the prebuilding action
32
+ #
33
+ # You may use this for your special demands. For example: the default archs in dSYMs
34
+ # of prebuilt frameworks is 'arm64 armv7 x86_64', and no 'i386' for 32bit simulator.
35
+ # It may generate a warning when building for a 32bit simulator. You may add following
36
+ # to your podfile
37
+ #
38
+ # ` set_custom_xcodebuild_options_for_prebuilt_frameworks :simulator => "ARCHS=$(ARCHS_STANDARD)" `
39
+ #
40
+ # Another example to disable the generating of dSYM file:
41
+ #
42
+ # ` set_custom_xcodebuild_options_for_prebuilt_frameworks "DEBUG_INFORMATION_FORMAT=dwarf"`
43
+ #
44
+ #
45
+ # @param [String or Hash] options
46
+ #
47
+ # If is a String, it will apply for device and simulator. Use it just like in the commandline.
48
+ # If is a Hash, it should be like this: { :device => "XXXXX", :simulator => "XXXXX" }
49
+ #
50
+ def set_custom_xcodebuild_options_for_prebuilt_frameworks(options)
51
+ if options.kind_of? Hash
52
+ DSL.custom_build_options = [options[:device]] unless options[:device].nil?
53
+ DSL.custom_build_options_simulator = [options[:simulator]] unless options[:simulator].nil?
54
+ elsif options.kind_of? String
55
+ DSL.custom_build_options = [options]
56
+ DSL.custom_build_options_simulator = [options]
57
+ else
58
+ raise "Wrong type."
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ # 是否全部二进库
65
+ class_attr_accessor :is_all_binary
66
+ is_all_binary = false
67
+
68
+ class_attr_accessor :bitcode_enabled
69
+ bitcode_enabled = false
70
+
71
+ class_attr_accessor :dont_remove_source_code
72
+ dont_remove_source_code = false
73
+
74
+ class_attr_accessor :custom_build_options
75
+ class_attr_accessor :custom_build_options_simulator
76
+ self.custom_build_options = []
77
+ self.custom_build_options_simulator = []
78
+
79
+ # 用户指定源码集合
80
+ class_attr_accessor :source_pods
81
+ source_pods = []
82
+
83
+ end
84
+ end
85
+ end
86
+
87
+ def run_pod_install
88
+ podfile = Pathname.new('Podfile')
89
+ if !podfile.exist?
90
+ STDERR.puts "[!] Podfile file did not exist".red
91
+ exit
92
+ end
93
+ argvs = []
94
+ gen = Pod::Command::Install.new(CLAide::ARGV.new(argvs))
95
+ gen.validate!
96
+ gen.run
97
+ end
98
+
99
+ # Pod::HooksManager.register('cocoapods-hd', :post_install) do |installer_context|
100
+ #
101
+ # Pod::UI.puts "cocoapods-hd: post_install"
102
+ # if Pod.is_ignore_hook_install == nil || Pod.is_ignore_hook_install == true
103
+ # Pod::UI.puts "cocoapods-hd: hook post_install"
104
+ # next
105
+ # end
106
+ # # installer_context.pods_project -> Xcodeproj::Project
107
+ # installer_context.pods_project.targets.each do |target|
108
+ # target.build_configurations.each do |config|
109
+ # if config.name == 'Release'
110
+ # config.build_settings['ARCHS'] = "$(ARCHS_STANDARD)"
111
+ # end
112
+ # end
113
+ # end
114
+ # installer_context.pods_project.save
115
+ # Pod::UI.puts "cocoapods-hd: set build configurations"
116
+ # end
117
+ #
118
+ Pod::HooksManager.register('cocoapods-hd', :pre_install) do |installer_context|
119
+
120
+ require_relative 'helper/feature_switches'
121
+ require_relative 'resolver'
122
+
123
+ Pod::UI.puts "cocoapods-hd: pre_install"
124
+
125
+ if !Pod.is_prebuild_stage
126
+ Pod::UI.puts "cocoapods-hd: update repo"
127
+
128
+ sources_manager = Pod::Config.instance.sources_manager
129
+ argvs = [sources_manager.binary_source.name]
130
+ repo_update = Pod::Command::Repo::Update.new(CLAide::ARGV.new(argvs))
131
+ repo_update.validate!
132
+ repo_update.run
133
+ end
134
+
135
+ if Pod.is_ignore_hook_install == nil || Pod.is_ignore_hook_install == true
136
+ Pod::UI.puts "cocoapods-hd: hook pre_install"
137
+ next
138
+ end
139
+
140
+ if Pod.is_prebuild_stage
141
+ next
142
+ end
143
+
144
+ # [Check Environment]
145
+ # check user_framework is on
146
+ podfile = installer_context.podfile
147
+ podfile.target_definition_list.each do |target_definition|
148
+
149
+ next if target_definition.prebuild_framework_pod_names.empty?
150
+ if not target_definition.uses_frameworks?
151
+ STDERR.puts "[!] Cocoapods-hd requires `use_frameworks!`".red
152
+ exit
153
+ end
154
+ end
155
+
156
+ # -- step 1: prebuild framework ---
157
+ # Execute a sperated pod install, to generate targets for building framework,
158
+ # then compile them to framework files.
159
+ require_relative 'helper/prebuild_sandbox'
160
+ require_relative 'prebuild'
161
+
162
+ Pod::UI.puts "️🍎 Prebuild frameworks"
163
+
164
+ # Fetch original installer (which is running this pre-install hook) options,
165
+ # then pass them to our installer to perform update if needed
166
+ # Looks like this is the most appropriate way to figure out that something should be updated
167
+
168
+ update = nil
169
+ repo_update = nil
170
+
171
+ include ObjectSpace
172
+ ObjectSpace.each_object(Pod::Installer) { |installer|
173
+ update = installer.update
174
+ repo_update = installer.repo_update
175
+ }
176
+
177
+ # control features
178
+ Pod.is_prebuild_stage = true
179
+ Pod::Podfile::DSL.enable_prebuild_patch true # enable sikpping for prebuild targets
180
+ Pod::Installer.force_disable_integration true # don't integrate targets
181
+ Pod::Config.force_disable_write_lockfile true # disbale write lock file for perbuild podfile
182
+ Pod::Installer.disable_install_complete_message true # disable install complete message
183
+
184
+ # make another custom sandbox
185
+ standard_sandbox = installer_context.sandbox
186
+ prebuild_sandbox = Pod::PrebuildSandbox.from_standard_sandbox(standard_sandbox)
187
+
188
+ # get the podfile for prebuild
189
+ prebuild_podfile = Pod::Podfile.from_ruby(podfile.defined_in_file)
190
+ prebuild_podfile.use_frameworks!(:linkage => :static)
191
+ # Pod::UI.puts "prebuild_podfile --------- : #{prebuild_podfile}"
192
+
193
+ # install
194
+ lockfile = installer_context.lockfile
195
+ # Pod::UI.puts "lockfile --------- : #{lockfile}"
196
+
197
+ binary_installer = Pod::Installer.new(prebuild_sandbox, prebuild_podfile, lockfile)
198
+ # Pod::UI.puts "binary_installer --------- : #{binary_installer}"
199
+
200
+ binary_installer.have_exact_prebuild_cache?
201
+ binary_installer.install!
202
+
203
+ # if binary_installer.have_exact_prebuild_cache? && !update
204
+ # binary_installer.install_when_cache_hit!
205
+ # else
206
+ # binary_installer.update = update
207
+ # binary_installer.repo_update = repo_update
208
+ # binary_installer.install!
209
+ # end
210
+
211
+ # reset the environment
212
+ Pod.is_prebuild_stage = false
213
+ Pod::Installer.force_disable_integration false
214
+ Pod::Podfile::DSL.enable_prebuild_patch false
215
+ Pod::Config.force_disable_write_lockfile false
216
+ Pod::Installer.disable_install_complete_message false
217
+ Pod::UserInterface.warnings = [] # clean the warning in the prebuild step, it's duplicated.
218
+
219
+ # -- step 2: pod install ---
220
+ # install
221
+ Pod::UI.puts "\n"
222
+ Pod::UI.puts "🍓 Pod Install"
223
+ require_relative 'Integration'
224
+ # go on the normal install step ...
225
+ end
226
+