cocoapods-panglePackager 1.5.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/Gemfile +12 -0
  4. data/LICENSE +21 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +12 -0
  7. data/Rakefile +13 -0
  8. data/cocoapods-panglePackager.gemspec +25 -0
  9. data/lib/cocoapods-panglePackager/builder.rb +321 -0
  10. data/lib/cocoapods-panglePackager/framework.rb +66 -0
  11. data/lib/cocoapods-panglePackager/mangle.rb +32 -0
  12. data/lib/cocoapods-panglePackager/pod_utils.rb +252 -0
  13. data/lib/cocoapods-panglePackager/spec_builder.rb +63 -0
  14. data/lib/cocoapods-panglePackager/symbols.rb +35 -0
  15. data/lib/cocoapods-panglePackager/user_interface/build_failed_report.rb +15 -0
  16. data/lib/cocoapods_panglePackager.rb +6 -0
  17. data/lib/cocoapods_plugin.rb +9 -0
  18. data/lib/pod/command/panglepackage.rb +169 -0
  19. data/scripts/lstconst.sh +9 -0
  20. data/scripts/lstsym.sh +8 -0
  21. data/spec/command/error_spec.rb +74 -0
  22. data/spec/command/package_spec.rb +359 -0
  23. data/spec/command/subspecs_spec.rb +30 -0
  24. data/spec/fixtures/Builder.podspec +25 -0
  25. data/spec/fixtures/CPDColors.podspec +19 -0
  26. data/spec/fixtures/FH.podspec +18 -0
  27. data/spec/fixtures/KFData.podspec +73 -0
  28. data/spec/fixtures/LibraryConsumerDemo/.gitignore +22 -0
  29. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcodeproj/project.pbxproj +340 -0
  30. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  31. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcodeproj/xcshareddata/xcschemes/LibraryConsumer.xcscheme +100 -0
  32. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/AppDelegate.h +17 -0
  33. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/AppDelegate.m +27 -0
  34. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/Info.plist +40 -0
  35. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/main.m +16 -0
  36. data/spec/fixtures/LibraryConsumerDemo/Podfile +5 -0
  37. data/spec/fixtures/LibraryDemo.podspec +14 -0
  38. data/spec/fixtures/NikeKit.podspec +19 -0
  39. data/spec/fixtures/OpenSans.podspec +18 -0
  40. data/spec/fixtures/PackagerTest/.gitignore +21 -0
  41. data/spec/fixtures/PackagerTest/PackagerTest.xcodeproj/project.pbxproj +536 -0
  42. data/spec/fixtures/PackagerTest/PackagerTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  43. data/spec/fixtures/PackagerTest/PackagerTest.xcodeproj/xcshareddata/xcschemes/PackagerTest.xcscheme +110 -0
  44. data/spec/fixtures/PackagerTest/PackagerTest.xcworkspace/contents.xcworkspacedata +1 -0
  45. data/spec/fixtures/PackagerTest/PackagerTest/CPDAppDelegate.h +15 -0
  46. data/spec/fixtures/PackagerTest/PackagerTest/CPDAppDelegate.m +49 -0
  47. data/spec/fixtures/PackagerTest/PackagerTest/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  48. data/spec/fixtures/PackagerTest/PackagerTest/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  49. data/spec/fixtures/PackagerTest/PackagerTest/PackagerTest-Info.plist +38 -0
  50. data/spec/fixtures/PackagerTest/PackagerTest/PackagerTest-Prefix.pch +16 -0
  51. data/spec/fixtures/PackagerTest/PackagerTest/en.lproj/InfoPlist.strings +2 -0
  52. data/spec/fixtures/PackagerTest/PackagerTest/main.m +18 -0
  53. data/spec/fixtures/PackagerTest/PackagerTestTests/PackagerTestTests-Info.plist +22 -0
  54. data/spec/fixtures/PackagerTest/PackagerTestTests/PackagerTestTests.m +34 -0
  55. data/spec/fixtures/PackagerTest/PackagerTestTests/en.lproj/InfoPlist.strings +2 -0
  56. data/spec/fixtures/PackagerTest/Podfile +10 -0
  57. data/spec/fixtures/PackagerTest/Podfile.lock +32 -0
  58. data/spec/fixtures/Weakly.podspec +13 -0
  59. data/spec/fixtures/a.podspec +19 -0
  60. data/spec/fixtures/foo-bar.podspec +19 -0
  61. data/spec/fixtures/layer-client-messaging-schema.podspec +13 -0
  62. data/spec/integration/project_spec.rb +70 -0
  63. data/spec/pod/utils_spec.rb +58 -0
  64. data/spec/spec_helper.rb +50 -0
  65. data/spec/specification/builder_spec.rb +40 -0
  66. data/spec/specification/spec_builder_spec.rb +61 -0
  67. data/spec/user_interface/build_failed_report_spec.rb +11 -0
  68. metadata +204 -0
