cocoapods-ppbuild 0.0.1
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 +7 -0
- data/lib/cocoapods-ppbuild/Integration.rb +306 -0
- data/lib/cocoapods-ppbuild/Main.rb +177 -0
- data/lib/cocoapods-ppbuild/Prebuild.rb +236 -0
- data/lib/cocoapods-ppbuild/command/ppbuild.rb +216 -0
- data/lib/cocoapods-ppbuild/command.rb +1 -0
- data/lib/cocoapods-ppbuild/gem_version.rb +3 -0
- data/lib/cocoapods-ppbuild/helper/feature_switches.rb +97 -0
- data/lib/cocoapods-ppbuild/helper/names.rb +78 -0
- data/lib/cocoapods-ppbuild/helper/passer.rb +41 -0
- data/lib/cocoapods-ppbuild/helper/podfile_options.rb +128 -0
- data/lib/cocoapods-ppbuild/helper/prebuild_sandbox.rb +109 -0
- data/lib/cocoapods-ppbuild/helper/target_checker.rb +49 -0
- data/lib/cocoapods-ppbuild/rome/build_framework.rb +199 -0
- data/lib/cocoapods-ppbuild/tool/tool.rb +12 -0
- data/lib/cocoapods-ppbuild.rb +1 -0
- data/lib/cocoapods_plugin.rb +4 -0
- metadata +87 -0
@@ -0,0 +1,236 @@
|
|
1
|
+
require_relative 'rome/build_framework'
|
2
|
+
require_relative 'helper/passer'
|
3
|
+
require_relative 'helper/target_checker'
|
4
|
+
|
5
|
+
|
6
|
+
# patch prebuild ability
|
7
|
+
module Pod
|
8
|
+
class Installer
|
9
|
+
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def local_manifest
|
14
|
+
if not @local_manifest_inited
|
15
|
+
@local_manifest_inited = true
|
16
|
+
raise "This method should be call before generate project" unless self.analysis_result == nil
|
17
|
+
@local_manifest = self.sandbox.manifest
|
18
|
+
end
|
19
|
+
@local_manifest
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Analyzer::SpecsState]
|
23
|
+
def prebuild_pods_changes
|
24
|
+
return nil if local_manifest.nil?
|
25
|
+
if @prebuild_pods_changes.nil?
|
26
|
+
changes = local_manifest.detect_changes_with_podfile(podfile)
|
27
|
+
@prebuild_pods_changes = Analyzer::SpecsState.new(changes)
|
28
|
+
# save the chagnes info for later stage
|
29
|
+
Pod::Prebuild::Passer.prebuild_pods_changes = @prebuild_pods_changes
|
30
|
+
end
|
31
|
+
@prebuild_pods_changes
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
public
|
36
|
+
|
37
|
+
# check if need to prebuild
|
38
|
+
def have_exact_prebuild_cache?
|
39
|
+
# check if need build frameworks
|
40
|
+
return false if local_manifest == nil
|
41
|
+
|
42
|
+
changes = prebuild_pods_changes
|
43
|
+
added = changes.added
|
44
|
+
changed = changes.changed
|
45
|
+
unchanged = changes.unchanged
|
46
|
+
deleted = changes.deleted
|
47
|
+
|
48
|
+
exsited_framework_pod_names = sandbox.exsited_framework_pod_names
|
49
|
+
missing = unchanged.select do |pod_name|
|
50
|
+
not exsited_framework_pod_names.include?(pod_name)
|
51
|
+
end
|
52
|
+
|
53
|
+
needed = (added + changed + deleted + missing)
|
54
|
+
return needed.empty?
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
# The install method when have completed cache
|
59
|
+
def install_when_cache_hit!
|
60
|
+
# just print log
|
61
|
+
self.sandbox.exsited_framework_target_names.each do |name|
|
62
|
+
UI.puts "Using #{name}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
# Build the needed framework files
|
68
|
+
def prebuild_frameworks!
|
69
|
+
# build options
|
70
|
+
sandbox_path = sandbox.root
|
71
|
+
existed_framework_folder = sandbox.generate_framework_path
|
72
|
+
bitcode_enabled = Pod::Podfile::DSL.bitcode_enabled
|
73
|
+
use_static_framework = Pod::Podfile::DSL.static_binary
|
74
|
+
targets = []
|
75
|
+
|
76
|
+
if local_manifest != nil
|
77
|
+
changes = prebuild_pods_changes
|
78
|
+
added = changes.added
|
79
|
+
changed = changes.changed
|
80
|
+
unchanged = changes.unchanged
|
81
|
+
deleted = changes.deleted
|
82
|
+
|
83
|
+
existed_framework_folder.mkdir unless existed_framework_folder.exist?
|
84
|
+
exsited_framework_pod_names = sandbox.exsited_framework_pod_names
|
85
|
+
|
86
|
+
# additions
|
87
|
+
missing = unchanged.select do |pod_name|
|
88
|
+
not exsited_framework_pod_names.include?(pod_name)
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
root_names_to_update = (added + changed + missing)
|
93
|
+
|
94
|
+
# transform names to targets
|
95
|
+
cache = []
|
96
|
+
targets = root_names_to_update.map do |pod_name|
|
97
|
+
tars = Pod.fast_get_targets_for_pod_name(pod_name, self.pod_targets, cache)
|
98
|
+
if tars.nil? || tars.empty?
|
99
|
+
raise "There's no target named (#{pod_name}) in Pod.xcodeproj.\n #{self.pod_targets.map(&:name)}" if t.nil?
|
100
|
+
end
|
101
|
+
tars
|
102
|
+
end.flatten
|
103
|
+
|
104
|
+
# add the dendencies
|
105
|
+
dependency_targets = targets.map {|t| t.recursive_dependent_targets }.flatten.uniq || []
|
106
|
+
targets = (targets + dependency_targets).uniq
|
107
|
+
else
|
108
|
+
targets = self.pod_targets
|
109
|
+
end
|
110
|
+
|
111
|
+
targets = targets.reject {|pod_target| sandbox.local?(pod_target.pod_name) }
|
112
|
+
|
113
|
+
|
114
|
+
# build!
|
115
|
+
Pod::UI.puts "Prebuild frameworks (total #{targets.count})"
|
116
|
+
Pod::Prebuild.remove_build_dir(sandbox_path)
|
117
|
+
targets.each do |target|
|
118
|
+
if !target.should_build?
|
119
|
+
UI.puts "Prebuilding #{target.label}"
|
120
|
+
next
|
121
|
+
end
|
122
|
+
|
123
|
+
output_path = sandbox.framework_folder_path_for_target_name(target.name)
|
124
|
+
output_path.mkpath unless output_path.exist?
|
125
|
+
Pod::Prebuild.build(sandbox_path, target, output_path, bitcode_enabled, Podfile::DSL.custom_build_options, Podfile::DSL.custom_build_options_simulator)
|
126
|
+
|
127
|
+
# save the resource paths for later installing,动态库需要将frameworkwork中资源链接到pod上
|
128
|
+
if target.static_framework? and !target.resource_paths.empty?
|
129
|
+
framework_path = output_path + target.framework_name
|
130
|
+
standard_sandbox_path = sandbox.standard_sanbox_path
|
131
|
+
|
132
|
+
resources = begin
|
133
|
+
if Pod::VERSION.start_with? "1.5"
|
134
|
+
target.resource_paths
|
135
|
+
else
|
136
|
+
# resource_paths is Hash{String=>Array<String>} on 1.6 and above
|
137
|
+
# (use AFNetworking to generate a demo data)
|
138
|
+
target.resource_paths.values.flatten
|
139
|
+
end
|
140
|
+
end
|
141
|
+
raise "Wrong type: #{resources}" unless resources.kind_of? Array
|
142
|
+
|
143
|
+
path_objects = resources.flat_map do |path|
|
144
|
+
real_path = framework_path + File.basename(path)
|
145
|
+
# 静态库资源目录处理
|
146
|
+
if use_static_framework
|
147
|
+
real_bundle_path = sandbox.real_bundle_path_for_pod(path)
|
148
|
+
if File.exists?(real_bundle_path)
|
149
|
+
FileUtils.cp_r(real_bundle_path, framework_path, :remove_destination => true)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
object = Prebuild::Passer::ResourcePath.new
|
153
|
+
if File.exists?(real_path)
|
154
|
+
object.real_file_path = real_path
|
155
|
+
end
|
156
|
+
object.target_file_path = path.gsub('${PODS_ROOT}', standard_sandbox_path.to_s) if path.start_with? '${PODS_ROOT}'
|
157
|
+
object.target_file_path = path.gsub("${PODS_CONFIGURATION_BUILD_DIR}", standard_sandbox_path.to_s) if path.start_with? "${PODS_CONFIGURATION_BUILD_DIR}"
|
158
|
+
object
|
159
|
+
end
|
160
|
+
Prebuild::Passer.resources_to_copy_for_static_framework[target.name] = path_objects
|
161
|
+
end
|
162
|
+
end
|
163
|
+
Pod::Prebuild.remove_build_dir(sandbox_path)
|
164
|
+
|
165
|
+
# copy vendored libraries and frameworks
|
166
|
+
targets.each do |target|
|
167
|
+
root_path = self.sandbox.pod_dir(target.name)
|
168
|
+
target_folder = sandbox.framework_folder_path_for_target_name(target.name)
|
169
|
+
|
170
|
+
# If target shouldn't build, we copy all the original files
|
171
|
+
# This is for target with only .a and .h files
|
172
|
+
if not target.should_build?
|
173
|
+
Prebuild::Passer.target_names_to_skip_integration_framework << target.name
|
174
|
+
FileUtils.cp_r(root_path, target_folder, :remove_destination => true)
|
175
|
+
next
|
176
|
+
end
|
177
|
+
|
178
|
+
target.spec_consumers.each do |consumer|
|
179
|
+
file_accessor = Sandbox::FileAccessor.new(root_path, consumer)
|
180
|
+
lib_paths = file_accessor.vendored_frameworks || []
|
181
|
+
lib_paths += file_accessor.vendored_libraries
|
182
|
+
# @TODO dSYM files
|
183
|
+
lib_paths.each do |lib_path|
|
184
|
+
relative = lib_path.relative_path_from(root_path)
|
185
|
+
destination = target_folder + relative
|
186
|
+
destination.dirname.mkpath unless destination.dirname.exist?
|
187
|
+
FileUtils.cp_r(lib_path, destination, :remove_destination => true)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# save the pod_name for prebuild framwork in sandbox
|
193
|
+
targets.each do |target|
|
194
|
+
sandbox.save_pod_name_for_target target
|
195
|
+
end
|
196
|
+
|
197
|
+
# Remove useless files
|
198
|
+
# remove useless pods
|
199
|
+
all_needed_names = self.pod_targets.map(&:name).uniq
|
200
|
+
useless_target_names = sandbox.exsited_framework_target_names.reject do |name|
|
201
|
+
all_needed_names.include? name
|
202
|
+
end
|
203
|
+
useless_target_names.each do |name|
|
204
|
+
path = sandbox.framework_folder_path_for_target_name(name)
|
205
|
+
path.rmtree if path.exist?
|
206
|
+
end
|
207
|
+
|
208
|
+
if Podfile::DSL.dont_remove_source_code
|
209
|
+
# just remove the tmp files
|
210
|
+
path = sandbox.root + 'Manifest.lock.tmp'
|
211
|
+
path.rmtree if path.exist?
|
212
|
+
else
|
213
|
+
# only keep manifest.lock and framework folder in _Prebuild
|
214
|
+
to_remain_files = ["Manifest.lock", File.basename(existed_framework_folder)]
|
215
|
+
to_delete_files = sandbox_path.children.select do |file|
|
216
|
+
filename = File.basename(file)
|
217
|
+
not to_remain_files.include?(filename)
|
218
|
+
end
|
219
|
+
to_delete_files.each do |path|
|
220
|
+
path.rmtree if path.exist?
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
# patch the post install hook
|
226
|
+
old_method2 = instance_method(:run_plugins_post_install_hooks)
|
227
|
+
define_method(:run_plugins_post_install_hooks) do
|
228
|
+
old_method2.bind(self).()
|
229
|
+
if Pod::is_prebuild_stage
|
230
|
+
self.prebuild_frameworks!
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
|
235
|
+
end
|
236
|
+
end
|
@@ -0,0 +1,216 @@
|
|
1
|
+
module Pod
|
2
|
+
class Command
|
3
|
+
#
|
4
|
+
class Ppbuild < Command
|
5
|
+
self.summary = '通过将二进制对应源码放置在临时目录中,让二进制出现断点时可以跳到对应的源码,方便调试。'
|
6
|
+
|
7
|
+
self.description = <<-DESC
|
8
|
+
通过将二进制对应源码放置在临时目录中,让二进制出现断点时可以跳到对应的源码,方便调试。
|
9
|
+
在不删除二进制的情况下为某个组件添加源码调试能力,多个组件名称用空格分隔
|
10
|
+
DESC
|
11
|
+
|
12
|
+
self.arguments = [
|
13
|
+
CLAide::Argument.new('NAME', false)
|
14
|
+
]
|
15
|
+
def self.options
|
16
|
+
[
|
17
|
+
['--all-clean', '删除所有已经下载的源码'],
|
18
|
+
['--clean', '删除所有指定下载的源码'],
|
19
|
+
['--list', '展示所有一级下载的源码以及其大小'],
|
20
|
+
['--source', '源码路径,本地路径,会去自动链接本地源码']
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(argv)
|
25
|
+
@codeSource = argv.option('source') || nil
|
26
|
+
@names = argv.arguments! unless argv.arguments.empty?
|
27
|
+
@list = argv.flag?('list', false )
|
28
|
+
@all_clean = argv.flag?('all-clean', false )
|
29
|
+
@clean = argv.flag?('clean', false )
|
30
|
+
@config = Pod::Config.instance
|
31
|
+
@analyzer = nil
|
32
|
+
@podfile_dependency_cache = Pod::Installer::Analyzer::PodfileDependencyCache.from_podfile(@config.podfile)
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def run
|
38
|
+
podfile_lock = File.join(Pathname.pwd,"Podfile.lock")
|
39
|
+
raise "podfile.lock,不存在,请先pod install/update" unless File.exist?(podfile_lock)
|
40
|
+
@lockfile ||= Lockfile.from_file(Pathname.new(podfile_lock) )
|
41
|
+
|
42
|
+
if @list
|
43
|
+
list
|
44
|
+
elsif @clean
|
45
|
+
clean
|
46
|
+
elsif @all_clean
|
47
|
+
all_clean
|
48
|
+
elsif @names
|
49
|
+
add
|
50
|
+
end
|
51
|
+
|
52
|
+
if @list && @clean && @names
|
53
|
+
raise "请选择您要执行的命令。"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
#==========================begin add ==============
|
58
|
+
|
59
|
+
def add
|
60
|
+
if @names == nil
|
61
|
+
raise "请输入要调试组件名,多个组件名称用空格分隔"
|
62
|
+
end
|
63
|
+
@names.each do |name|
|
64
|
+
lib_file = get_lib_path(name)
|
65
|
+
unless File.exist?(lib_file)
|
66
|
+
raise "找不到 #{lib_file}"
|
67
|
+
end
|
68
|
+
UI.puts "#{lib_file}"
|
69
|
+
|
70
|
+
target_path = @codeSource || download_source(name)
|
71
|
+
|
72
|
+
link(lib_file,target_path,name)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
#下载源码到本地
|
77
|
+
def download_source(name)
|
78
|
+
target_path = File.join(source_root, name)
|
79
|
+
UI.puts target_path
|
80
|
+
FileUtils.rm_rf(target_path)
|
81
|
+
find_dependency = find_dependency(name)
|
82
|
+
spec = fetch_external_source(find_dependency, @config.podfile,@config.lockfile, @config.sandbox,true )
|
83
|
+
|
84
|
+
download_request = Pod::Downloader::Request.new(:name => name, :spec => spec)
|
85
|
+
Downloader.download(download_request, Pathname.new(target_path), :can_cache => true)
|
86
|
+
|
87
|
+
target_path
|
88
|
+
end
|
89
|
+
|
90
|
+
#找出依赖
|
91
|
+
def find_dependency (name)
|
92
|
+
find_dependency = nil
|
93
|
+
|
94
|
+
@config.podfile.dependencies.each do |dependency|
|
95
|
+
if dependency.root_name.downcase == name.downcase
|
96
|
+
find_dependency = dependency
|
97
|
+
break
|
98
|
+
end
|
99
|
+
end
|
100
|
+
if find_dependency.external_source.nil?
|
101
|
+
|
102
|
+
end
|
103
|
+
find_dependency
|
104
|
+
end
|
105
|
+
|
106
|
+
# 获取external_source 下的仓库
|
107
|
+
# @return spec
|
108
|
+
def fetch_external_source(dependency ,podfile , lockfile, sandbox,use_lockfile_options)
|
109
|
+
checkout_options = lockfile.checkout_options_for_pod_named(dependency.root_name)
|
110
|
+
source = if use_lockfile_options && lockfile && checkout_options
|
111
|
+
ExternalSources.from_params(checkout_options, dependency, podfile.defined_in_file, podfile.installation_options.clean?)
|
112
|
+
else
|
113
|
+
ExternalSources.from_dependency(dependency, podfile.defined_in_file, podfile.installation_options.clean?)
|
114
|
+
end
|
115
|
+
source.fetch(sandbox)
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
#==========================link begin ==============
|
120
|
+
|
121
|
+
#链接,.a文件位置, 源码目录
|
122
|
+
def link(lib_file,target_path,basename)
|
123
|
+
check(lib_file,dir,basename)
|
124
|
+
end
|
125
|
+
|
126
|
+
def check(lib_file,dir,basename)
|
127
|
+
file = `dwarfdump "#{lib_file}" | grep -E "DW_AT_decl_file.*#{basename}.*\\.m|\\.c" | head -1 | cut -d \\" -f2`
|
128
|
+
if File.exist?(file)
|
129
|
+
raise "#{file} 不存在 请检测代码源是否正确~"
|
130
|
+
end
|
131
|
+
UI.puts "link successfully!"
|
132
|
+
UI.puts "view linked source at path: #{dir}"
|
133
|
+
end
|
134
|
+
|
135
|
+
def get_lib_path(name)
|
136
|
+
dir = Pathname.new(File.join(Pathname.pwd,"Pods",name))
|
137
|
+
dir = get_framework_path(dir, name)
|
138
|
+
if !Dir.exist?(dir)
|
139
|
+
raise "找不到组件:#{name}, 请输入正确名称!! 者将组件名在git上提issues"
|
140
|
+
end
|
141
|
+
lib_path = File.join(dir, name)
|
142
|
+
lib_path
|
143
|
+
end
|
144
|
+
|
145
|
+
def get_framework_path(basepath, name)
|
146
|
+
dir = Pathname.new(File.join(basepath, "#{name}.framework"))
|
147
|
+
if !Dir.exist?(dir)
|
148
|
+
dir = dir.children.first
|
149
|
+
if Dir.exist?(dir)
|
150
|
+
return get_framework_path(dir, name)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
return dir
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
#源码地址
|
158
|
+
# def get_gitlib_iOS_path(name)
|
159
|
+
# "git@gitlab.xxx.com:iOS/#{name}.git"
|
160
|
+
# end
|
161
|
+
#要转换的地址,Github-iOS默认都是静态库
|
162
|
+
# def git_gitlib_iOS_path
|
163
|
+
# 'git@gitlab.xxx.com:Github-iOS/'
|
164
|
+
# end
|
165
|
+
|
166
|
+
|
167
|
+
#要转换的地址,Github-iOS默认都是静态库
|
168
|
+
# def http_gitlib_GitHub_iOS_path
|
169
|
+
# 'https://gitlab.xxx.com/Github-iOS/'
|
170
|
+
# end
|
171
|
+
|
172
|
+
#要转换的地址,iOS默认都是静态库
|
173
|
+
# def http_gitlib_iOS_path
|
174
|
+
# 'https://gitlab.xxx.com/iOS/'
|
175
|
+
# end
|
176
|
+
|
177
|
+
#==========================list begin ==============
|
178
|
+
|
179
|
+
def list
|
180
|
+
Dir.entries(source_root).each do |sub|
|
181
|
+
UI.puts "- #{sub}" unless sub.include?('.')
|
182
|
+
end
|
183
|
+
UI.puts "加载完成"
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
#==========================clean begin ==============
|
188
|
+
def all_clean
|
189
|
+
FileUtils.rm_rf(source_root) if File.directory?(source_root)
|
190
|
+
UI.puts "清理完成 #{source_root}"
|
191
|
+
end
|
192
|
+
|
193
|
+
def clean
|
194
|
+
raise "请输入要删除的组件库" if @names.nil?
|
195
|
+
@names.each do |name|
|
196
|
+
full_path = File.join(source_root,name)
|
197
|
+
if File.directory?(full_path)
|
198
|
+
FileUtils.rm_rf(full_path)
|
199
|
+
else
|
200
|
+
UI.puts "找不到 #{full_path}".yellow
|
201
|
+
end
|
202
|
+
end
|
203
|
+
UI.puts "清理完成 #{@names.to_s}"
|
204
|
+
end
|
205
|
+
|
206
|
+
private
|
207
|
+
|
208
|
+
def source_root
|
209
|
+
dir = File.join(@config.cache_root,"Source")
|
210
|
+
FileUtils.mkdir_p(dir) unless File.exist? dir
|
211
|
+
UI.puts "缓存目录 #{dir}"
|
212
|
+
dir
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'cocoapods-ppbuild/command/ppbuild'
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require_relative '../tool/tool'
|
2
|
+
require_relative 'prebuild_sandbox'
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
|
6
|
+
# a flag that indicate stages
|
7
|
+
class_attr_accessor :is_prebuild_stage
|
8
|
+
|
9
|
+
|
10
|
+
# a switch for the `pod` DSL to make it only valid for ':ppbuild => true'
|
11
|
+
class Podfile
|
12
|
+
module DSL
|
13
|
+
|
14
|
+
@@enable_prebuild_patch = false
|
15
|
+
|
16
|
+
# when enable, `pod` function will skip all pods without 'prebuild => true'
|
17
|
+
def self.enable_prebuild_patch(value)
|
18
|
+
@@enable_prebuild_patch = value
|
19
|
+
end
|
20
|
+
|
21
|
+
# --- patch ---
|
22
|
+
old_method = instance_method(:pod)
|
23
|
+
|
24
|
+
define_method(:pod) do |name, *args|
|
25
|
+
if !@@enable_prebuild_patch
|
26
|
+
old_method.bind(self).(name, *args)
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
# patched content
|
31
|
+
should_prebuild = Pod::Podfile::DSL.prebuild_all
|
32
|
+
local = false
|
33
|
+
|
34
|
+
options = args.last
|
35
|
+
if options.is_a?(Hash) and options[Pod::Prebuild.keyword] != nil
|
36
|
+
should_prebuild = options[Pod::Prebuild.keyword]
|
37
|
+
local = (options[:path] != nil)
|
38
|
+
end
|
39
|
+
|
40
|
+
if should_prebuild and (not local)
|
41
|
+
old_method.bind(self).(name, *args)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
# a force disable option for integral
|
49
|
+
class Installer
|
50
|
+
def self.force_disable_integration(value)
|
51
|
+
@@force_disable_integration = value
|
52
|
+
end
|
53
|
+
|
54
|
+
old_method = instance_method(:integrate_user_project)
|
55
|
+
define_method(:integrate_user_project) do
|
56
|
+
if @@force_disable_integration
|
57
|
+
return
|
58
|
+
end
|
59
|
+
old_method.bind(self).()
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# a option to disable install complete message
|
64
|
+
class Installer
|
65
|
+
def self.disable_install_complete_message(value)
|
66
|
+
@@disable_install_complete_message = value
|
67
|
+
end
|
68
|
+
|
69
|
+
old_method = instance_method(:print_post_install_message)
|
70
|
+
define_method(:print_post_install_message) do
|
71
|
+
if @@disable_install_complete_message
|
72
|
+
return
|
73
|
+
end
|
74
|
+
old_method.bind(self).()
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# option to disable write lockfiles
|
79
|
+
class Config
|
80
|
+
|
81
|
+
@@force_disable_write_lockfile = false
|
82
|
+
def self.force_disable_write_lockfile(value)
|
83
|
+
@@force_disable_write_lockfile = value
|
84
|
+
end
|
85
|
+
|
86
|
+
old_method = instance_method(:lockfile_path)
|
87
|
+
define_method(:lockfile_path) do
|
88
|
+
if @@force_disable_write_lockfile
|
89
|
+
# As config is a singleton, sandbox_root refer to the standard sandbox.
|
90
|
+
return PrebuildSandbox.from_standard_sanbox_path(sandbox_root).root + 'Manifest.lock.tmp'
|
91
|
+
else
|
92
|
+
return old_method.bind(self).()
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
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,41 @@
|
|
1
|
+
require_relative '../tool/tool'
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class Prebuild
|
5
|
+
|
6
|
+
# Pass the data between the 2 steps
|
7
|
+
#
|
8
|
+
# At step 2, the normal pod install, it needs some info of the
|
9
|
+
# prebuilt step. So we store it here.
|
10
|
+
#
|
11
|
+
class Passer
|
12
|
+
|
13
|
+
# indicate the add/remove/update of prebuit pods
|
14
|
+
# @return [Analyzer::SpecsState]
|
15
|
+
#
|
16
|
+
class_attr_accessor :prebuild_pods_changes
|
17
|
+
|
18
|
+
|
19
|
+
# represent the path of resurces to copy
|
20
|
+
class ResourcePath
|
21
|
+
attr_accessor :real_file_path
|
22
|
+
attr_accessor :target_file_path
|
23
|
+
end
|
24
|
+
# Save the resoures for static framework, and used when installing the prebuild framework
|
25
|
+
# static framework needs copy the resurces mannully
|
26
|
+
#
|
27
|
+
# @return [Hash<String, [Passer::ResourcePath]>]
|
28
|
+
class_attr_accessor :resources_to_copy_for_static_framework
|
29
|
+
self.resources_to_copy_for_static_framework = {}
|
30
|
+
|
31
|
+
# Some pod won't be build in prebuild stage even if it have `binary=>true`.
|
32
|
+
# The targets of this pods have `oshould_build? == true`.
|
33
|
+
# We should skip integration (patch spec) for this pods
|
34
|
+
#
|
35
|
+
# @return [Array<String>]
|
36
|
+
class_attr_accessor :target_names_to_skip_integration_framework
|
37
|
+
self.target_names_to_skip_integration_framework = []
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|