cocoapods-packager-pro 1.5.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.
Files changed (77) 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 +129 -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 +339 -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 +232 -0
  17. data/lib/cocoapods-packager/spec_builder.rb +63 -0
  18. data/lib/cocoapods-packager/symbols.rb +42 -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 +177 -0
  23. data/scripts/lstconst.sh +9 -0
  24. data/scripts/lstsym.sh +8 -0
  25. data/spec/command/error_spec.rb +81 -0
  26. data/spec/command/package_spec.rb +410 -0
  27. data/spec/command/subspecs_spec.rb +30 -0
  28. data/spec/fixtures/Archs.podspec +13 -0
  29. data/spec/fixtures/Builder.podspec +25 -0
  30. data/spec/fixtures/CPDColors.podspec +19 -0
  31. data/spec/fixtures/FH.podspec +18 -0
  32. data/spec/fixtures/KFData.podspec +73 -0
  33. data/spec/fixtures/LibraryConsumerDemo/.gitignore +22 -0
  34. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcodeproj/project.pbxproj +343 -0
  35. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  36. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer.xcodeproj/xcshareddata/xcschemes/LibraryConsumer.xcscheme +100 -0
  37. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/AppDelegate.h +17 -0
  38. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/AppDelegate.m +27 -0
  39. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/Info.plist +40 -0
  40. data/spec/fixtures/LibraryConsumerDemo/LibraryConsumer/main.m +16 -0
  41. data/spec/fixtures/LibraryConsumerDemo/Podfile +5 -0
  42. data/spec/fixtures/LibraryDemo.podspec +14 -0
  43. data/spec/fixtures/LocalSources/LICENSE +0 -0
  44. data/spec/fixtures/LocalSources/LocalNikeKit.h +4 -0
  45. data/spec/fixtures/LocalSources/LocalNikeKit.m +9 -0
  46. data/spec/fixtures/LocalSources/LocalNikeKit.podspec +19 -0
  47. data/spec/fixtures/NikeKit.podspec +19 -0
  48. data/spec/fixtures/OpenSans.podspec +18 -0
  49. data/spec/fixtures/PackagerTest/.gitignore +21 -0
  50. data/spec/fixtures/PackagerTest/PackagerTest.xcodeproj/project.pbxproj +539 -0
  51. data/spec/fixtures/PackagerTest/PackagerTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  52. data/spec/fixtures/PackagerTest/PackagerTest.xcodeproj/xcshareddata/xcschemes/PackagerTest.xcscheme +110 -0
  53. data/spec/fixtures/PackagerTest/PackagerTest.xcworkspace/contents.xcworkspacedata +1 -0
  54. data/spec/fixtures/PackagerTest/PackagerTest/CPDAppDelegate.h +15 -0
  55. data/spec/fixtures/PackagerTest/PackagerTest/CPDAppDelegate.m +49 -0
  56. data/spec/fixtures/PackagerTest/PackagerTest/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  57. data/spec/fixtures/PackagerTest/PackagerTest/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  58. data/spec/fixtures/PackagerTest/PackagerTest/PackagerTest-Info.plist +38 -0
  59. data/spec/fixtures/PackagerTest/PackagerTest/PackagerTest-Prefix.pch +16 -0
  60. data/spec/fixtures/PackagerTest/PackagerTest/en.lproj/InfoPlist.strings +2 -0
  61. data/spec/fixtures/PackagerTest/PackagerTest/main.m +18 -0
  62. data/spec/fixtures/PackagerTest/PackagerTestTests/PackagerTestTests-Info.plist +22 -0
  63. data/spec/fixtures/PackagerTest/PackagerTestTests/PackagerTestTests.m +34 -0
  64. data/spec/fixtures/PackagerTest/PackagerTestTests/en.lproj/InfoPlist.strings +2 -0
  65. data/spec/fixtures/PackagerTest/Podfile +10 -0
  66. data/spec/fixtures/PackagerTest/Podfile.lock +32 -0
  67. data/spec/fixtures/Weakly.podspec +13 -0
  68. data/spec/fixtures/a.podspec +19 -0
  69. data/spec/fixtures/foo-bar.podspec +19 -0
  70. data/spec/fixtures/layer-client-messaging-schema.podspec +13 -0
  71. data/spec/integration/project_spec.rb +70 -0
  72. data/spec/pod/utils_spec.rb +58 -0
  73. data/spec/spec_helper.rb +50 -0
  74. data/spec/specification/builder_spec.rb +43 -0
  75. data/spec/specification/spec_builder_spec.rb +61 -0
  76. data/spec/user_interface/build_failed_report_spec.rb +11 -0
  77. metadata +222 -0
