cocoapods-fanQiePackager 1.5.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/Gemfile +13 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +11 -0
  6. data/Rakefile +13 -0
  7. data/cocoapods-fanQiePackager.gemspec +25 -0
  8. data/lib/cocoapods-fanQiePackager/builder.rb +321 -0
  9. data/lib/cocoapods-fanQiePackager/framework.rb +66 -0
  10. data/lib/cocoapods-fanQiePackager/mangle.rb +32 -0
  11. data/lib/cocoapods-fanQiePackager/pod_utils.rb +252 -0
  12. data/lib/cocoapods-fanQiePackager/spec_builder.rb +63 -0
  13. data/lib/cocoapods-fanQiePackager/symbols.rb +35 -0
  14. data/lib/cocoapods-fanQiePackager/user_interface/build_failed_report.rb +15 -0
  15. data/lib/cocoapods_fanQiePackager.rb +7 -0
  16. data/lib/cocoapods_plugin.rb +8 -0
  17. data/lib/pod/command/fanqiepackage.rb +169 -0
  18. data/scripts/lstconst.sh +9 -0
  19. data/scripts/lstsym.sh +8 -0
  20. data/spec/command/error_spec.rb +74 -0
  21. data/spec/command/package_spec.rb +359 -0
  22. data/spec/command/subspecs_spec.rb +30 -0
  23. data/spec/fixtures/Builder.podspec +25 -0
  24. data/spec/fixtures/CPDColors.podspec +19 -0
  25. data/spec/fixtures/FH.podspec +18 -0
  26. data/spec/fixtures/KFData.podspec +73 -0
  27. data/spec/fixtures/LibraryConsumerDemo/.gitignore +22 -0
  28. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcodeproj/project.pbxproj +340 -0
  29. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  30. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcodeproj/xcshareddata/xcschemes/LibraryConsumer.xcscheme +100 -0
  31. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/AppDelegate.h +17 -0
  32. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/AppDelegate.m +27 -0
  33. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/Info.plist +40 -0
  34. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/main.m +16 -0
  35. data/spec/fixtures/LibraryConsumerDemo/Podfile +5 -0
  36. data/spec/fixtures/LibraryDemo.podspec +14 -0
  37. data/spec/fixtures/NikeKit.podspec +19 -0
  38. data/spec/fixtures/OpenSans.podspec +18 -0
  39. data/spec/fixtures/PackagerTest/.gitignore +21 -0
  40. data/spec/fixtures/PackagerTest/PackagerTest.xcodeproj/project.pbxproj +536 -0
  41. data/spec/fixtures/PackagerTest/PackagerTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  42. data/spec/fixtures/PackagerTest/PackagerTest.xcodeproj/xcshareddata/xcschemes/PackagerTest.xcscheme +110 -0
  43. data/spec/fixtures/PackagerTest/PackagerTest.xcworkspace/contents.xcworkspacedata +1 -0
  44. data/spec/fixtures/PackagerTest/PackagerTest/CPDAppDelegate.h +15 -0
  45. data/spec/fixtures/PackagerTest/PackagerTest/CPDAppDelegate.m +49 -0
  46. data/spec/fixtures/PackagerTest/PackagerTest/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  47. data/spec/fixtures/PackagerTest/PackagerTest/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  48. data/spec/fixtures/PackagerTest/PackagerTest/PackagerTest-Info.plist +38 -0
  49. data/spec/fixtures/PackagerTest/PackagerTest/PackagerTest-Prefix.pch +16 -0
  50. data/spec/fixtures/PackagerTest/PackagerTest/en.lproj/InfoPlist.strings +2 -0
  51. data/spec/fixtures/PackagerTest/PackagerTest/main.m +18 -0
  52. data/spec/fixtures/PackagerTest/PackagerTestTests/PackagerTestTests-Info.plist +22 -0
  53. data/spec/fixtures/PackagerTest/PackagerTestTests/PackagerTestTests.m +34 -0
  54. data/spec/fixtures/PackagerTest/PackagerTestTests/en.lproj/InfoPlist.strings +2 -0
  55. data/spec/fixtures/PackagerTest/Podfile +10 -0
  56. data/spec/fixtures/PackagerTest/Podfile.lock +32 -0
  57. data/spec/fixtures/Weakly.podspec +13 -0
  58. data/spec/fixtures/a.podspec +19 -0
  59. data/spec/fixtures/foo-bar.podspec +19 -0
  60. data/spec/fixtures/layer-client-messaging-schema.podspec +13 -0
  61. data/spec/integration/project_spec.rb +70 -0
  62. data/spec/pod/utils_spec.rb +58 -0
  63. data/spec/spec_helper.rb +50 -0
  64. data/spec/specification/builder_spec.rb +40 -0
  65. data/spec/specification/spec_builder_spec.rb +61 -0
  66. data/spec/user_interface/build_failed_report_spec.rb +11 -0
  67. metadata +203 -0
