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,333 @@
1
+ require_relative 'build/build_framework'
2
+ require_relative 'helper/passer'
3
+ require_relative 'helper/target_checker'
4
+ require_relative 'upload/upload_helper'
5
+
6
+ # patch prebuild ability
7
+ module Pod
8
+ class Installer
9
+
10
+ private
11
+
12
+ def local_manifest
13
+ if not @local_manifest_inited
14
+ @local_manifest_inited = true
15
+ raise "This method should be call before generate project" unless self.analysis_result == nil
16
+ @local_manifest = self.sandbox.manifest
17
+ end
18
+ @local_manifest
19
+ end
20
+
21
+ # @return [Analyzer::SpecsState]
22
+ def prebuild_pods_changes
23
+ return nil if local_manifest.nil?
24
+ if @prebuild_pods_changes.nil?
25
+ changes = local_manifest.detect_changes_with_podfile(podfile)
26
+ @prebuild_pods_changes = Analyzer::SpecsState.new(changes)
27
+ # save the chagnes info for later stage
28
+ Pod::Prebuild::Passer.prebuild_pods_changes = @prebuild_pods_changes
29
+ end
30
+ @prebuild_pods_changes
31
+ end
32
+
33
+ public
34
+
35
+ # check if need to prebuild
36
+ def have_exact_prebuild_cache?
37
+ # check if need build frameworks
38
+ return false if local_manifest == nil
39
+
40
+ changes = prebuild_pods_changes
41
+ added = changes.added
42
+ changed = changes.changed
43
+ unchanged = changes.unchanged
44
+ deleted = changes.deleted
45
+
46
+ exsited_framework_pod_names = sandbox.exsited_framework_pod_names
47
+ missing = unchanged.select do |pod_name|
48
+ not exsited_framework_pod_names.include?(pod_name)
49
+ end
50
+
51
+ needed = (added + changed + deleted + missing)
52
+ return needed.empty?
53
+ end
54
+
55
+ # The install method when have completed cache
56
+ def install_when_cache_hit!
57
+ # just print log
58
+ self.sandbox.exsited_framework_target_names.each do |name|
59
+ UI.puts "Using #{name}"
60
+ end
61
+ end
62
+
63
+ # Build the needed framework files
64
+ def prebuild_frameworks!
65
+
66
+ # build options
67
+ sandbox_path = sandbox.root
68
+ existed_framework_folder = sandbox.generate_framework_path
69
+ bitcode_enabled = Pod::Podfile::DSL.bitcode_enabled
70
+
71
+ if local_manifest != nil
72
+
73
+ changes = prebuild_pods_changes
74
+ added = changes.added
75
+ changed = changes.changed
76
+ unchanged = changes.unchanged
77
+ deleted = changes.deleted
78
+
79
+ existed_framework_folder.mkdir unless existed_framework_folder.exist?
80
+ exsited_framework_pod_names = sandbox.exsited_framework_pod_names
81
+
82
+ # additions
83
+ missing = unchanged.select do |pod_name|
84
+ not exsited_framework_pod_names.include?(pod_name)
85
+ end
86
+
87
+ root_names_to_update = (added + changed + missing)
88
+
89
+ # transform names to targets
90
+ cache = []
91
+ targets = root_names_to_update.map do |pod_name|
92
+ tars = Pod.fast_get_targets_for_pod_name(pod_name, self.pod_targets, cache)
93
+ if tars.nil? || tars.empty?
94
+ raise "There's no target named (#{pod_name}) in Pod.xcodeproj.\n #{self.pod_targets.map(&:name)}" if t.nil?
95
+ end
96
+ tars
97
+ end.flatten
98
+
99
+ # add the dendencies
100
+ dependency_targets = targets.map { |t| t.recursive_dependent_targets }.flatten.uniq || []
101
+ targets = (targets + dependency_targets).uniq
102
+ else
103
+ targets = self.pod_targets
104
+ end
105
+
106
+ # STDERR.puts "targets ------- : #{targets}".cyan
107
+ # 移除local target, ps: HDTestKit
108
+ # targets = targets.reject { |pod_target| sandbox.local?(pod_target.pod_name) }
109
+
110
+ unless Prebuild::Passer.target_names.nil?
111
+ targets = targets.select { |pod_target| Prebuild::Passer.target_names.include? pod_target.pod_name }
112
+ end
113
+
114
+ Pod::UI.puts "Prebuild frameworks (total #{targets.count})"
115
+ Pod::Prebuild.remove_build_dir(sandbox_path)
116
+
117
+ targets.each do |target|
118
+
119
+ STDERR.puts "开始build: #{target.name} ,should_build: #{target.should_build?} "
120
+
121
+ # fix: 注释掉下面方法,否则Pod::Prebuild.build不执行
122
+ if !target.should_build?
123
+ # STDERR.puts "prebuilding: --------- #{target.label}"
124
+ next
125
+ end
126
+
127
+ output_path = sandbox.framework_folder_path_for_target_name(target.name)
128
+ output_path.mkpath unless output_path.exist?
129
+ STDERR.puts "output_path : ------ #{output_path}".yellow
130
+
131
+ Pod::Prebuild.build(sandbox_path, target, output_path, bitcode_enabled, Podfile::DSL.custom_build_options, Podfile::DSL.custom_build_options_simulator)
132
+
133
+ # save the resource paths for later installing
134
+ if !target.resource_paths.empty?
135
+ # fix: framework_path 添加 target.name
136
+ framework_path = output_path + target.framework_name
137
+ standard_sandbox_path = sandbox.standard_sanbox_path
138
+
139
+ resources = begin
140
+ if Pod::VERSION.start_with? "1.5"
141
+ target.resource_paths
142
+ else
143
+ # resource_paths is Hash{String=>Array<String>} on 1.6 and above
144
+ # (use AFNetworking to generate a demo data)
145
+ # https://github.com/leavez/cocoapods-binary/issues/50
146
+ target.resource_paths.values.flatten
147
+ end
148
+ end
149
+ raise "Wrong type: #{resources}" unless resources.kind_of? Array
150
+
151
+ path_objects = resources.map do |path|
152
+ object = Prebuild::Passer::ResourcePath.new
153
+ object.real_file_path = framework_path + File.basename(path)
154
+ STDERR.puts "framework_path------ #{framework_path}".yellow
155
+
156
+ object.target_file_path = path.gsub('${PODS_ROOT}', standard_sandbox_path.to_s + "/_Prebuild") if path.start_with? '${PODS_ROOT}'
157
+ # object.target_file_path = path.gsub('${PODS_ROOT}', standard_sandbox_path.to_s) if path.start_with? '${PODS_ROOT}'
158
+ # object.target_file_path = path.gsub("${PODS_CONFIGURATION_BUILD_DIR}", standard_sandbox_path.to_s) if path.start_with? "${PODS_CONFIGURATION_BUILD_DIR}"
159
+ object
160
+ end
161
+ Prebuild::Passer.resources_to_copy_for_static_framework[target.name] = path_objects
162
+ end
163
+
164
+ end
165
+
166
+ # copy vendored libraries and frameworks
167
+ targets.each do |target|
168
+ root_path = self.sandbox.pod_dir(target.name)
169
+ target_folder = sandbox.framework_folder_path_for_target_name(target.name)
170
+
171
+ # If target shouldn't build, we copy all the original files
172
+ # This is for target with only .a and .h files
173
+
174
+ if not target.should_build?
175
+ Prebuild::Passer.target_names_to_skip_integration_framework << target.name
176
+ STDERR.puts "copy vendored libraries and frameworks ------ #{root_path}, #{target_folder}".yellow
177
+ FileUtils.cp_r(root_path, target_folder, :remove_destination => true)
178
+ next
179
+ end
180
+
181
+ target.spec_consumers.each do |consumer|
182
+ file_accessor = Sandbox::FileAccessor.new(root_path, consumer)
183
+ lib_paths = file_accessor.vendored_frameworks || []
184
+ lib_paths += file_accessor.vendored_libraries
185
+
186
+ # @TODO dSYM files
187
+ lib_paths.each do |lib_path|
188
+ relative = lib_path.relative_path_from(root_path)
189
+ destination = target_folder + relative
190
+ UI.puts "destination ------- #{destination}"
191
+ destination.dirname.mkpath unless destination.dirname.exist?
192
+ FileUtils.cp_r(lib_path, destination, :remove_destination => true)
193
+ end
194
+
195
+ # 将destination替换成target_folder,不需要全路径还原
196
+ # 需要将外部依赖的vendored_frameworks和vendored_libraries复制到target的同级目录中
197
+ lib_paths.each do |lib_path|
198
+ UI.puts "lib_path ----- #{lib_path}"
199
+ relative = lib_path.relative_path_from(root_path)
200
+ destination = target_folder + relative
201
+ destination.dirname.mkpath unless destination.dirname.exist?
202
+ FileUtils.cp_r(lib_path, target_folder, :remove_destination => true)
203
+ end
204
+
205
+ end
206
+ end
207
+
208
+ targets.each do |target|
209
+ target_name = target.name
210
+ module_name = target.product_module_name
211
+ hash = Prebuild::Passer.resources_to_copy_for_static_framework || {}
212
+ # 将podspec.resource资源复制到framework里面 ps: SVProgerssHUD
213
+ path_objects = hash[target_name]
214
+ if path_objects != nil
215
+ path_objects.each do |object|
216
+ if object.target_file_path != nil
217
+ UI.puts "target_file_path --- #{object.target_file_path}"
218
+ UI.puts "real_file_path ------ #{object.real_file_path}"
219
+ FileUtils.cp_r(object.target_file_path, object.real_file_path, :remove_destination => true)
220
+ end
221
+ end
222
+ end
223
+
224
+ output_path = sandbox.framework_folder_path_for_target_name(target.name)
225
+ output_path.mkpath unless output_path.exist?
226
+
227
+ sandbox_root = Pathname(sandbox_path)
228
+ build_dir = sandbox_root.parent + 'build'
229
+
230
+ bundle_path = "#{build_dir}/Release-iphoneos/#{module_name}/*.bundle"
231
+ if Dir[bundle_path].any?
232
+ FileUtils.cp_r Dir.glob(bundle_path), output_path, verbose: true
233
+ end
234
+
235
+ originPath = Dir.pwd
236
+
237
+ Dir.chdir(output_path) {
238
+
239
+ zipTargetFramework = "#{target_name}.zip"
240
+ frameworkFileType = "#{output_path}/*.framework"
241
+ bundleFileType = "#{output_path}/*.bundle"
242
+ staticLibraryFileType = "#{output_path}/*.a"
243
+ zipFiles = ""
244
+ if Dir[bundleFileType].any?
245
+ zipFiles += " *.bundle "
246
+ end
247
+ if Dir[frameworkFileType].any?
248
+ zipFiles += " *.framework "
249
+ end
250
+ if Dir[staticLibraryFileType].any?
251
+ zipFiles += " *.a "
252
+ end
253
+ # puts "output_path: zipTargetFramework-------- #{output_path}, #{zipTargetFramework}, zipfile: #{zipFiles}"
254
+ `zip -r #{zipTargetFramework} #{zipFiles}`
255
+ %x[`cd #{originPath}`]
256
+ }
257
+
258
+ end
259
+ Pod::Prebuild.remove_build_dir(sandbox_path)
260
+
261
+ # 上传zip包和二进制repo
262
+ targets.each do |target|
263
+ root_spec = target.specs.select { |spec|
264
+ spec.root?
265
+ }.first
266
+
267
+ UI.puts "上传zip包和二进制repo ------- #{root_spec}"
268
+
269
+ if !root_spec.nil?
270
+ #output_path: ~/Example/Pods/_Prebuild/GeneratedFrameworks/MBProgressHUD
271
+ output_path = sandbox.framework_folder_path_for_target_name(target.name)
272
+ output_path.mkpath unless output_path.exist?
273
+ UI.puts "output_path ------- #{output_path}"
274
+
275
+ # 上传二进库的podspec
276
+ upload_binary(root_spec, output_path)
277
+ end
278
+
279
+ end
280
+
281
+ # save the pod_name for prebuild framwork in sandbox
282
+ targets.each do |target|
283
+ sandbox.save_pod_name_for_target target
284
+ end
285
+
286
+ # Remove useless files
287
+ # remove useless pods
288
+ all_needed_names = self.pod_targets.map(&:name).uniq
289
+ useless_target_names = sandbox.exsited_framework_target_names.reject do |name|
290
+ all_needed_names.include? name
291
+ end
292
+ useless_target_names.each do |name|
293
+ path = sandbox.framework_folder_path_for_target_name(name)
294
+ path.rmtree if path.exist?
295
+ end
296
+
297
+ if not Podfile::DSL.dont_remove_source_code
298
+ # only keep manifest.lock and framework folder in _Prebuild
299
+ to_remain_files = ["Manifest.lock", File.basename(existed_framework_folder)]
300
+ to_delete_files = sandbox_path.children.select do |file|
301
+ filename = File.basename(file)
302
+ not to_remain_files.include?(filename)
303
+ end
304
+ to_delete_files.each do |path|
305
+ path.rmtree if path.exist?
306
+ end
307
+ else
308
+ # just remove the tmp files
309
+ path = sandbox.root + 'Manifest.lock.tmp'
310
+ path.rmtree if path.exist?
311
+ end
312
+
313
+ end
314
+
315
+ # 上传二进库
316
+ def upload_binary(root_spec, output_path)
317
+ puts "开始上传 ------------------------------- "
318
+ upload_helper = CocoapodsHd::UploadHelper.new(root_spec, output_path)
319
+ upload_helper.spec_creator
320
+ upload_helper.upload
321
+ end
322
+
323
+ # patch the post install hook
324
+ old_method2 = instance_method(:run_plugins_post_install_hooks)
325
+ define_method(:run_plugins_post_install_hooks) do
326
+ old_method2.bind(self).()
327
+ if Pod::is_prebuild_stage
328
+ self.prebuild_frameworks!
329
+ end
330
+ end
331
+
332
+ end
333
+ end
@@ -0,0 +1,116 @@
1
+ require 'cocoapods'
2
+ require_relative 'helper/feature_switches'
3
+
4
+ module Pod
5
+ class Source
6
+ class Manager
7
+ # 二进制源
8
+ def binary_source
9
+ source_with_name_or_url("http://gitlab.dushuclub.io/cocoapods/HDBinarySpecs.git")
10
+ end
11
+
12
+ # 三方库源
13
+ def third_party_source
14
+ source_with_name_or_url("http://gitlab.dushuclub.io/cocoapods/Specs.git")
15
+ end
16
+
17
+ # 私有库源
18
+ def private_source
19
+ source_with_name_or_url("http://gitlab.dushuclub.io/cocoapods/HDSourceSpecs.git")
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+
26
+ module Pod
27
+ class Resolver
28
+
29
+ # 用二进制源查找name和version,存在就用新的ResolverSpecification
30
+ # 如果找不到返回原始的ResolverSpecification
31
+ old_resolver_specs_by_target = instance_method(:resolver_specs_by_target)
32
+ define_method(:resolver_specs_by_target) do
33
+ # Pod::UI.puts "Cocoapods-bone resolver_specs_by_target ------ "
34
+ specs_by_target = old_resolver_specs_by_target.bind(self).call
35
+ if Podfile::DSL.is_all_binary == nil || Podfile::DSL.is_all_binary == false
36
+ return specs_by_target
37
+ end
38
+ # 只有在pod install的时候执行替换源,其他逻辑不参与
39
+ if Pod.is_ignore_hook_install == nil || Pod.is_ignore_hook_install == true
40
+ specs_by_target.each do |target, rspecs|
41
+ specs_by_target[target] = rspecs.map do |rspec|
42
+ sources_manager = Config.instance.sources_manager
43
+ binary_source = sources_manager.binary_source
44
+ third_party_source = sources_manager.third_party_source
45
+ private_source = sources_manager.private_source
46
+ spec_version = rspec.spec.version
47
+
48
+ if Podfile::DSL.source_pods.include?(rspec.name)
49
+
50
+ # Pod::UI.puts "name:#{rspec.name}
51
+ # rspec.source:#{rspec.source.url}
52
+ # third_party_source:#{third_party_source.url}
53
+ # private_source: #{private_source.url} \n"
54
+
55
+ if rspec.source.url != third_party_source.url && rspec.source.url != private_source.url
56
+ used_by_only = rspec.used_by_non_library_targets_only
57
+ begin
58
+ specification = third_party_source.specification(rspec.name, spec_version)
59
+ # Pod::UI.puts "specification : -----------#{specification}"
60
+ rspec = ResolverSpecification.new(specification, used_by_only, third_party_source)
61
+ rescue Exception => e
62
+ rspec = ResolverSpecification.new(rspec.spec, used_by_only, private_source)
63
+ end
64
+ end
65
+ else
66
+ begin
67
+
68
+ specification = binary_source.specification(rspec.root.name, spec_version)
69
+ # Pod::UI.puts "specification----- #{specification}, #{used_by_only}, #{binary_source}"
70
+
71
+ if rspec.spec.subspec?
72
+ specification = specification.subspec_by_name(rspec.name, false, true)
73
+ end
74
+
75
+ next unless specification
76
+
77
+ used_by_only = rspec.used_by_non_library_targets_only
78
+
79
+ rspec = ResolverSpecification.new(specification, used_by_only, binary_source)
80
+ rescue Exception => e
81
+ rspec
82
+ end
83
+ end
84
+
85
+ rspec
86
+ end.compact
87
+ end
88
+ else
89
+ #制作二进制库,需要将源强制切换到源码源
90
+ Pod::UI.puts "制作二进制库,force switch source pods"
91
+ specs_by_target.each do |target, rspecs|
92
+
93
+ specs_by_target[target] = rspecs.map do |rspec|
94
+ sources_manager = Config.instance.sources_manager
95
+ third_party_source = sources_manager.third_party_source
96
+ private_source = sources_manager.private_source
97
+ spec_version = rspec.spec.version
98
+
99
+ used_by_only = rspec.used_by_non_library_targets_only
100
+
101
+ begin
102
+ specification = third_party_source.specification(rspec.name, spec_version)
103
+ rspec = ResolverSpecification.new(specification, used_by_only, third_party_source)
104
+ rescue Exception => e
105
+ rspec = ResolverSpecification.new(rspec.spec, used_by_only, private_source)
106
+ end
107
+ rspec
108
+ end.compact
109
+ end
110
+ end
111
+
112
+ specs_by_target
113
+ end
114
+ end
115
+ end
116
+
@@ -2,10 +2,6 @@ require 'cocoapods'
2
2
 
3
3
  module Pod
4
4
  class TagUtil
5
- # attr_accessor :test
6
- # def initialize(test)
7
- # @test = test
8
- # end
9
5
 
10
6
  # tag 是否存在
11
7
  def self.exist_tag(tag)
@@ -20,15 +16,23 @@ module Pod
20
16
  end
21
17
 
22
18
  # tag 是否存在符合格式的分支
23
- def self.exist_branch
19
+ def self.check_master_branch
24
20
  branch_name = `git symbolic-ref --short -q HEAD`
25
21
  UI.puts("current branch: #{branch_name}")
26
- if branch_name =~ /release_[0-9].[0-9].[0-9]/ || branch_name.to_s.strip == "master"
22
+ if branch_name.to_s.strip == "master"
27
23
  return true
28
24
  end
29
25
  false
30
26
  end
31
27
 
28
+ # 上传Sources
29
+ def self.upload_origin_sources(commit_desc)
30
+ `git status -s`
31
+ `git add .`
32
+ `git commit -m '#{commit_desc}'`
33
+ `git push origin master`
34
+ end
35
+
32
36
  def self.check_branch_include_tag(tag)
33
37
  branch_name = `git symbolic-ref --short -q HEAD`
34
38
  if branch_name.to_s.strip == "master"