my-cocoapods-packager 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +3 -0
  4. data/.rubocop-cocoapods.yml +71 -0
  5. data/.rubocop.yml +38 -0
  6. data/.travis.yml +9 -0
  7. data/Gemfile +12 -0
  8. data/Gemfile.lock +121 -0
  9. data/LICENSE +22 -0
  10. data/README.md +42 -0
  11. data/Rakefile +12 -0
  12. data/cocoapods-packager.gemspec +22 -0
  13. data/lib/cocoapods-packager/builder.rb +340 -0
  14. data/lib/cocoapods-packager/framework.rb +66 -0
  15. data/lib/cocoapods-packager/mangle.rb +32 -0
  16. data/lib/cocoapods-packager/pod_utils.rb +252 -0
  17. data/lib/cocoapods-packager/spec_builder.rb +63 -0
  18. data/lib/cocoapods-packager/symbols.rb +35 -0
  19. data/lib/cocoapods-packager/user_interface/build_failed_report.rb +15 -0
  20. data/lib/cocoapods_packager.rb +5 -0
  21. data/lib/cocoapods_plugin.rb +8 -0
  22. data/lib/pod/command/package.rb +163 -0
  23. data/scripts/lstconst.sh +9 -0
  24. data/scripts/lstsym.sh +8 -0
  25. data/spec/command/error_spec.rb +74 -0
  26. data/spec/command/package_spec.rb +359 -0
  27. data/spec/command/subspecs_spec.rb +30 -0
  28. data/spec/fixtures/Builder.podspec +25 -0
  29. data/spec/fixtures/CPDColors.podspec +19 -0
  30. data/spec/fixtures/FH.podspec +18 -0
  31. data/spec/fixtures/KFData.podspec +73 -0
  32. data/spec/fixtures/LibraryConsumerDemo/.gitignore +22 -0
  33. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/AppDelegate.h +17 -0
  34. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/AppDelegate.m +27 -0
  35. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/Info.plist +40 -0
  36. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/main.m +16 -0
  37. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcodeproj/project.pbxproj +340 -0
  38. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  39. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcodeproj/xcshareddata/xcschemes/LibraryConsumer.xcscheme +100 -0
  40. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcworkspace/contents.xcworkspacedata +10 -0
  41. data/spec/fixtures/LibraryConsumerDemo/Podfile +5 -0
  42. data/spec/fixtures/LibraryDemo.podspec +14 -0
  43. data/spec/fixtures/NikeKit.podspec +19 -0
  44. data/spec/fixtures/OpenSans.podspec +18 -0
  45. data/spec/fixtures/PackagerTest/.gitignore +21 -0
  46. data/spec/fixtures/PackagerTest/PackagerTest/CPDAppDelegate.h +15 -0
  47. data/spec/fixtures/PackagerTest/PackagerTest/CPDAppDelegate.m +49 -0
  48. data/spec/fixtures/PackagerTest/PackagerTest/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  49. data/spec/fixtures/PackagerTest/PackagerTest/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  50. data/spec/fixtures/PackagerTest/PackagerTest/PackagerTest-Info.plist +38 -0
  51. data/spec/fixtures/PackagerTest/PackagerTest/PackagerTest-Prefix.pch +16 -0
  52. data/spec/fixtures/PackagerTest/PackagerTest/en.lproj/InfoPlist.strings +2 -0
  53. data/spec/fixtures/PackagerTest/PackagerTest/main.m +18 -0
  54. data/spec/fixtures/PackagerTest/PackagerTest.xcodeproj/project.pbxproj +536 -0
  55. data/spec/fixtures/PackagerTest/PackagerTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  56. data/spec/fixtures/PackagerTest/PackagerTest.xcodeproj/xcshareddata/xcschemes/PackagerTest.xcscheme +110 -0
  57. data/spec/fixtures/PackagerTest/PackagerTest.xcworkspace/contents.xcworkspacedata +1 -0
  58. data/spec/fixtures/PackagerTest/PackagerTestTests/PackagerTestTests-Info.plist +22 -0
  59. data/spec/fixtures/PackagerTest/PackagerTestTests/PackagerTestTests.m +34 -0
  60. data/spec/fixtures/PackagerTest/PackagerTestTests/en.lproj/InfoPlist.strings +2 -0
  61. data/spec/fixtures/PackagerTest/Podfile +10 -0
  62. data/spec/fixtures/PackagerTest/Podfile.lock +32 -0
  63. data/spec/fixtures/Weakly.podspec +13 -0
  64. data/spec/fixtures/a.podspec +19 -0
  65. data/spec/fixtures/foo-bar.podspec +19 -0
  66. data/spec/fixtures/layer-client-messaging-schema.podspec +13 -0
  67. data/spec/integration/project_spec.rb +70 -0
  68. data/spec/pod/utils_spec.rb +58 -0
  69. data/spec/spec_helper.rb +50 -0
  70. data/spec/specification/builder_spec.rb +40 -0
  71. data/spec/specification/spec_builder_spec.rb +61 -0
  72. data/spec/user_interface/build_failed_report_spec.rb +11 -0
  73. metadata +212 -0