@@ -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,6 @@
1
+ module Pod
2
+ module PanglePackager
3
+ VERSION = '1.5.0.1'.freeze
4
+ end
5
+ end
6
+
@@ -0,0 +1,9 @@
1
+ require 'pod/command/panglepackage'
2
+ require 'cocoapods-panglePackager/user_interface/build_failed_report'
3
+ require 'cocoapods-panglePackager/builder'
4
+ require 'cocoapods-panglePackager/framework'
5
+ require 'cocoapods-panglePackager/mangle'
6
+ require 'cocoapods-panglePackager/pod_utils'
7
+ require 'cocoapods-panglePackager/spec_builder'
8
+ require 'cocoapods-panglePackager/symbols'
9
+
@@ -0,0 +1,169 @@
1
+ require 'tmpdir'
2
+ module Pod
3
+ class Command
4
+ class PanglePackage < Command
5
+ self.summary = 'Pangle 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/pangle-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}/pangle-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::PangleBuilder.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
@@ -0,0 +1,9 @@
1
+ #!/bin/sh
2
+
3
+ #
4
+ # List symbols for all constants
5
+ #
6
+
7
+ nm "$@"|grep ' S '|grep -v 'OBJC\|\.eh$'| \
8
+ cut -d_ -f2-|sort|uniq
9
+ nm "$@"|grep ' T '|cut -d_ -f2-|sort|uniq
data/scripts/lstsym.sh ADDED
@@ -0,0 +1,8 @@
1
+ #!/bin/sh
2
+
3
+ #
4
+ # List symbols for all Objective-C classes
5
+ #
6
+
7
+ nm "$@"| grep 'OBJC_CLASS_\$_'|grep -v '_NS\|_UI'| \
8
+ rev|cut -d' ' -f-1|rev|sort|uniq|cut -d'_' -f5-
@@ -0,0 +1,74 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Pod
4
+ describe 'PanglePackager' do
5
+ after do
6
+ Dir.glob("CPDColors-*").each { |dir| Pathname.new(dir).rmtree }
7
+ Dir.glob("layer-client-messaging-schema-*").each { |dir| Pathname.new(dir).rmtree }
8
+ Dir.glob("OpenSans-*").each { |dir| Pathname.new(dir).rmtree }
9
+ Dir.glob("Weakly-*").each { |dir| Pathname.new(dir).rmtree }
10
+ end
11
+
12
+ it 'presents the help if a directory is provided' do
13
+ should.raise CLAide::Help do
14
+ command = Command.parse(%w{ pangle-package spec })
15
+ end.message.should.match /is a directory/
16
+ end
17
+
18
+ it 'presents the help if a random file is provided instead of a specification' do
19
+ should.raise CLAide::Help do
20
+ command = Command.parse(%w{ pangle-package README.md })
21
+ end.message.should.match /is not a podspec/
22
+ end
23
+
24
+ it 'presents the help if a podspec with binary-only dependencies is used' do
25
+ command = Command.parse(%w{ pangle-package spec/fixtures/CPDColors.podspec })
26
+ should.raise CLAide::Help do
27
+ command.validate!
28
+ end.message.should.match /binary-only/
29
+ end
30
+
31
+ it 'presents the help if only --bundle-identifier is specified' do
32
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec --bundle-identifier=com.example.NikeKit })
33
+ should.raise CLAide::Help do
34
+ command.validate!
35
+ end.message.should.match /--bundle-identifier option can only be used for dynamic frameworks/
36
+ end
37
+
38
+ it 'presents the help if both --exclude-deps and --dynamic are specified' do
39
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec --exclude-deps --dynamic })
40
+ should.raise CLAide::Help do
41
+ command.validate!
42
+ end.message.should.match /--exclude-deps option can only be used for static libraries/
43
+ end
44
+
45
+ it 'can pangle-package a podspec with only resources' do
46
+ command = Command.parse(%w{ pangle-package spec/fixtures/layer-client-messaging-schema.podspec --no-mangle })
47
+ command.run
48
+
49
+ true.should == true # To make the test pass without any shoulds
50
+ end
51
+
52
+ it 'can pangle-package a podspec with binary-only dependencies if --no-mangle is specified' do
53
+ command = Command.parse(%w{ pangle-package spec/fixtures/CPDColors.podspec --no-mangle })
54
+ command.run
55
+
56
+ true.should == true # To make the test pass without any shoulds
57
+ end
58
+
59
+ it 'can pangle-package a podspec with resource bundles' do
60
+ command = Command.parse(%w{ pangle-package spec/fixtures/OpenSans.podspec })
61
+ command.run
62
+
63
+ bundles = Dir.glob('OpenSans-*/ios/OpenSans.framework/Versions/A/Resources/*.bundle')
64
+ bundles.count.should == 1
65
+ end
66
+
67
+ it 'can pangle-package a podspec with weak frameworks without strong linking' do
68
+ command = Command.parse(%w{ pangle-package spec/fixtures/Weakly.podspec })
69
+ command.run
70
+
71
+ `otool -l Weakly-*/ios/Weakly.framework/Weakly`.should.not.match /AssetsLibrary/
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,359 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Pod
4
+
5
+ DONT_CODESIGN = true
6
+
7
+ describe Command::Spec::PanglePackage do
8
+ describe 'CLAide' do
9
+ after do
10
+ Dir.glob("KFData-*").each { |dir| Pathname.new(dir).rmtree }
11
+ Dir.glob("NikeKit-*").each { |dir| Pathname.new(dir).rmtree }
12
+ Dir.glob("foo-bar-*").each { |dir| Pathname.new(dir).rmtree }
13
+ Dir.glob("a-*").each { |dir| Pathname.new(dir).rmtree }
14
+ Dir.glob("FH-*").each { |dir| Pathname.new(dir).rmtree }
15
+ end
16
+
17
+ it 'registers itself' do
18
+ Command.parse(%w{ pangle-package }).should.be.instance_of Command::PanglePackage
19
+ end
20
+
21
+ it 'presents the help if no spec is provided' do
22
+ command = Command.parse(%w{ pangle-package })
23
+ should.raise CLAide::Help do
24
+ command.validate!
25
+ end.message.should.match /required/
26
+ end
27
+
28
+ it "errors if it cannot find a spec" do
29
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
30
+
31
+ command = Command.parse(%w{ pangle-package KFData })
32
+ should.raise CLAide::Help do
33
+ command.run
34
+ end.message.should.match /Unable to find/
35
+ end
36
+
37
+
38
+ it "should produce a dynamic library when dynamic is specified" do
39
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
40
+
41
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec --dynamic })
42
+ command.run
43
+
44
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
45
+ file_command = "file #{lib}"
46
+ output = `#{file_command}`.lines.to_a
47
+
48
+ output[0].should.match /Mach-O universal binary with 5 architectures/
49
+ output[1].should.match /Mach-O dynamically linked shared library i386/
50
+ end
51
+
52
+ it "should produce a dSYM when dynamic is specified" do
53
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
54
+
55
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec --dynamic })
56
+ command.run
57
+
58
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework.dSYM/Contents/Resources/DWARF/NikeKit").first
59
+ file_command = "file #{lib}"
60
+ output = `#{file_command}`.lines.to_a
61
+
62
+ output[0].should.match /Mach-O universal binary with 3 architectures/
63
+ output[1].should.match /Mach-O dSYM companion file arm/
64
+ end
65
+
66
+ it "should link category symbols when dynamic is specified" do
67
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
68
+
69
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec --dynamic })
70
+ command.run
71
+
72
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
73
+ file_command = "nm #{lib}"
74
+ output = `#{file_command}`.lines.to_a
75
+
76
+ match = output.detect { |line| line =~ /UIButton\(AFNetworking\)/ }
77
+ match.should.not.be.empty
78
+ end
79
+
80
+ it "should produce a dynamic library for OSX when dynamic is specified" do
81
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
82
+
83
+ command = Command.parse(%w{ pangle-package spec/fixtures/KFData.podspec --dynamic })
84
+ command.run
85
+
86
+ lib = Dir.glob("KFData-*/osx/KFData.framework/KFData").first
87
+ file_command = "file #{lib}"
88
+ output = `#{file_command}`.lines.to_a
89
+
90
+ output[0].should.match /Mach-O 64-bit dynamically linked shared library x86_64/
91
+ end
92
+
93
+ it "should produce a dSYM for OSX when dynamic is specified" do
94
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
95
+
96
+ command = Command.parse(%w{ pangle-package spec/fixtures/KFData.podspec --dynamic })
97
+ command.run
98
+
99
+ lib = Dir.glob("KFData-*/osx/KFData.framework.dSYM/Contents/Resources/DWARF/KFData").first
100
+ file_command = "file #{lib}"
101
+ output = `#{file_command}`.lines.to_a
102
+
103
+ output[0].should.match /Mach-O 64-bit dSYM companion file x86_64/
104
+ end
105
+
106
+ it "should produce the default plist for iOS and OSX when --dynamic is specified but --bundle-identifier is not" do
107
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
108
+
109
+ command = Command.parse(%w{ pangle-package spec/fixtures/KFData.podspec --dynamic})
110
+ command.run
111
+
112
+ ios_plist = File.expand_path(Dir.glob("KFData-*/ios/KFData.framework/Info.plist").first)
113
+ osx_plist = File.expand_path(Dir.glob("KFData-*/osx/KFData.framework/Resources/Info.plist").first)
114
+
115
+ ios_bundle_id = `defaults read #{ios_plist} CFBundleIdentifier`
116
+ osx_bundle_id = `defaults read #{osx_plist} CFBundleIdentifier`
117
+
118
+ ios_bundle_id.should.match /org.cocoapods.KFData/
119
+ osx_bundle_id.should.match /org.cocoapods.KFData/
120
+ end
121
+
122
+ it "should produce the correct plist for iOS and OSX when --dynamic and --bundle-identifier are specified" do
123
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
124
+
125
+ command = Command.parse(%w{ pangle-package spec/fixtures/KFData.podspec --dynamic --bundle-identifier=com.example.KFData})
126
+ command.run
127
+
128
+ ios_plist = File.expand_path(Dir.glob("KFData-*/ios/KFData.framework/Info.plist").first)
129
+ osx_plist = File.expand_path(Dir.glob("KFData-*/osx/KFData.framework/Resources/Info.plist").first)
130
+
131
+ ios_bundle_id = `defaults read #{ios_plist} CFBundleIdentifier`
132
+ osx_bundle_id = `defaults read #{osx_plist} CFBundleIdentifier`
133
+
134
+ ios_bundle_id.should.match /com.example.KFData/
135
+ osx_bundle_id.should.match /com.example.KFData/
136
+ end
137
+
138
+ it "should produce a static library when dynamic is not specified" do
139
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
140
+
141
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec })
142
+ command.run
143
+
144
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
145
+ file_command = "file #{lib}"
146
+ output = `#{file_command}`.lines.to_a
147
+
148
+ output[0].should.match /Mach-O universal binary with 5 architectures/
149
+ output[1].should.match /current ar archive/
150
+ end
151
+
152
+ it "mangles symbols if the Pod has dependencies" do
153
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
154
+
155
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec })
156
+ command.run
157
+
158
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
159
+ symbols = Symbols.symbols_from_library(lib).uniq.sort.reject { |e| e =~ /PodNikeKit/ }
160
+
161
+ symbols.should == %w{ BBUNikePlusActivity BBUNikePlusSessionManager
162
+ BBUNikePlusTag }
163
+ end
164
+
165
+ it "mangles symbols if the Pod has dependencies and framework is dynamic" do
166
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
167
+
168
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec --dynamic })
169
+ command.run
170
+
171
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
172
+ symbols = Symbols.symbols_from_library(lib).uniq.sort.reject { |e| e =~ /PodNikeKit/ }
173
+
174
+ symbols.should == %w{ BBUNikePlusActivity BBUNikePlusSessionManager
175
+ BBUNikePlusTag NikeKitVersionNumber NikeKitVersionString }
176
+ end
177
+
178
+ it "mangles symbols if the Pod has dependencies regardless of name" do
179
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
180
+
181
+ command = Command.parse(%w{ pangle-package spec/fixtures/a.podspec })
182
+ command.run
183
+
184
+ lib = Dir.glob("a-*/ios/a.framework/a").first
185
+ symbols = Symbols.symbols_from_library(lib).uniq.sort.reject { |e| e =~ /Poda/ }
186
+ symbols.should == %w{ BBUNikePlusActivity BBUNikePlusSessionManager
187
+ BBUNikePlusTag }
188
+ end
189
+
190
+ it "does not mangle symbols if option --no-mangle is specified" do
191
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
192
+
193
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec --no-mangle })
194
+ command.run
195
+
196
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
197
+ symbols = Symbols.symbols_from_library(lib).uniq.sort.select { |e| e =~ /PodNikeKit/ }
198
+ symbols.should == []
199
+ end
200
+
201
+ it "does not mangle symbols if option --no-mangle and --dynamic are specified" do
202
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
203
+
204
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec --no-mangle --dynamic })
205
+ command.run
206
+
207
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
208
+ symbols = Symbols.symbols_from_library(lib).uniq.sort.select { |e| e =~ /PodNikeKit/ }
209
+ symbols.should == []
210
+ end
211
+
212
+ it "does not include symbols from dependencies if option --exclude-deps is specified" do
213
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
214
+
215
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec --exclude-deps })
216
+ command.run
217
+
218
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
219
+ symbols = Symbols.symbols_from_library(lib).uniq.sort.select { |e| e =~ /AFNetworking|ISO8601DateFormatter|KZPropertyMapper/ }
220
+ symbols.should == []
221
+ end
222
+
223
+ it "includes the correct architectures when packaging an iOS Pod" do
224
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
225
+
226
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec })
227
+ command.run
228
+
229
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
230
+ `lipo #{lib} -verify_arch x86_64 i386 armv7 armv7s arm64`
231
+ $?.success?.should == true
232
+ end
233
+
234
+ it "includes the correct architectures when packaging an iOS Pod as --dynamic" do
235
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
236
+
237
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec --dynamic })
238
+ command.run
239
+
240
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
241
+ `lipo #{lib} -verify_arch armv7 armv7s arm64`
242
+ $?.success?.should == true
243
+ end
244
+
245
+ it "includes Bitcode for device arch slices when packaging an iOS Pod" do
246
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
247
+
248
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec })
249
+ command.run
250
+
251
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
252
+
253
+ #Check for __LLVM segment in each device architecture
254
+ `lipo -extract armv7 #{lib} -o armv7.a && otool -l armv7.a`.should.match /__LLVM/
255
+ `lipo -extract armv7s #{lib} -o armv7s.a && otool -l armv7s.a`.should.match /__LLVM/
256
+ `lipo -extract arm64 #{lib} -o arm64.a && otool -l arm64.a`.should.match /__LLVM/
257
+ `rm armv7.a armv7s.a arm64.a`
258
+ end
259
+
260
+ it "includes Bitcode for device arch slices when packaging an dynamic iOS Pod" do
261
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
262
+
263
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec --dynamic })
264
+ command.run
265
+
266
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
267
+
268
+ #Check for __LLVM segment in each device architecture
269
+ `lipo -extract armv7 #{lib} -o armv7.a && otool -l armv7.a`.should.match /__LLVM/
270
+ `lipo -extract armv7s #{lib} -o armv7s.a && otool -l armv7s.a`.should.match /__LLVM/
271
+ `lipo -extract arm64 #{lib} -o arm64.a && otool -l arm64.a`.should.match /__LLVM/
272
+ `rm armv7.a armv7s.a arm64.a`
273
+ end
274
+
275
+ it "does not include Bitcode for simulator arch slices when packaging an iOS Pod" do
276
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
277
+
278
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec })
279
+ command.run
280
+
281
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
282
+
283
+ #Check for __LLVM segment in each simulator architecture
284
+ `lipo -extract i386 #{lib} -o i386.a && otool -l i386.a`.should.not.match /__LLVM/
285
+ `lipo -extract x86_64 #{lib} -o x86_64.a && otool -l x86_64.a`.should.not.match /__LLVM/
286
+ `rm i386.a x86_64.a`
287
+ end
288
+
289
+ it "does not include Bitcode for simulator arch slices when packaging an dynamic iOS Pod" do
290
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
291
+
292
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec --dynamic })
293
+ command.run
294
+
295
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
296
+
297
+ #Check for __LLVM segment in each simulator architecture
298
+ `lipo -extract i386 #{lib} -o i386.a && otool -l i386.a`.should.not.match /__LLVM/
299
+ `lipo -extract x86_64 #{lib} -o x86_64.a && otool -l x86_64.a`.should.not.match /__LLVM/
300
+ `rm i386.a x86_64.a`
301
+ end
302
+
303
+ it "does not include local ModuleCache references" do
304
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
305
+
306
+ command = Command.parse(%w{ pangle-package spec/fixtures/NikeKit.podspec })
307
+ command.run
308
+
309
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
310
+
311
+ #Check for ModuleCache references
312
+ `strings #{lib}`.should.not.match /ModuleCache/
313
+ end
314
+
315
+ it "does not fail when the pod name contains a dash" do
316
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
317
+
318
+ command = Command.parse(%w{ pangle-package spec/fixtures/foo-bar.podspec })
319
+ command.run
320
+
321
+ true.should == true # To make the test pass without any shoulds
322
+ end
323
+
324
+ it "runs with a path to a spec" do
325
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
326
+
327
+ command = Command.parse(%w{ pangle-package spec/fixtures/KFData.podspec })
328
+ command.run
329
+
330
+ true.should == true # To make the test pass without any shoulds
331
+ end
332
+
333
+ it "it respects module_map directive" do
334
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
335
+
336
+ command = Command.parse(%w{ pangle-package spec/fixtures/FH.podspec })
337
+ command.run
338
+
339
+ modulemap_contents = File.read(Dir.glob("FH-*/ios/FH.framework/Modules/module.modulemap").first)
340
+ module_map = <<MAP
341
+ framework module FH {
342
+ umbrella header "FeedHenry.h"
343
+
344
+ export *
345
+ module * { export * }
346
+ }
347
+ MAP
348
+ modulemap_contents.should == module_map
349
+ end
350
+
351
+ # it "runs with a spec in the master repository" do
352
+ # command = Command.parse(%w{ pangle-package KFData })
353
+ # command.run
354
+ #
355
+ # true.should == true # To make the test pass without any shoulds
356
+ # end
357
+ end
358
+ end
359
+ end