@@ -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 FanqiePackage < 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'] = 'YES'
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
@@ -0,0 +1,63 @@
1
+ module Pod
2
+ class SpecBuilder
3
+ def initialize(spec, source, embedded, dynamic)
4
+ @spec = spec
5
+ @source = source.nil? ? '{ :path => \'.\' }' : source
6
+ @embedded = embedded
7
+ @dynamic = dynamic
8
+ end
9
+
10
+ def framework_path
11
+ if @embedded
12
+ @spec.name + '.embeddedframework' + '/' + @spec.name + '.framework'
13
+ else
14
+ @spec.name + '.framework'
15
+ end
16
+ end
17
+
18
+ def spec_platform(platform)
19
+ fwk_base = platform.name.to_s + '/' + framework_path
20
+ spec = <<RB
21
+ s.#{platform.name}.deployment_target = '#{platform.deployment_target}'
22
+ s.#{platform.name}.vendored_framework = '#{fwk_base}'
23
+ RB
24
+
25
+ %w(frameworks weak_frameworks libraries requires_arc xcconfig).each do |attribute|
26
+ attributes_hash = @spec.attributes_hash[platform.name.to_s]
27
+ next if attributes_hash.nil?
28
+ value = attributes_hash[attribute]
29
+ next if value.nil?
30
+
31
+ value = "'#{value}'" if value.class == String
32
+ spec += " s.#{platform.name}.#{attribute} = #{value}\n"
33
+ end
34
+ spec
35
+ end
36
+
37
+ def spec_metadata
38
+ spec = spec_header
39
+ spec
40
+ end
41
+
42
+ def spec_close
43
+ "end\n"
44
+ end
45
+
46
+ private
47
+
48
+ def spec_header
49
+ spec = "Pod::Spec.new do |s|\n"
50
+
51
+ %w(name version summary license authors homepage description social_media_url
52
+ docset_url documentation_url screenshots frameworks weak_frameworks libraries requires_arc
53
+ deployment_target xcconfig).each do |attribute|
54
+ value = @spec.attributes_hash[attribute]
55
+ next if value.nil?
56
+ value = value.dump if value.class == String
57
+ spec += " s.#{attribute} = #{value}\n"
58
+ end
59
+
60
+ spec + " s.source = #{@source}\n\n"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,35 @@
1
+ module Symbols
2
+ def symbols_from_library(library)
3
+ syms = `nm -gU #{library}`.split("\n")
4
+ result = classes_from_symbols(syms)
5
+ result += constants_from_symbols(syms)
6
+
7
+ result.reject { |e| e == 'llvm.cmdline' || e == 'llvm.embedded.module' }
8
+ end
9
+
10
+ module_function :symbols_from_library
11
+
12
+ private
13
+
14
+ def classes_from_symbols(syms)
15
+ classes = syms.select { |klass| klass[/OBJC_CLASS_\$_/] }
16
+ classes = classes.uniq
17
+ classes.map! { |klass| klass.gsub(/^.*\$_/, '') }
18
+ end
19
+
20
+ def constants_from_symbols(syms)
21
+ consts = syms.select { |const| const[/ S /] }
22
+ consts = consts.select { |const| const !~ /OBJC|\.eh/ }
23
+ consts = consts.uniq
24
+ consts = consts.map! { |const| const.gsub(/^.* _/, '') }
25
+
26
+ other_consts = syms.select { |const| const[/ T /] }
27
+ other_consts = other_consts.uniq
28
+ other_consts = other_consts.map! { |const| const.gsub(/^.* _/, '') }
29
+
30
+ consts + other_consts
31
+ end
32
+
33
+ module_function :classes_from_symbols
34
+ module_function :constants_from_symbols
35
+ end
@@ -0,0 +1,15 @@
1
+ module Pod
2
+ module UserInterface
3
+ module BuildFailedReport
4
+ class << self
5
+ def report(command, output)
6
+ <<-EOF
7
+ Build command failed: #{command}
8
+ Output:
9
+ #{output.map { |line| " #{line}" }.join}
10
+ EOF
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module Pod
2
+ module FanqiePackager
3
+ VERSION = '1.5.0.1'.freeze
4
+ end
5
+ end
6
+
7
+
@@ -0,0 +1,8 @@
1
+ require 'pod/command/fanqiepackage'
2
+ require 'cocoapods-fanQiePackager/user_interface/build_failed_report'
3
+ require 'cocoapods-fanQiePackager/builder'
4
+ require 'cocoapods-fanQiePackager/framework'
5
+ require 'cocoapods-fanQiePackager/mangle'
6
+ require 'cocoapods-fanQiePackager/pod_utils'
7
+ require 'cocoapods-fanQiePackager/spec_builder'
8
+ require 'cocoapods-fanQiePackager/symbols'
@@ -0,0 +1,169 @@
1
+ require 'tmpdir'
2
+ module Pod
3
+ class Command
4
+ class FanqiePackage < Command
5
+ self.summary = 'Fanqie plugin which package a podspec into a static library.'
6
+ self.arguments = [
7
+ CLAide::Argument.new('NAME', true),
8
+ CLAide::Argument.new('SOURCE', false)
9
+ ]
10
+
11
+ def self.options
12
+ [
13
+ ['--force', 'Overwrite existing files.'],
14
+ ['--no-mangle', 'Do not mangle symbols of depedendant Pods.'],
15
+ ['--embedded', 'Generate embedded frameworks.'],
16
+ ['--library', 'Generate static libraries.'],
17
+ ['--dynamic', 'Generate dynamic framework.'],
18
+ ['--bundle-identifier', 'Bundle identifier for dynamic framework'],
19
+ ['--exclude-deps', 'Exclude symbols from dependencies.'],
20
+ ['--configuration', 'Build the specified configuration (e.g. Debug). Defaults to Release'],
21
+ ['--subspecs', 'Only include the given subspecs'],
22
+ ['--spec-sources=private,https://github.com/CocoaPods/Specs.git', 'The sources to pull dependant ' \
23
+ 'pods from (defaults to https://github.com/CocoaPods/Specs.git)'],
24
+ ['--toolchain', 'xcodebuild toolchain (e.g. --toolchain=Byteguard-Bitcode)'],
25
+ ['--logpath', 'Logs path (e.g. --logpath=/Users/username/Desktop/fanqie-package/Logs)']
26
+ ]
27
+ end
28
+
29
+ def initialize(argv)
30
+ @embedded = argv.flag?('embedded')
31
+ @force = argv.flag?('force')
32
+ @library = argv.flag?('library')
33
+ @dynamic = argv.flag?('dynamic')
34
+ @mangle = argv.flag?('mangle', true)
35
+ @bundle_identifier = argv.option('bundle-identifier', nil)
36
+ @exclude_deps = argv.flag?('exclude-deps', false)
37
+ @name = argv.shift_argument
38
+ @source = argv.shift_argument
39
+ @spec_sources = argv.option('spec-sources', 'https://github.com/CocoaPods/Specs.git').split(',')
40
+
41
+ subspecs = argv.option('subspecs')
42
+ @subspecs = subspecs.split(',') unless subspecs.nil?
43
+
44
+ @config = argv.option('configuration', 'Release')
45
+
46
+ @source_dir = Dir.pwd
47
+ @spec = spec_with_path(@name)
48
+ @spec = spec_with_name(@name) unless @spec
49
+ @toolchain = argv.option('toolchain', '')
50
+ @logpath = argv.option('logpath', "#{Dir.home}/fanqie-package/Logs")
51
+ super
52
+ end
53
+
54
+ def validate!
55
+ super
56
+ help! 'A podspec name or path is required.' unless @spec
57
+ help! 'podspec has binary-only depedencies, mangling not possible.' if @mangle && binary_only?(@spec)
58
+ help! '--bundle-identifier option can only be used for dynamic frameworks' if @bundle_identifier && !@dynamic
59
+ help! '--exclude-deps option can only be used for static libraries' if @exclude_deps && @dynamic
60
+ end
61
+
62
+ def run
63
+ if @path.nil? || @spec.nil?
64
+ help! 'Unable to find a podspec with path or name.'
65
+ return
66
+ end
67
+
68
+ target_dir, work_dir = create_working_directory
69
+ return if target_dir.nil?
70
+ build_package
71
+
72
+ `mv "#{work_dir}" "#{target_dir}"`
73
+ Dir.chdir(@source_dir)
74
+ end
75
+
76
+ private
77
+
78
+ def build_in_sandbox(platform)
79
+ config.installation_root = Pathname.new(Dir.pwd)
80
+ config.sandbox_root = 'Pods'
81
+
82
+ static_sandbox = build_static_sandbox(@dynamic)
83
+ static_installer = install_pod(platform.name, static_sandbox)
84
+
85
+ if @dynamic
86
+ dynamic_sandbox = build_dynamic_sandbox(static_sandbox, static_installer)
87
+ install_dynamic_pod(dynamic_sandbox, static_sandbox, static_installer)
88
+ end
89
+
90
+ begin
91
+ perform_build(platform, static_sandbox, dynamic_sandbox)
92
+
93
+ ensure # in case the build fails; see Builder#xcodebuild.
94
+ Pathname.new(config.sandbox_root).rmtree
95
+ FileUtils.rm_f('Podfile.lock')
96
+ end
97
+ end
98
+
99
+ def build_package
100
+ builder = SpecBuilder.new(@spec, @source, @embedded, @dynamic)
101
+ newspec = builder.spec_metadata
102
+
103
+ @spec.available_platforms.each do |platform|
104
+ build_in_sandbox(platform)
105
+
106
+ newspec += builder.spec_platform(platform)
107
+ end
108
+
109
+ newspec += builder.spec_close
110
+ File.open(@spec.name + '.podspec', 'w') { |file| file.write(newspec) }
111
+ end
112
+
113
+ def create_target_directory
114
+ target_dir = "#{@source_dir}/#{@spec.name}-#{@spec.version}"
115
+ if File.exist? target_dir
116
+ if @force
117
+ Pathname.new(target_dir).rmtree
118
+ else
119
+ UI.puts "Target directory '#{target_dir}' already exists."
120
+ return nil
121
+ end
122
+ end
123
+ target_dir
124
+ end
125
+
126
+ def create_working_directory
127
+ target_dir = create_target_directory
128
+ return if target_dir.nil?
129
+
130
+ work_dir = Dir.tmpdir + '/cocoapods-' + Array.new(8) { rand(36).to_s(36) }.join
131
+ Pathname.new(work_dir).mkdir
132
+ `cp #{@path} #{work_dir}`
133
+ Dir.chdir(work_dir)
134
+
135
+ [target_dir, work_dir]
136
+ end
137
+
138
+ def perform_build(platform, static_sandbox, dynamic_sandbox)
139
+ static_sandbox_root = config.sandbox_root.to_s
140
+
141
+ if @dynamic
142
+ static_sandbox_root = "#{static_sandbox_root}/#{static_sandbox.root.to_s.split('/').last}"
143
+ dynamic_sandbox_root = "#{config.sandbox_root}/#{dynamic_sandbox.root.to_s.split('/').last}"
144
+ end
145
+
146
+ builder = Pod::FanqieBuilder.new(
147
+ @source_dir,
148
+ static_sandbox_root,
149
+ dynamic_sandbox_root,
150
+ static_sandbox.public_headers.root,
151
+ @spec,
152
+ @embedded,
153
+ @mangle,
154
+ @dynamic,
155
+ @config,
156
+ @bundle_identifier,
157
+ @exclude_deps,
158
+ @toolchain,
159
+ @logpath
160
+ )
161
+
162
+ builder.build(platform, @library)
163
+
164
+ return unless @embedded
165
+ builder.link_embedded_resources
166
+ end
167
+ end
168
+ end
169
+ end