cocoapods-hd 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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"