@@ -0,0 +1,340 @@
1
+ module Pod
2
+ class Builder
3
+ def initialize(source_dir, static_sandbox_root, dynamic_sandbox_root, public_headers_root, spec, embedded, mangle, dynamic, config, bundle_identifier, exclude_deps)
4
+ @source_dir = source_dir
5
+ @static_sandbox_root = static_sandbox_root
6
+ @dynamic_sandbox_root = dynamic_sandbox_root
7
+ @public_headers_root = public_headers_root
8
+ @spec = spec
9
+ @embedded = embedded
10
+ @mangle = mangle
11
+ @dynamic = dynamic
12
+ @config = config
13
+ @bundle_identifier = bundle_identifier
14
+ @exclude_deps = exclude_deps
15
+ end
16
+
17
+ def build(platform, library)
18
+ if library
19
+ build_static_library(platform)
20
+ else
21
+ build_framework(platform)
22
+ end
23
+ end
24
+
25
+ def build_static_library(platform)
26
+ UI.puts("Building static library #{@spec} with configuration #{@config}")
27
+
28
+ defines = compile(platform)
29
+ build_sim_libraries(platform, defines)
30
+
31
+ platform_path = Pathname.new(platform.name.to_s)
32
+ platform_path.mkdir unless platform_path.exist?
33
+ build_library(platform, defines, platform_path + Pathname.new("lib#{@spec.name}.a"))
34
+ end
35
+
36
+ def build_framework(platform)
37
+ UI.puts("Building framework #{@spec} with configuration #{@config}")
38
+
39
+ defines = compile(platform)
40
+ build_sim_libraries(platform, defines)
41
+
42
+ if @dynamic
43
+ build_dynamic_framework(platform, defines, "#{@dynamic_sandbox_root}/build/#{@spec.name}.framework/#{@spec.name}")
44
+ else
45
+ create_framework(platform.name.to_s)
46
+ build_library(platform, defines, @fwk.versions_path + Pathname.new(@spec.name))
47
+ copy_headers
48
+ copy_license
49
+ end
50
+
51
+ copy_resources(platform)
52
+ end
53
+
54
+ def link_embedded_resources
55
+ target_path = @fwk.root_path + Pathname.new('Resources')
56
+ target_path.mkdir unless target_path.exist?
57
+
58
+ Dir.glob(@fwk.resources_path.to_s + '/*').each do |resource|
59
+ resource = Pathname.new(resource).relative_path_from(target_path)
60
+ `ln -sf #{resource} #{target_path}`
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def build_dynamic_framework(platform, defines, output)
67
+ UI.puts("Building dynamic Framework #{@spec} with configuration #{@config}")
68
+
69
+ if @bundle_identifier
70
+ defines = "#{defines} PRODUCT_BUNDLE_IDENTIFIER='#{@bundle_identifier}'"
71
+ end
72
+
73
+ clean_directory_for_dynamic_build
74
+ if platform.name == :ios
75
+ build_dynamic_framework_for_ios(platform, defines, output)
76
+ else
77
+ build_dynamic_framework_for_mac(platform, defines, output)
78
+ end
79
+ end
80
+
81
+ def build_library(platform, defines, output)
82
+ static_libs = static_libs_in_sandbox
83
+
84
+ if platform.name == :ios
85
+ build_static_lib_for_ios(static_libs, defines, output)
86
+ else
87
+ build_static_lib_for_mac(static_libs, output)
88
+ end
89
+ end
90
+
91
+ def build_dynamic_framework_for_ios(platform, defines, output)
92
+ # Specify frameworks to link and search paths
93
+ lib_linker_flags = static_linker_flags_in_sandbox
94
+ framework_link_flas = framework_linker_flags_in_sandbox
95
+
96
+ linker_flags = lib_linker_flags.push(framework_link_flas)
97
+
98
+ puts linker_flags
99
+
100
+ defines = "#{defines} OTHER_LDFLAGS='$(inherited) #{linker_flags.join(' ')}'"
101
+
102
+ # Build Target Dynamic Framework for both device and Simulator
103
+ device_defines = "#{defines} LIBRARY_SEARCH_PATHS=\"#{Dir.pwd}/#{@static_sandbox_root}/build\""
104
+ device_defines = "#{device_defines} FRAMEWORK_SEARCH_PATHS=\"#{Dir.pwd}/#{@static_sandbox_root}/**\""
105
+
106
+ device_options = ios_build_options << ' -sdk iphoneos'
107
+
108
+ puts device_defines
109
+ puts linker_flags
110
+
111
+ xcodebuild(device_defines, device_options, 'build', @spec.name.to_s, @dynamic_sandbox_root.to_s)
112
+
113
+ sim_defines = "#{defines} LIBRARY_SEARCH_PATHS=\"#{Dir.pwd}/#{@static_sandbox_root}/build-sim\" ONLY_ACTIVE_ARCH=NO"
114
+ sim_defines = "#{sim_defines} FRAMEWORK_SEARCH_PATHS=\"#{Dir.pwd}/#{@static_sandbox_root}/**\""
115
+
116
+ xcodebuild(sim_defines, '-sdk iphonesimulator', 'build-sim', @spec.name.to_s, @dynamic_sandbox_root.to_s)
117
+
118
+ # Combine architectures
119
+ `lipo #{@dynamic_sandbox_root}/build/#{@spec.name}.framework/#{@spec.name} #{@dynamic_sandbox_root}/build-sim/#{@spec.name}.framework/#{@spec.name} -create -output #{output}`
120
+
121
+ FileUtils.mkdir(platform.name.to_s)
122
+ `mv #{@dynamic_sandbox_root}/build/#{@spec.name}.framework #{platform.name}`
123
+ `mv #{@dynamic_sandbox_root}/build/#{@spec.name}.framework.dSYM #{platform.name}`
124
+ end
125
+
126
+ def build_dynamic_framework_for_mac(platform, defines, _output)
127
+ # Specify frameworks to link and search paths
128
+ lib_linker_flags = static_linker_flags_in_sandbox
129
+ framework_link_flas = framework_linker_flags_in_sandbox
130
+
131
+ linker_flags = lib_linker_flags.push(framework_link_flas)
132
+
133
+
134
+ defines = "#{defines} OTHER_LDFLAGS=\"#{linker_flags.join(' ')}\""
135
+
136
+ # Build Target Dynamic Framework for osx
137
+ defines = "#{defines} LIBRARY_SEARCH_PATHS=\"#{Dir.pwd}/#{@static_sandbox_root}/build\""
138
+ device_defines = "#{device_defines} FRAMEWORK_SEARCH_PATHS=\"#{Dir.pwd}/#{@static_sandbox_root}/**\""
139
+
140
+ xcodebuild(defines, nil, 'build', @spec.name.to_s, @dynamic_sandbox_root.to_s)
141
+
142
+ FileUtils.mkdir(platform.name.to_s)
143
+ `mv #{@dynamic_sandbox_root}/build/#{@spec.name}.framework #{platform.name}`
144
+ `mv #{@dynamic_sandbox_root}/build/#{@spec.name}.framework.dSYM #{platform.name}`
145
+ end
146
+
147
+ def build_sim_libraries(platform, defines)
148
+ if platform.name == :ios
149
+ xcodebuild(defines, '-sdk iphonesimulator', 'build-sim')
150
+ end
151
+ end
152
+
153
+ def build_static_lib_for_ios(static_libs, _defines, output)
154
+ return if static_libs.count == 0
155
+ `libtool -static -o #{@static_sandbox_root}/build/package.a #{static_libs.join(' ')}`
156
+
157
+ sim_libs = static_libs_in_sandbox('build-sim')
158
+ `libtool -static -o #{@static_sandbox_root}/build-sim/package.a #{sim_libs.join(' ')}`
159
+
160
+ `lipo #{@static_sandbox_root}/build/package.a #{@static_sandbox_root}/build-sim/package.a -create -output #{output}`
161
+ end
162
+
163
+ def build_static_lib_for_mac(static_libs, output)
164
+ return if static_libs.count == 0
165
+ `libtool -static -o #{output} #{static_libs.join(' ')}`
166
+ end
167
+
168
+ def build_with_mangling(platform, options)
169
+ UI.puts 'Mangling symbols'
170
+ defines = Symbols.mangle_for_pod_dependencies(@spec.name, @static_sandbox_root)
171
+ defines << ' ' << @spec.consumer(platform).compiler_flags.join(' ')
172
+
173
+ UI.puts 'Building mangled framework'
174
+ xcodebuild(defines, options)
175
+ defines
176
+ end
177
+
178
+ def clean_directory_for_dynamic_build
179
+ # Remove static headers to avoid duplicate declaration conflicts
180
+ FileUtils.rm_rf("#{@static_sandbox_root}/Headers/Public/#{@spec.name}")
181
+ FileUtils.rm_rf("#{@static_sandbox_root}/Headers/Private/#{@spec.name}")
182
+
183
+ # Equivalent to removing derrived data
184
+ FileUtils.rm_rf('Pods/build')
185
+ end
186
+
187
+ def compile(platform)
188
+ defines = "GCC_PREPROCESSOR_DEFINITIONS='$(inherited) PodsDummy_Pods_#{@spec.name}=PodsDummy_PodPackage_#{@spec.name}'"
189
+ defines << ' ' << @spec.consumer(platform).compiler_flags.join(' ')
190
+
191
+ if platform.name == :ios
192
+ options = ios_build_options
193
+ end
194
+
195
+ xcodebuild(defines, options)
196
+
197
+ if @mangle
198
+ return build_with_mangling(platform, options)
199
+ end
200
+
201
+ defines
202
+ end
203
+
204
+ def copy_headers
205
+ headers_source_root = "#{@public_headers_root}/#{@spec.name}"
206
+
207
+ Dir.glob("#{headers_source_root}/**/*.h").
208
+ each { |h| `ditto #{h} #{@fwk.headers_path}/#{h.sub(headers_source_root, '')}` }
209
+
210
+ # If custom 'module_map' is specified add it to the framework distribution
211
+ # otherwise check if a header exists that is equal to 'spec.name', if so
212
+ # create a default 'module_map' one using it.
213
+ if !@spec.module_map.nil?
214
+ module_map_file = "#{@static_sandbox_root}/#{@spec.name}/#{@spec.module_map}"
215
+ module_map = File.read(module_map_file) if Pathname(module_map_file).exist?
216
+ elsif File.exist?("#{@public_headers_root}/#{@spec.name}/#{@spec.name}.h")
217
+ module_map = <<MAP
218
+ framework module #{@spec.name} {
219
+ umbrella header "#{@spec.name}.h"
220
+
221
+ export *
222
+ module * { export * }
223
+ }
224
+ MAP
225
+ end
226
+
227
+ unless module_map.nil?
228
+ @fwk.module_map_path.mkpath unless @fwk.module_map_path.exist?
229
+ File.write("#{@fwk.module_map_path}/module.modulemap", module_map)
230
+ end
231
+ end
232
+
233
+ def copy_license
234
+ license_file = @spec.license[:file] || 'LICENSE'
235
+ `cp "#{license_file}" .` if Pathname(license_file).exist?
236
+ end
237
+
238
+ def copy_resources(platform)
239
+ bundles = Dir.glob("#{@static_sandbox_root}/build/*.bundle")
240
+ if @dynamic
241
+ resources_path = "ios/#{@spec.name}.framework"
242
+ `cp -rp #{@static_sandbox_root}/build/*.bundle #{resources_path} 2>&1`
243
+ else
244
+ `cp -rp #{@static_sandbox_root}/build/*.bundle #{@fwk.resources_path} 2>&1`
245
+ resources = expand_paths(@spec.consumer(platform).resources)
246
+ if resources.count == 0 && bundles.count == 0
247
+ @fwk.delete_resources
248
+ return
249
+ end
250
+ if resources.count > 0
251
+ `cp -rp #{resources.join(' ')} #{@fwk.resources_path}`
252
+ end
253
+ end
254
+ end
255
+
256
+ def create_framework(platform)
257
+ @fwk = Framework::Tree.new(@spec.name, platform, @embedded)
258
+ @fwk.make
259
+ end
260
+
261
+ def dependency_count
262
+ count = @spec.dependencies.count
263
+
264
+ @spec.subspecs.each do |subspec|
265
+ count += subspec.dependencies.count
266
+ end
267
+
268
+ count
269
+ end
270
+
271
+ def expand_paths(path_specs)
272
+ path_specs.map do |path_spec|
273
+ Dir.glob(File.join(@source_dir, path_spec))
274
+ end
275
+ end
276
+
277
+ def static_libs_in_sandbox(build_dir = 'build')
278
+ if @exclude_deps
279
+ UI.puts 'Excluding dependencies'
280
+ Dir.glob("#{@static_sandbox_root}/#{build_dir}/lib#{@spec.name}.a")
281
+ else
282
+ Dir.glob("#{@static_sandbox_root}/#{build_dir}/lib*.a")
283
+ end
284
+ end
285
+
286
+ def framework_in_sandbox(build_dir = 'build')
287
+ if @exclude_deps
288
+ UI.puts 'Excluding dependencies'
289
+ Dir.glob("#{@static_sandbox_root}/**/{@spec.name}.framework")
290
+ else
291
+ Dir.glob("#{@static_sandbox_root}/**/*.framework")
292
+ end
293
+ end
294
+
295
+ def framework_linker_flags_in_sandbox
296
+ linker_flags = framework_in_sandbox.map do |lib|
297
+ lib_flag = lib.chomp('.framework').split('/').last
298
+ "-framework #{lib_flag}"
299
+ end
300
+ linker_flags.reject { |e| e == "-framework #{@spec.name}" }
301
+ end
302
+
303
+ def static_linker_flags_in_sandbox
304
+ puts static_libs_in_sandbox.map
305
+ linker_flags = static_libs_in_sandbox.map do |lib|
306
+ lib.slice!('lib')
307
+ lib_flag = lib.chomp('.a').split('/').last
308
+ "-l#{lib_flag}"
309
+ end
310
+ linker_flags.reject { |e| e == "-l#{@spec.name}" || e == '-lPods-packager' }
311
+ end
312
+
313
+ def ios_build_options
314
+ "ARCHS=\'x86_64 i386 arm64 armv7 armv7s\' OTHER_CFLAGS=\'-fembed-bitcode -Qunused-arguments\'"
315
+ end
316
+
317
+ def xcodebuild(defines = '', args = '', build_dir = 'build', target = 'Pods-packager', project_root = @static_sandbox_root, config = @config)
318
+ if defined?(Pod::DONT_CODESIGN)
319
+ args = "#{args} CODE_SIGN_IDENTITY=\"\" CODE_SIGNING_REQUIRED=NO"
320
+ end
321
+
322
+ UI.puts project_root
323
+
324
+ command = "xcodebuild #{defines} #{args} CONFIGURATION_BUILD_DIR=#{build_dir} clean build -configuration #{config} -target #{target} -project #{project_root}/Pods.xcodeproj 2>&1"
325
+ puts command
326
+ output = `#{command}`.lines.to_a
327
+
328
+ if $?.exitstatus != 0
329
+ puts UI::BuildFailedReport.report(command, output)
330
+
331
+ # Note: We use `Process.exit` here because it fires a `SystemExit`
332
+ # exception, which gives the caller a chance to clean up before the
333
+ # process terminates.
334
+ #
335
+ # See http://ruby-doc.org/core-1.9.3/Process.html#method-c-exit
336
+ Process.exit
337
+ end
338
+ end
339
+ end
340
+ end
@@ -0,0 +1,66 @@
1
+ module Framework
2
+ class Tree
3
+ attr_reader :headers_path
4
+ attr_reader :module_map_path
5
+ attr_reader :resources_path
6
+ attr_reader :root_path
7
+ attr_reader :versions_path
8
+
9
+ def delete_resources
10
+ Pathname.new(@resources_path).rmtree
11
+ (Pathname.new(@fwk_path) + Pathname.new('Resources')).delete
12
+ end
13
+
14
+ def initialize(name, platform, embedded)
15
+ @name = name
16
+ @platform = platform
17
+ @embedded = embedded
18
+ end
19
+
20
+ def make
21
+ make_root
22
+ make_framework
23
+ make_headers
24
+ make_resources
25
+ make_current_version
26
+ end
27
+
28
+ private
29
+
30
+ def make_current_version
31
+ current_version_path = @versions_path + Pathname.new('../Current')
32
+ `ln -sf A #{current_version_path}`
33
+ `ln -sf Versions/Current/Headers #{@fwk_path}/`
34
+ `ln -sf Versions/Current/Resources #{@fwk_path}/`
35
+ `ln -sf Versions/Current/#{@name} #{@fwk_path}/`
36
+ end
37
+
38
+ def make_framework
39
+ @fwk_path = @root_path + Pathname.new(@name + '.framework')
40
+ @fwk_path.mkdir unless @fwk_path.exist?
41
+
42
+ @module_map_path = @fwk_path + Pathname.new('Modules')
43
+ @versions_path = @fwk_path + Pathname.new('Versions/A')
44
+ end
45
+
46
+ def make_headers
47
+ @headers_path = @versions_path + Pathname.new('Headers')
48
+ @headers_path.mkpath unless @headers_path.exist?
49
+ end
50
+
51
+ def make_resources
52
+ @resources_path = @versions_path + Pathname.new('Resources')
53
+ @resources_path.mkpath unless @resources_path.exist?
54
+ end
55
+
56
+ def make_root
57
+ @root_path = Pathname.new(@platform)
58
+
59
+ if @embedded
60
+ @root_path += Pathname.new(@name + '.embeddedframework')
61
+ end
62
+
63
+ @root_path.mkpath unless @root_path.exist?
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,32 @@
1
+ module Symbols
2
+ #
3
+ # performs symbol aliasing
4
+ #
5
+ # for each dependency:
6
+ # - determine symbols for classes and global constants
7
+ # - alias each symbol to Pod#{pod_name}_#{symbol}
8
+ # - put defines into `GCC_PREPROCESSOR_DEFINITIONS` for passing to Xcode
9
+ #
10
+ def mangle_for_pod_dependencies(pod_name, sandbox_root)
11
+ pod_libs = Dir.glob("#{sandbox_root}/build/lib*.a").select do |file|
12
+ file !~ /lib#{pod_name}.a$/
13
+ end
14
+
15
+ dummy_alias = alias_symbol "PodsDummy_#{pod_name}", pod_name
16
+ all_syms = [dummy_alias]
17
+
18
+ pod_libs.each do |pod_lib|
19
+ syms = Symbols.symbols_from_library(pod_lib)
20
+ all_syms += syms.map! { |sym| alias_symbol sym, pod_name }
21
+ end
22
+
23
+ "GCC_PREPROCESSOR_DEFINITIONS='$(inherited) #{all_syms.uniq.join(' ')}'"
24
+ end
25
+
26
+ def alias_symbol(sym, pod_name)
27
+ pod_name = pod_name.tr('-', '_')
28
+ sym + "=Pod#{pod_name}_" + sym
29
+ end
30
+
31
+ module_function :mangle_for_pod_dependencies, :alias_symbol
32
+ end
@@ -0,0 +1,252 @@
1
+ module Pod
2
+ class Command
3
+ class Package < Command
4
+ private
5
+
6
+ def build_static_sandbox(dynamic)
7
+ static_sandbox_root = if dynamic
8
+ Pathname.new(config.sandbox_root + '/Static')
9
+ else
10
+ Pathname.new(config.sandbox_root)
11
+ end
12
+ Sandbox.new(static_sandbox_root)
13
+ end
14
+
15
+ def install_pod(platform_name, sandbox)
16
+ podfile = podfile_from_spec(
17
+ File.basename(@path),
18
+ @spec.name,
19
+ platform_name,
20
+ @spec.deployment_target(platform_name),
21
+ @subspecs,
22
+ @spec_sources
23
+ )
24
+
25
+ static_installer = Installer.new(sandbox, podfile)
26
+ static_installer.install!
27
+
28
+ unless static_installer.nil?
29
+ static_installer.pods_project.targets.each do |target|
30
+ target.build_configurations.each do |config|
31
+ config.build_settings['CLANG_MODULES_AUTOLINK'] = 'NO'
32
+ config.build_settings['GCC_GENERATE_DEBUGGING_SYMBOLS'] = 'NO'
33
+ end
34
+ end
35
+ static_installer.pods_project.save
36
+ end
37
+
38
+ static_installer
39
+ end
40
+
41
+ def podfile_from_spec(path, spec_name, platform_name, deployment_target, subspecs, sources)
42
+ options = {}
43
+ if path
44
+ options[:podspec] = path
45
+ else
46
+ options[:path] = '.'
47
+ end
48
+ options[:subspecs] = subspecs if subspecs
49
+ Pod::Podfile.new do
50
+ sources.each { |s| source s }
51
+ platform(platform_name, deployment_target)
52
+ pod(spec_name, options)
53
+
54
+ install!('cocoapods',
55
+ :integrate_targets => false,
56
+ :deterministic_uuids => false)
57
+
58
+ target('packager') do
59
+ if path
60
+ if subspecs
61
+ subspecs.each do |subspec|
62
+ pod spec_name + '/' + subspec, :podspec => path
63
+ end
64
+ else
65
+ pod spec_name, :podspec => path
66
+ end
67
+ elsif subspecs
68
+ subspecs.each do |subspec|
69
+ pod spec_name + '/' + subspec, :path => '.'
70
+ end
71
+ else
72
+ pod spec_name, :path => '.'
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ def binary_only?(spec)
79
+ deps = spec.dependencies.map { |dep| spec_with_name(dep.name) }
80
+ [spec, *deps].each do |specification|
81
+ %w(vendored_frameworks vendored_libraries).each do |attrib|
82
+ if specification.attributes_hash[attrib]
83
+ return true
84
+ end
85
+ end
86
+ end
87
+
88
+ false
89
+ end
90
+
91
+ def spec_with_name(name)
92
+ return if name.nil?
93
+
94
+ set = Pod::Config.instance.sources_manager.search(Dependency.new(name))
95
+ return nil if set.nil?
96
+
97
+ set.specification.root
98
+ end
99
+
100
+ def spec_with_path(path)
101
+ return if path.nil? || !Pathname.new(path).exist?
102
+
103
+ @path = path
104
+
105
+ if Pathname.new(path).directory?
106
+ help! path + ': is a directory.'
107
+ return
108
+ end
109
+
110
+ unless ['.podspec', '.json'].include? Pathname.new(path).extname
111
+ help! path + ': is not a podspec.'
112
+ return
113
+ end
114
+
115
+ Specification.from_file(path)
116
+ end
117
+
118
+ #----------------------
119
+ # Dynamic Project Setup
120
+ #----------------------
121
+
122
+ def build_dynamic_sandbox(_static_sandbox, _static_installer)
123
+ dynamic_sandbox_root = Pathname.new(config.sandbox_root + '/Dynamic')
124
+ dynamic_sandbox = Sandbox.new(dynamic_sandbox_root)
125
+
126
+ dynamic_sandbox
127
+ end
128
+
129
+ def install_dynamic_pod(dynamic_sandbox, static_sandbox, static_installer)
130
+ # 1 Create a dynamic target for only the spec pod.
131
+ dynamic_target = build_dynamic_target(dynamic_sandbox, static_installer)
132
+
133
+ # 2. Build a new xcodeproj in the dynamic_sandbox with only the spec pod as a target.
134
+ project = prepare_pods_project(dynamic_sandbox, dynamic_target.name, static_installer)
135
+
136
+ # 3. Copy the source directory for the dynamic framework from the static sandbox.
137
+ copy_dynamic_target(static_sandbox, dynamic_target, dynamic_sandbox)
138
+
139
+ # 4. Copy the supporting files for the dynamic framework from the static sandbox.
140
+ copy_dynamic_supporting_files(static_sandbox, dynamic_target, dynamic_sandbox)
141
+
142
+ # 5. Update the file accecssors.
143
+ dynamic_target = update_file_accessors(dynamic_target, dynamic_sandbox)
144
+
145
+ # 6. Create the file references.
146
+ install_file_references(dynamic_sandbox, [dynamic_target], project)
147
+
148
+ # 7. Install the target.
149
+ install_library(dynamic_sandbox, dynamic_target)
150
+
151
+ # 9. Write the actual Xcodeproject to the dynamic sandbox.
152
+ write_pod_project(project, dynamic_sandbox)
153
+ end
154
+
155
+ def build_dynamic_target(dynamic_sandbox, static_installer)
156
+ spec_targets = static_installer.pod_targets.select do |target|
157
+ target.name == @spec.name
158
+ end
159
+ static_target = spec_targets[0]
160
+
161
+ dynamic_target = Pod::PodTarget.new(static_target.specs, static_target.target_definitions, dynamic_sandbox)
162
+ dynamic_target.host_requires_frameworks = true
163
+ dynamic_target.user_build_configurations = static_target.user_build_configurations
164
+ dynamic_target
165
+ end
166
+
167
+ def prepare_pods_project(dynamic_sandbox, spec_name, installer)
168
+ # Create a new pods project
169
+ pods_project = Pod::Project.new(dynamic_sandbox.project_path)
170
+
171
+ # Update build configurations
172
+ installer.analysis_result.all_user_build_configurations.each do |name, type|
173
+ pods_project.add_build_configuration(name, type)
174
+ end
175
+
176
+ # Add the pod group for only the dynamic framework
177
+ local = dynamic_sandbox.local?(spec_name)
178
+ path = dynamic_sandbox.pod_dir(spec_name)
179
+ was_absolute = dynamic_sandbox.local_path_was_absolute?(spec_name)
180
+ pods_project.add_pod_group(spec_name, path, local, was_absolute)
181
+
182
+ dynamic_sandbox.project = pods_project
183
+ pods_project
184
+ end
185
+
186
+ def copy_dynamic_target(static_sandbox, _dynamic_target, dynamic_sandbox)
187
+ command = "cp -a #{static_sandbox.root}/#{@spec.name} #{dynamic_sandbox.root}"
188
+ `#{command}`
189
+ end
190
+
191
+ def copy_dynamic_supporting_files(_static_sandbox, dynamic_target, _dynamic_sandbox)
192
+ support_dir = Pathname.new(dynamic_target.support_files_dir.to_s.chomp("/#{dynamic_target.name}"))
193
+ support_dir.mkdir
194
+ end
195
+
196
+ def update_file_accessors(dynamic_target, dynamic_sandbox)
197
+ pod_root = dynamic_sandbox.pod_dir(dynamic_target.root_spec.name)
198
+
199
+ path_list = Sandbox::PathList.new(pod_root)
200
+ file_accessors = dynamic_target.specs.map do |spec|
201
+ Sandbox::FileAccessor.new(path_list, spec.consumer(dynamic_target.platform))
202
+ end
203
+
204
+ dynamic_target.file_accessors = file_accessors
205
+ dynamic_target
206
+ end
207
+
208
+ def install_file_references(dynamic_sandbox, pod_targets, pods_project)
209
+ installer = Pod::Installer::Xcode::PodsProjectGenerator::FileReferencesInstaller.new(dynamic_sandbox, pod_targets, pods_project)
210
+ installer.install!
211
+ end
212
+
213
+ def install_library(dynamic_sandbox, dynamic_target)
214
+ return if dynamic_target.target_definitions.flat_map(&:dependencies).empty?
215
+ target_installer = Pod::Installer::Xcode::PodsProjectGenerator::PodTargetInstaller.new(dynamic_sandbox, dynamic_target)
216
+ target_installer.install!
217
+
218
+ # Installs System Frameworks
219
+ dynamic_target.file_accessors.each do |file_accessor|
220
+ file_accessor.spec_consumer.frameworks.each do |framework|
221
+ if dynamic_target.should_build?
222
+ dynamic_target.native_target.add_system_framework(framework)
223
+ end
224
+ end
225
+
226
+ file_accessor.spec_consumer.libraries.each do |library|
227
+ if dynamic_target.should_build?
228
+ dynamic_target.native_target.add_system_library(library)
229
+ end
230
+ end
231
+ end
232
+ end
233
+
234
+ def write_pod_project(dynamic_project, dynamic_sandbox)
235
+ UI.message "- Writing Xcode project file to #{UI.path dynamic_sandbox.project_path}" do
236
+ dynamic_project.pods.remove_from_project if dynamic_project.pods.empty?
237
+ dynamic_project.development_pods.remove_from_project if dynamic_project.development_pods.empty?
238
+ dynamic_project.sort(:groups_position => :below)
239
+ dynamic_project.recreate_user_schemes(false)
240
+
241
+ # Edit search paths so that we can find our dependency headers
242
+ dynamic_project.targets.first.build_configuration_list.build_configurations.each do |config|
243
+ config.build_settings['HEADER_SEARCH_PATHS'] = "$(inherited) #{Dir.pwd}/Pods/Static/Headers/**"
244
+ config.build_settings['USER_HEADER_SEARCH_PATHS'] = "$(inherited) #{Dir.pwd}/Pods/Static/Headers/**"
245
+ config.build_settings['OTHER_LDFLAGS'] = '$(inherited) -ObjC'
246
+ end
247
+ dynamic_project.save
248
+ end
249
+ end
250
+ end
251
+ end
252
+ end