@@ -0,0 +1,5 @@
1
+ module Pod
2
+ module Packager
3
+ VERSION = '1.5.1'.freeze
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ require 'pod/command/package'
2
+ require 'cocoapods-packager/user_interface/build_failed_report'
3
+ require 'cocoapods-packager/builder'
4
+ require 'cocoapods-packager/framework'
5
+ require 'cocoapods-packager/mangle'
6
+ require 'cocoapods-packager/pod_utils'
7
+ require 'cocoapods-packager/spec_builder'
8
+ require 'cocoapods-packager/symbols'
@@ -0,0 +1,177 @@
1
+ require 'tmpdir'
2
+ module Pod
3
+ class Command
4
+ class Package < Command
5
+ self.summary = '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
+ ['--local', 'Use local state rather than published versions.'],
19
+ ['--bundle-identifier', 'Bundle identifier for dynamic framework'],
20
+ ['--exclude-deps', 'Exclude symbols from dependencies.'],
21
+ ['--configuration', 'Build the specified configuration (e.g. Debug). Defaults to Release'],
22
+ ['--subspecs', 'Only include the given subspecs'],
23
+ ['--spec-sources=private,https://github.com/CocoaPods/Specs.git', 'The sources to pull dependant ' \
24
+ 'pods from (defaults to https://github.com/CocoaPods/Specs.git)']
25
+ ]
26
+ end
27
+
28
+ def initialize(argv)
29
+ @embedded = argv.flag?('embedded')
30
+ @library = argv.flag?('library')
31
+ @dynamic = argv.flag?('dynamic')
32
+ @local = argv.flag?('local', false)
33
+ @package_type = if @embedded
34
+ :static_framework
35
+ elsif @dynamic
36
+ :dynamic_framework
37
+ elsif @library
38
+ :static_library
39
+ else
40
+ :static_framework
41
+ end
42
+ @force = argv.flag?('force')
43
+ @mangle = argv.flag?('mangle', true)
44
+ @bundle_identifier = argv.option('bundle-identifier', nil)
45
+ @exclude_deps = argv.flag?('exclude-deps', false)
46
+ @name = argv.shift_argument
47
+ @source = argv.shift_argument
48
+ @spec_sources = argv.option('spec-sources', 'https://github.com/CocoaPods/Specs.git').split(',')
49
+
50
+ subspecs = argv.option('subspecs')
51
+ @subspecs = subspecs.split(',') unless subspecs.nil?
52
+
53
+ @config = argv.option('configuration', 'Release')
54
+
55
+ @source_dir = Dir.pwd
56
+ @is_spec_from_path = false
57
+ @spec = spec_with_path(@name)
58
+ @is_spec_from_path = true if @spec
59
+ @spec ||= spec_with_name(@name)
60
+ super
61
+ end
62
+
63
+ def validate!
64
+ super
65
+ help! 'A podspec name or path is required.' unless @spec
66
+ help! 'podspec has binary-only depedencies, mangling not possible.' if @mangle && binary_only?(@spec)
67
+ help! '--bundle-identifier option can only be used for dynamic frameworks' if @bundle_identifier && !@dynamic
68
+ help! '--exclude-deps option can only be used for static libraries' if @exclude_deps && @dynamic
69
+ help! '--local option can only be used when a local `.podspec` path is given.' if @local && !@is_spec_from_path
70
+ end
71
+
72
+ def run
73
+ if @spec.nil?
74
+ help! 'Unable to find a podspec with path or name.'
75
+ return
76
+ end
77
+
78
+ target_dir, work_dir = create_working_directory
79
+ return if target_dir.nil?
80
+ build_package
81
+
82
+ `mv "#{work_dir}" "#{target_dir}"`
83
+ Dir.chdir(@source_dir)
84
+ end
85
+
86
+ private
87
+
88
+ def build_in_sandbox(platform)
89
+ config.installation_root = Pathname.new(Dir.pwd)
90
+ config.sandbox_root = 'Pods'
91
+
92
+ static_sandbox = build_static_sandbox(@dynamic)
93
+ static_installer = install_pod(platform.name, static_sandbox)
94
+
95
+ if @dynamic
96
+ dynamic_sandbox = build_dynamic_sandbox(static_sandbox, static_installer)
97
+ install_dynamic_pod(dynamic_sandbox, static_sandbox, static_installer)
98
+ end
99
+
100
+ begin
101
+ perform_build(platform, static_sandbox, dynamic_sandbox, static_installer)
102
+ ensure # in case the build fails; see Builder#xcodebuild.
103
+ Pathname.new(config.sandbox_root).rmtree
104
+ FileUtils.rm_f('Podfile.lock')
105
+ end
106
+ end
107
+
108
+ def build_package
109
+ builder = SpecBuilder.new(@spec, @source, @embedded, @dynamic)
110
+ newspec = builder.spec_metadata
111
+
112
+ @spec.available_platforms.each do |platform|
113
+ build_in_sandbox(platform)
114
+
115
+ newspec += builder.spec_platform(platform)
116
+ end
117
+
118
+ newspec += builder.spec_close
119
+ File.open(@spec.name + '.podspec', 'w') { |file| file.write(newspec) }
120
+ end
121
+
122
+ def create_target_directory
123
+ target_dir = "#{@source_dir}/#{@spec.name}-#{@spec.version}"
124
+ if File.exist? target_dir
125
+ if @force
126
+ Pathname.new(target_dir).rmtree
127
+ else
128
+ UI.puts "Target directory '#{target_dir}' already exists."
129
+ return nil
130
+ end
131
+ end
132
+ target_dir
133
+ end
134
+
135
+ def create_working_directory
136
+ target_dir = create_target_directory
137
+ return if target_dir.nil?
138
+
139
+ work_dir = Dir.tmpdir + '/cocoapods-' + Array.new(8) { rand(36).to_s(36) }.join
140
+ Pathname.new(work_dir).mkdir
141
+ Dir.chdir(work_dir)
142
+
143
+ [target_dir, work_dir]
144
+ end
145
+
146
+ def perform_build(platform, static_sandbox, dynamic_sandbox, static_installer)
147
+ static_sandbox_root = config.sandbox_root.to_s
148
+
149
+ if @dynamic
150
+ static_sandbox_root = "#{static_sandbox_root}/#{static_sandbox.root.to_s.split('/').last}"
151
+ dynamic_sandbox_root = "#{config.sandbox_root}/#{dynamic_sandbox.root.to_s.split('/').last}"
152
+ end
153
+
154
+ builder = Pod::Builder.new(
155
+ platform,
156
+ static_installer,
157
+ @source_dir,
158
+ static_sandbox_root,
159
+ dynamic_sandbox_root,
160
+ static_sandbox.public_headers.root,
161
+ @spec,
162
+ @embedded,
163
+ @mangle,
164
+ @dynamic,
165
+ @config,
166
+ @bundle_identifier,
167
+ @exclude_deps
168
+ )
169
+
170
+ builder.build(@package_type)
171
+
172
+ return unless @embedded
173
+ builder.link_embedded_resources
174
+ end
175
+ end
176
+ end
177
+ 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,81 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Pod
4
+ describe 'Packager' 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{ 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{ 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{ 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{ 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{ 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 'presents the help if --local is specified without .podspec path' do
46
+ command = Command.parse(%w{ package AFNetworking --local })
47
+ should.raise CLAide::Help do
48
+ command.validate!
49
+ end.message.should.match /--local option can only be used when a local `.podspec` path is given/
50
+ end
51
+
52
+ it 'can package a podspec with only resources' do
53
+ command = Command.parse(%w{ package spec/fixtures/layer-client-messaging-schema.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 package a podspec with binary-only dependencies if --no-mangle is specified' do
60
+ command = Command.parse(%w{ package spec/fixtures/CPDColors.podspec --no-mangle })
61
+ command.run
62
+
63
+ true.should == true # To make the test pass without any shoulds
64
+ end
65
+
66
+ it 'can package a podspec with resource bundles' do
67
+ command = Command.parse(%w{ package spec/fixtures/OpenSans.podspec })
68
+ command.run
69
+
70
+ bundles = Dir.glob('OpenSans-*/ios/OpenSans.framework/Versions/A/Resources/*.bundle')
71
+ bundles.count.should == 1
72
+ end
73
+
74
+ it 'can package a podspec with weak frameworks without strong linking' do
75
+ command = Command.parse(%w{ package spec/fixtures/Weakly.podspec })
76
+ command.run
77
+
78
+ `otool -l Weakly-*/ios/Weakly.framework/Weakly`.should.not.match /AssetsLibrary/
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,410 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Pod
4
+
5
+ DONT_CODESIGN = true
6
+
7
+ describe Command::Spec::Package do
8
+ describe 'CLAide' do
9
+ after do
10
+ Dir.glob("Archs-*").each { |dir| Pathname.new(dir).rmtree }
11
+ Dir.glob("CPDColors-*").each { |dir| Pathname.new(dir).rmtree }
12
+ Dir.glob("KFData-*").each { |dir| Pathname.new(dir).rmtree }
13
+ Dir.glob("NikeKit-*").each { |dir| Pathname.new(dir).rmtree }
14
+ Dir.glob("LocalNikeKit-*").each { |dir| Pathname.new(dir).rmtree }
15
+ Dir.glob("foo-bar-*").each { |dir| Pathname.new(dir).rmtree }
16
+ Dir.glob("a-*").each { |dir| Pathname.new(dir).rmtree }
17
+ Dir.glob("FH-*").each { |dir| Pathname.new(dir).rmtree }
18
+ Dir.glob("FirebaseAnalytics-*").each { |dir| Pathname.new(dir).rmtree }
19
+ end
20
+
21
+ it 'registers itself' do
22
+ Command.parse(%w{ package }).should.be.instance_of Command::Package
23
+ end
24
+
25
+ it 'presents the help if no spec is provided' do
26
+ command = Command.parse(%w{ package })
27
+ should.raise CLAide::Help do
28
+ command.validate!
29
+ end.message.should.match /required/
30
+ end
31
+
32
+ it "errors if it cannot find a spec" do
33
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
34
+
35
+ command = Command.parse(%w{ package KFData })
36
+ should.raise CLAide::Help do
37
+ command.run
38
+ end.message.should.match /Unable to find/
39
+ end
40
+
41
+
42
+ it "should produce a dynamic library when dynamic is specified" do
43
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
44
+
45
+ command = Command.parse(%w{ package spec/fixtures/NikeKit.podspec --dynamic })
46
+ command.run
47
+
48
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
49
+ file_command = "file #{lib}"
50
+ output = `#{file_command}`.lines.to_a
51
+
52
+ output[0].should.match /Mach-O universal binary with 5 architectures/
53
+ output[1].should.match /Mach-O dynamically linked shared library i386/
54
+ end
55
+
56
+ it "should produce a dSYM when dynamic is specified" do
57
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
58
+
59
+ command = Command.parse(%w{ package spec/fixtures/NikeKit.podspec --dynamic })
60
+ command.run
61
+
62
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework.dSYM/Contents/Resources/DWARF/NikeKit").first
63
+ file_command = "file #{lib}"
64
+ output = `#{file_command}`.lines.to_a
65
+
66
+ output[0].should.match /Mach-O universal binary with 3 architectures/
67
+ output[1].should.match /Mach-O dSYM companion file arm/
68
+ end
69
+
70
+ it "should link category symbols when dynamic is specified" do
71
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
72
+
73
+ command = Command.parse(%w{ package spec/fixtures/NikeKit.podspec --dynamic })
74
+ command.run
75
+
76
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
77
+ file_command = "nm #{lib}"
78
+ output = `#{file_command}`.lines.to_a
79
+
80
+ match = output.detect { |line| line =~ /UIButton\(AFNetworking\)/ }
81
+ match.should.not.be.empty
82
+ end
83
+
84
+ it "should produce a dynamic library for OSX when dynamic is specified" do
85
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
86
+
87
+ command = Command.parse(%w{ package spec/fixtures/KFData.podspec --dynamic })
88
+ command.run
89
+
90
+ lib = Dir.glob("KFData-*/osx/KFData.framework/KFData").first
91
+ file_command = "file #{lib}"
92
+ output = `#{file_command}`.lines.to_a
93
+
94
+ output[0].should.match /Mach-O 64-bit dynamically linked shared library x86_64/
95
+ end
96
+
97
+ it "should produce a dSYM for OSX when dynamic is specified" do
98
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
99
+
100
+ command = Command.parse(%w{ package spec/fixtures/KFData.podspec --dynamic })
101
+ command.run
102
+
103
+ lib = Dir.glob("KFData-*/osx/KFData.framework.dSYM/Contents/Resources/DWARF/KFData").first
104
+ file_command = "file #{lib}"
105
+ output = `#{file_command}`.lines.to_a
106
+
107
+ output[0].should.match /Mach-O 64-bit dSYM companion file x86_64/
108
+ end
109
+
110
+ it "should produce the default plist for iOS and OSX when --dynamic is specified but --bundle-identifier is not" do
111
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
112
+
113
+ command = Command.parse(%w{ package spec/fixtures/KFData.podspec --dynamic})
114
+ command.run
115
+
116
+ ios_plist = File.expand_path(Dir.glob("KFData-*/ios/KFData.framework/Info.plist").first)
117
+ osx_plist = File.expand_path(Dir.glob("KFData-*/osx/KFData.framework/Resources/Info.plist").first)
118
+
119
+ ios_bundle_id = `defaults read #{ios_plist} CFBundleIdentifier`
120
+ osx_bundle_id = `defaults read #{osx_plist} CFBundleIdentifier`
121
+
122
+ ios_bundle_id.should.match /org.cocoapods.KFData/
123
+ osx_bundle_id.should.match /org.cocoapods.KFData/
124
+ end
125
+
126
+ it "should produce the correct plist for iOS and OSX when --dynamic and --bundle-identifier are specified" do
127
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
128
+
129
+ command = Command.parse(%w{ package spec/fixtures/KFData.podspec --dynamic --bundle-identifier=com.example.KFData})
130
+ command.run
131
+
132
+ ios_plist = File.expand_path(Dir.glob("KFData-*/ios/KFData.framework/Info.plist").first)
133
+ osx_plist = File.expand_path(Dir.glob("KFData-*/osx/KFData.framework/Resources/Info.plist").first)
134
+
135
+ ios_bundle_id = `defaults read #{ios_plist} CFBundleIdentifier`
136
+ osx_bundle_id = `defaults read #{osx_plist} CFBundleIdentifier`
137
+
138
+ ios_bundle_id.should.match /com.example.KFData/
139
+ osx_bundle_id.should.match /com.example.KFData/
140
+ end
141
+
142
+ it "should produce a static library when dynamic is not specified" do
143
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
144
+
145
+ command = Command.parse(%w{ package spec/fixtures/NikeKit.podspec })
146
+ command.run
147
+
148
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
149
+ file_command = "file #{lib}"
150
+ output = `#{file_command}`.lines.to_a
151
+
152
+ output[0].should.match /Mach-O universal binary with 5 architectures/
153
+ output[1].should.match /current ar archive/
154
+ end
155
+
156
+ it "produces package using local sources when --local is specified" do
157
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
158
+
159
+ command = Command.parse(%w{ package spec/fixtures/LocalSources/LocalNikeKit.podspec --local})
160
+ command.run
161
+
162
+ lib = Dir.glob("LocalNikeKit-*/ios/LocalNikeKit.framework/LocalNikeKit").first
163
+ symbols = Symbols.symbols_from_library(lib)
164
+ symbols.should.include('LocalNikeKit')
165
+ symbols.should.not.include('BBUNikePlusActivity')
166
+ end
167
+
168
+ it "includes vendor symbols both from itself and pod dependencies" do
169
+ command = Command.parse(%w{ package FirebaseAnalytics --no-mangle })
170
+ command.run
171
+
172
+ lib = Dir.glob("FirebaseAnalytics-*/ios/FirebaseAnalytics.framework/FirebaseAnalytics").first
173
+ symbols = Symbols.symbols_from_library(lib)
174
+ # from itself
175
+ symbols.should.include('FIRAnalytics')
176
+ # from pod dependency
177
+ symbols.should.include('FIRApp')
178
+ end
179
+
180
+ it "does not include vendor symbols from pod dependencies if option --exclude-deps is specified" do
181
+ command = Command.parse(%w{ package FirebaseAnalytics --no-mangle --exclude-deps})
182
+ command.run
183
+
184
+ lib = Dir.glob("FirebaseAnalytics-*/ios/FirebaseAnalytics.framework/FirebaseAnalytics").first
185
+ symbols = Symbols.symbols_from_library(lib)
186
+ # from itself
187
+ symbols.should.include('FIRAnalytics')
188
+ # from pod dependency
189
+ symbols.should.not.include('FIRApp')
190
+ end
191
+
192
+ it "includes only available architectures when packaging an iOS Pod with binary dependencies" do
193
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
194
+
195
+ command = Command.parse(%w{ package spec/fixtures/Archs.podspec --no-mangle })
196
+ command.run
197
+
198
+ lib = Dir.glob("Archs-*/ios/Archs.framework/Archs").first
199
+ `lipo #{lib} -verify_arch x86_64 i386 armv7 arm64`
200
+ $?.success?.should == true
201
+ end
202
+
203
+ it "mangles symbols if the Pod has dependencies" do
204
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
205
+
206
+ command = Command.parse(%w{ package spec/fixtures/NikeKit.podspec })
207
+ command.run
208
+
209
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
210
+ symbols = Symbols.symbols_from_library(lib).uniq.sort.reject { |e| e =~ /PodNikeKit/ }
211
+
212
+ symbols.should == %w{ BBUNikePlusActivity BBUNikePlusSessionManager
213
+ BBUNikePlusTag }
214
+ end
215
+
216
+ it "mangles symbols if the Pod has dependencies and framework is dynamic" do
217
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
218
+
219
+ command = Command.parse(%w{ package spec/fixtures/NikeKit.podspec --dynamic })
220
+ command.run
221
+
222
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
223
+ symbols = Symbols.symbols_from_library(lib).uniq.sort.reject { |e| e =~ /PodNikeKit/ }
224
+
225
+ symbols.should == %w{ BBUNikePlusActivity BBUNikePlusSessionManager
226
+ BBUNikePlusTag NikeKitVersionNumber NikeKitVersionString }
227
+ end
228
+
229
+ it "mangles symbols if the Pod has dependencies regardless of name" do
230
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
231
+
232
+ command = Command.parse(%w{ package spec/fixtures/a.podspec })
233
+ command.run
234
+
235
+ lib = Dir.glob("a-*/ios/a.framework/a").first
236
+ symbols = Symbols.symbols_from_library(lib).uniq.sort.reject { |e| e =~ /Poda/ }
237
+ symbols.should == %w{ BBUNikePlusActivity BBUNikePlusSessionManager
238
+ BBUNikePlusTag }
239
+ end
240
+
241
+ it "does not mangle symbols if option --no-mangle is specified" do
242
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
243
+
244
+ command = Command.parse(%w{ package spec/fixtures/NikeKit.podspec --no-mangle })
245
+ command.run
246
+
247
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
248
+ symbols = Symbols.symbols_from_library(lib).uniq.sort.select { |e| e =~ /PodNikeKit/ }
249
+ symbols.should == []
250
+ end
251
+
252
+ it "does not mangle symbols if option --no-mangle and --dynamic are specified" do
253
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
254
+
255
+ command = Command.parse(%w{ package spec/fixtures/NikeKit.podspec --no-mangle --dynamic })
256
+ command.run
257
+
258
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
259
+ symbols = Symbols.symbols_from_library(lib).uniq.sort.select { |e| e =~ /PodNikeKit/ }
260
+ symbols.should == []
261
+ end
262
+
263
+ it "does not include symbols from dependencies if option --exclude-deps is specified" do
264
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
265
+
266
+ command = Command.parse(%w{ package spec/fixtures/NikeKit.podspec --exclude-deps })
267
+ command.run
268
+
269
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
270
+ symbols = Symbols.symbols_from_library(lib).uniq.sort.select { |e| e =~ /AFNetworking|ISO8601DateFormatter|KZPropertyMapper/ }
271
+ symbols.should == []
272
+ end
273
+
274
+ it "includes the correct architectures when packaging an iOS Pod" do
275
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
276
+
277
+ command = Command.parse(%w{ package spec/fixtures/NikeKit.podspec })
278
+ command.run
279
+
280
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
281
+ `lipo #{lib} -verify_arch x86_64 i386 armv7 armv7s arm64`
282
+ $?.success?.should == true
283
+ end
284
+
285
+ it "includes the correct architectures when packaging an iOS Pod as --dynamic" do
286
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
287
+
288
+ command = Command.parse(%w{ package spec/fixtures/NikeKit.podspec --dynamic })
289
+ command.run
290
+
291
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
292
+ `lipo #{lib} -verify_arch armv7 armv7s arm64`
293
+ $?.success?.should == true
294
+ end
295
+
296
+ it "includes Bitcode for device arch slices when packaging an iOS Pod" do
297
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
298
+
299
+ command = Command.parse(%w{ package spec/fixtures/NikeKit.podspec })
300
+ command.run
301
+
302
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
303
+
304
+ #Check for __LLVM segment in each device architecture
305
+ `lipo -extract armv7 #{lib} -o armv7.a && otool -l armv7.a`.should.match /__LLVM/
306
+ `lipo -extract armv7s #{lib} -o armv7s.a && otool -l armv7s.a`.should.match /__LLVM/
307
+ `lipo -extract arm64 #{lib} -o arm64.a && otool -l arm64.a`.should.match /__LLVM/
308
+ `rm armv7.a armv7s.a arm64.a`
309
+ end
310
+
311
+ it "includes Bitcode for device arch slices when packaging an dynamic iOS Pod" do
312
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
313
+
314
+ command = Command.parse(%w{ package spec/fixtures/NikeKit.podspec --dynamic })
315
+ command.run
316
+
317
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
318
+
319
+ #Check for __LLVM segment in each device architecture
320
+ `lipo -extract armv7 #{lib} -o armv7.a && otool -l armv7.a`.should.match /__LLVM/
321
+ `lipo -extract armv7s #{lib} -o armv7s.a && otool -l armv7s.a`.should.match /__LLVM/
322
+ `lipo -extract arm64 #{lib} -o arm64.a && otool -l arm64.a`.should.match /__LLVM/
323
+ `rm armv7.a armv7s.a arm64.a`
324
+ end
325
+
326
+ it "does not include Bitcode for simulator arch slices when packaging an iOS Pod" do
327
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
328
+
329
+ command = Command.parse(%w{ package spec/fixtures/NikeKit.podspec })
330
+ command.run
331
+
332
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
333
+
334
+ #Check for __LLVM segment in each simulator architecture
335
+ `lipo -extract i386 #{lib} -o i386.a && otool -l i386.a`.should.not.match /__LLVM/
336
+ `lipo -extract x86_64 #{lib} -o x86_64.a && otool -l x86_64.a`.should.not.match /__LLVM/
337
+ `rm i386.a x86_64.a`
338
+ end
339
+
340
+ it "does not include Bitcode for simulator arch slices when packaging an dynamic iOS Pod" do
341
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
342
+
343
+ command = Command.parse(%w{ package spec/fixtures/NikeKit.podspec --dynamic })
344
+ command.run
345
+
346
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
347
+
348
+ #Check for __LLVM segment in each simulator architecture
349
+ `lipo -extract i386 #{lib} -o i386.a && otool -l i386.a`.should.not.match /__LLVM/
350
+ `lipo -extract x86_64 #{lib} -o x86_64.a && otool -l x86_64.a`.should.not.match /__LLVM/
351
+ `rm i386.a x86_64.a`
352
+ end
353
+
354
+ it "does not include local ModuleCache references" do
355
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
356
+
357
+ command = Command.parse(%w{ package spec/fixtures/NikeKit.podspec })
358
+ command.run
359
+
360
+ lib = Dir.glob("NikeKit-*/ios/NikeKit.framework/NikeKit").first
361
+
362
+ #Check for ModuleCache references
363
+ `strings #{lib}`.should.not.match /ModuleCache/
364
+ end
365
+
366
+ it "does not fail when the pod name contains a dash" do
367
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
368
+
369
+ command = Command.parse(%w{ package spec/fixtures/foo-bar.podspec })
370
+ command.run
371
+
372
+ true.should == true # To make the test pass without any shoulds
373
+ end
374
+
375
+ it "runs with a path to a spec" do
376
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
377
+
378
+ command = Command.parse(%w{ package spec/fixtures/KFData.podspec })
379
+ command.run
380
+
381
+ true.should == true # To make the test pass without any shoulds
382
+ end
383
+
384
+ it "it respects module_map directive" do
385
+ Pod::Config.instance.sources_manager.stubs(:search).returns(nil)
386
+
387
+ command = Command.parse(%w{ package spec/fixtures/FH.podspec })
388
+ command.run
389
+
390
+ modulemap_contents = File.read(Dir.glob("FH-*/ios/FH.framework/Modules/module.modulemap").first)
391
+ module_map = <<MAP
392
+ framework module FH {
393
+ umbrella header "FeedHenry.h"
394
+
395
+ export *
396
+ module * { export * }
397
+ }
398
+ MAP
399
+ modulemap_contents.should == module_map
400
+ end
401
+
402
+ it "runs with a spec in the master repository" do
403
+ command = Command.parse(%w{ package KFData })
404
+ command.run
405
+
406
+ true.should == true # To make the test pass without any shoulds
407
+ end
408
+ end
409
+ end
410
+ end