cocoapods 0.35.0 → 0.36.0.beta.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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +185 -6
  3. data/README.md +1 -1
  4. data/lib/cocoapods.rb +4 -0
  5. data/lib/cocoapods/command.rb +2 -2
  6. data/lib/cocoapods/command/inter_process_communication.rb +1 -1
  7. data/lib/cocoapods/command/lib.rb +3 -0
  8. data/lib/cocoapods/command/list.rb +0 -35
  9. data/lib/cocoapods/command/search.rb +1 -2
  10. data/lib/cocoapods/command/spec.rb +6 -3
  11. data/lib/cocoapods/config.rb +1 -20
  12. data/lib/cocoapods/external_sources/abstract_external_source.rb +4 -0
  13. data/lib/cocoapods/gem_version.rb +1 -1
  14. data/lib/cocoapods/generator/embed_frameworks_script.rb +107 -0
  15. data/lib/cocoapods/generator/header.rb +13 -1
  16. data/lib/cocoapods/generator/info_plist_file.rb +84 -0
  17. data/lib/cocoapods/generator/module_map.rb +49 -0
  18. data/lib/cocoapods/generator/umbrella_header.rb +44 -0
  19. data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +69 -23
  20. data/lib/cocoapods/generator/xcconfig/private_pod_xcconfig.rb +12 -0
  21. data/lib/cocoapods/generator/xcconfig/public_pod_xcconfig.rb +1 -9
  22. data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +79 -1
  23. data/lib/cocoapods/hooks_manager.rb +75 -13
  24. data/lib/cocoapods/installer.rb +59 -2
  25. data/lib/cocoapods/installer/analyzer.rb +115 -38
  26. data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +6 -1
  27. data/lib/cocoapods/installer/file_references_installer.rb +11 -5
  28. data/lib/cocoapods/installer/migrator.rb +9 -0
  29. data/lib/cocoapods/installer/target_installer.rb +89 -5
  30. data/lib/cocoapods/installer/target_installer/aggregate_target_installer.rb +49 -5
  31. data/lib/cocoapods/installer/target_installer/pod_target_installer.rb +57 -9
  32. data/lib/cocoapods/installer/user_project_integrator.rb +3 -2
  33. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +67 -6
  34. data/lib/cocoapods/project.rb +18 -2
  35. data/lib/cocoapods/resolver.rb +2 -2
  36. data/lib/cocoapods/sandbox/file_accessor.rb +23 -3
  37. data/lib/cocoapods/sandbox/headers_store.rb +4 -0
  38. data/lib/cocoapods/sources_manager.rb +5 -1
  39. data/lib/cocoapods/target.rb +117 -1
  40. data/lib/cocoapods/target/aggregate_target.rb +46 -4
  41. data/lib/cocoapods/target/pod_target.rb +39 -1
  42. data/lib/cocoapods/user_interface.rb +16 -21
  43. data/lib/cocoapods/user_interface/error_report.rb +2 -2
  44. data/lib/cocoapods/validator.rb +68 -23
  45. metadata +23 -19
@@ -0,0 +1,49 @@
1
+ module Pod
2
+ module Generator
3
+ # Generates LLVM module map files. A module map file is generated for each
4
+ # Pod and for each Pod target definition that is built as a framework. It
5
+ # specifies a different umbrella header than usual to avoid name conflicts
6
+ # with existing headers of the podspec.
7
+ #
8
+ class ModuleMap
9
+ # @return [Target] the target represented by this Info.plist.
10
+ #
11
+ attr_reader :target
12
+
13
+ # @param [Target] target @see target
14
+ #
15
+ def initialize(target)
16
+ @target = target
17
+ end
18
+
19
+ # Generates and saves the Info.plist to the given path.
20
+ #
21
+ # @param [Pathname] path
22
+ # the path where the prefix header should be stored.
23
+ #
24
+ # @return [void]
25
+ #
26
+ def save_as(path)
27
+ contents = generate
28
+ path.open('w') do |f|
29
+ f.write(contents)
30
+ end
31
+ end
32
+
33
+ # Generates the contents of the module.modulemap file.
34
+ #
35
+ # @return [String]
36
+ #
37
+ def generate
38
+ <<-eos.strip_heredoc
39
+ framework module #{target.product_module_name} {
40
+ umbrella header "#{target.umbrella_header_path.basename}"
41
+
42
+ export *
43
+ module * { export * }
44
+ }
45
+ eos
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,44 @@
1
+ module Pod
2
+ module Generator
3
+ # Generates an umbrella header file for clang modules, which are used by
4
+ # dynamic frameworks on iOS 8 and OSX 10.10 under the hood.
5
+ #
6
+ # If the target is a +PodTarget+, then the umbrella header is required
7
+ # to make all public headers in a convenient manner available without the
8
+ # need to write out header declarations for every library header.
9
+ #
10
+ class UmbrellaHeader < Header
11
+ # @return [Target]
12
+ # the target, which provides the product name
13
+ attr_reader :target
14
+
15
+ # @param [Target] target
16
+ # @see target
17
+ #
18
+ def initialize(target)
19
+ super(target.target_definition.platform)
20
+ @target = target
21
+ end
22
+
23
+ # Generates the contents of the umbrella header according to the included
24
+ # pods.
25
+ #
26
+ # @return [String]
27
+ #
28
+ def generate
29
+ result = super
30
+
31
+ result << "\n"
32
+
33
+ result << <<-eos.strip_heredoc
34
+ FOUNDATION_EXPORT double #{target.product_module_name}VersionNumber;
35
+ FOUNDATION_EXPORT const unsigned char #{target.product_module_name}VersionString[];
36
+ eos
37
+
38
+ result << "\n"
39
+
40
+ result
41
+ end
42
+ end
43
+ end
44
+ end
@@ -47,33 +47,58 @@ module Pod
47
47
  # @return [Xcodeproj::Config]
48
48
  #
49
49
  def generate
50
- header_search_path_flags = target.sandbox.public_headers.search_paths(target.platform)
51
- @xcconfig = Xcodeproj::Config.new(
52
- 'OTHER_LDFLAGS' => XCConfigHelper.default_ld_flags(target),
53
- 'OTHER_LIBTOOLFLAGS' => '$(OTHER_LDFLAGS)',
54
- 'HEADER_SEARCH_PATHS' => XCConfigHelper.quote(header_search_path_flags),
55
- 'PODS_ROOT' => target.relative_pods_root,
56
- 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) COCOAPODS=1',
57
- 'OTHER_CFLAGS' => '$(inherited) ' + XCConfigHelper.quote(header_search_path_flags, '-isystem')
58
- )
50
+ pod_targets = target.pod_targets_for_build_configuration(@configuration_name)
51
+ config = {
52
+ 'OTHER_LDFLAGS' => XCConfigHelper.default_ld_flags(target),
53
+ 'OTHER_LIBTOOLFLAGS' => '$(OTHER_LDFLAGS)',
54
+ 'PODS_ROOT' => target.relative_pods_root,
55
+ 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) COCOAPODS=1',
56
+ }
59
57
 
60
- target.pod_targets.each do |pod_target|
61
- next unless pod_target.include_in_build_config?(@configuration_name)
58
+ if target.requires_frameworks?
59
+ # Framework headers are automatically discoverable by `#import <…>`.
60
+ header_search_paths = pod_targets.map { |target| "$PODS_FRAMEWORK_BUILD_PATH/#{target.product_name}/Headers" }
61
+ build_settings = {
62
+ 'PODS_FRAMEWORK_BUILD_PATH' => target.configuration_build_dir,
63
+ 'FRAMEWORK_SEARCH_PATHS' => '"$PODS_FRAMEWORK_BUILD_PATH"',
64
+ # Make headers discoverable by `import "…"`
65
+ 'OTHER_CFLAGS' => '$(inherited) ' + XCConfigHelper.quote(header_search_paths, '-iquote')
66
+ }
67
+ config.merge!(build_settings)
68
+ else
69
+ # Make headers discoverable from $PODS_ROOT/Headers directory
70
+ header_search_paths = target.sandbox.public_headers.search_paths(target.platform)
71
+ build_settings = {
72
+ # by `#import "…"`
73
+ 'HEADER_SEARCH_PATHS' => XCConfigHelper.quote(header_search_paths),
74
+ # by `#import <…>`
75
+ 'OTHER_CFLAGS' => '$(inherited) ' + XCConfigHelper.quote(header_search_paths, '-isystem')
76
+ }
77
+ config.merge!(build_settings)
78
+ end
62
79
 
63
- pod_target.file_accessors.each do |file_accessor|
64
- XCConfigHelper.add_spec_build_settings_to_xcconfig(file_accessor.spec_consumer, @xcconfig)
65
- file_accessor.vendored_frameworks.each do |vendored_framework|
66
- XCConfigHelper.add_framework_build_settings(vendored_framework, @xcconfig, target.sandbox.root)
67
- end
68
- file_accessor.vendored_libraries.each do |vendored_library|
69
- XCConfigHelper.add_library_build_settings(vendored_library, @xcconfig, target.sandbox.root)
70
- end
71
- end
80
+ @xcconfig = Xcodeproj::Config.new(config)
72
81
 
73
- # Add pod static lib to list of libraries that are to be linked with
74
- # the user’s project.
82
+ XCConfigHelper.add_target_specific_settings(target, @xcconfig)
75
83
 
76
- @xcconfig.merge!('OTHER_LDFLAGS' => %(-l "#{pod_target.name}"))
84
+ pod_targets.each do |pod_target|
85
+ unless pod_target.should_build? && pod_target.requires_frameworks?
86
+ # In case of generated pod targets, which require frameworks, the
87
+ # vendored frameworks and libraries are already linked statically
88
+ # into the framework binary and must not be linked again to the
89
+ # user target.
90
+ XCConfigHelper.add_settings_for_file_accessors_of_target(pod_target, @xcconfig)
91
+ end
92
+
93
+ # Add pod target to list of frameworks / libraries that are
94
+ # linked with the user’s project.
95
+ if pod_target.should_build?
96
+ if pod_target.requires_frameworks?
97
+ @xcconfig.merge!('OTHER_LDFLAGS' => %(-framework "#{pod_target.product_basename}"))
98
+ else
99
+ @xcconfig.merge!('OTHER_LDFLAGS' => %(-l "#{pod_target.product_basename}"))
100
+ end
101
+ end
77
102
  end
78
103
 
79
104
  # TODO Need to decide how we are going to ensure settings like these
@@ -82,9 +107,30 @@ module Pod
82
107
  # See https://github.com/CocoaPods/CocoaPods/issues/1216
83
108
  @xcconfig.attributes.delete('USE_HEADERMAP')
84
109
 
110
+ generate_ld_runpath_search_paths if target.requires_frameworks?
111
+
85
112
  @xcconfig
86
113
  end
87
114
 
115
+ def generate_ld_runpath_search_paths
116
+ ld_runpath_search_paths = ['$(inherited)']
117
+ if target.platform.symbolic_name == :osx
118
+ ld_runpath_search_paths << "'@executable_path/../Frameworks'"
119
+ ld_runpath_search_paths << \
120
+ if target.native_target.symbol_type == :unit_test_bundle
121
+ "'@loader_path/../Frameworks'"
122
+ else
123
+ "'@loader_path/Frameworks'"
124
+ end
125
+ else
126
+ ld_runpath_search_paths << [
127
+ "'@executable_path/Frameworks'",
128
+ "'@loader_path/Frameworks'"
129
+ ]
130
+ end
131
+ @xcconfig.merge!('LD_RUNPATH_SEARCH_PATHS' => ld_runpath_search_paths.join(' '))
132
+ end
133
+
88
134
  #---------------------------------------------------------------------#
89
135
  end
90
136
  end
@@ -57,8 +57,20 @@ module Pod
57
57
  # 'USE_HEADERMAP' => 'NO'
58
58
  }
59
59
 
60
+ if target.requires_frameworks?
61
+ # Only quote the FRAMEWORK_SEARCH_PATHS entry, because it’s a setting that takes multiple values.
62
+ # In addition, quoting CONFIGURATION_BUILD_DIR would make it be interpreted as a relative path.
63
+ build_settings = {
64
+ 'PODS_FRAMEWORK_BUILD_PATH' => target.configuration_build_dir,
65
+ 'CONFIGURATION_BUILD_DIR' => '$PODS_FRAMEWORK_BUILD_PATH',
66
+ 'FRAMEWORK_SEARCH_PATHS' => '"$PODS_FRAMEWORK_BUILD_PATH"',
67
+ }
68
+ config.merge!(build_settings)
69
+ end
70
+
60
71
  xcconfig_hash = add_xcconfig_namespaced_keys(public_xcconfig.to_hash, config, target.xcconfig_prefix)
61
72
  @xcconfig = Xcodeproj::Config.new(xcconfig_hash)
73
+ XCConfigHelper.add_target_specific_settings(target, @xcconfig)
62
74
  @xcconfig.includes = [target.name]
63
75
  @xcconfig
64
76
  end
@@ -40,15 +40,7 @@ module Pod
40
40
  #
41
41
  def generate
42
42
  @xcconfig = Xcodeproj::Config.new
43
- target.file_accessors.each do |file_accessor|
44
- XCConfigHelper.add_spec_build_settings_to_xcconfig(file_accessor.spec_consumer, @xcconfig)
45
- file_accessor.vendored_frameworks.each do |vendored_framework|
46
- XCConfigHelper.add_framework_build_settings(vendored_framework, @xcconfig, target.sandbox.root)
47
- end
48
- file_accessor.vendored_libraries.each do |vendored_library|
49
- XCConfigHelper.add_library_build_settings(vendored_library, @xcconfig, target.sandbox.root)
50
- end
51
- end
43
+ XCConfigHelper.add_settings_for_file_accessors_of_target(target, @xcconfig)
52
44
  @xcconfig
53
45
  end
54
46
 
@@ -33,6 +33,26 @@ module Pod
33
33
  ld_flags
34
34
  end
35
35
 
36
+ # Configures the given Xcconfig
37
+ #
38
+ # @param [PodTarget] pod_target
39
+ # The pod target, which holds the list of +Spec::FileAccessor+.
40
+ #
41
+ # @param [Xcodeproj::Config] xcconfig
42
+ # The xcconfig to edit.
43
+ #
44
+ def self.add_settings_for_file_accessors_of_target(target, xcconfig)
45
+ target.file_accessors.each do |file_accessor|
46
+ XCConfigHelper.add_spec_build_settings_to_xcconfig(file_accessor.spec_consumer, xcconfig)
47
+ file_accessor.vendored_frameworks.each do |vendored_framework|
48
+ XCConfigHelper.add_framework_build_settings(vendored_framework, xcconfig, target.sandbox.root)
49
+ end
50
+ file_accessor.vendored_libraries.each do |vendored_library|
51
+ XCConfigHelper.add_library_build_settings(vendored_library, xcconfig, target.sandbox.root)
52
+ end
53
+ end
54
+ end
55
+
36
56
  # Configures the given Xcconfig according to the build settings of the
37
57
  # given Specification.
38
58
  #
@@ -59,6 +79,9 @@ module Pod
59
79
  # @param [Xcodeproj::Config] xcconfig
60
80
  # The xcconfig to edit.
61
81
  #
82
+ # @param [Pathname] sandbox_root
83
+ # The path retrieved from Sandbox#root.
84
+ #
62
85
  def self.add_framework_build_settings(framework_path, xcconfig, sandbox_root)
63
86
  name = File.basename(framework_path, '.framework')
64
87
  dirname = '$(PODS_ROOT)/' + framework_path.dirname.relative_path_from(sandbox_root).to_s
@@ -70,7 +93,7 @@ module Pod
70
93
  end
71
94
 
72
95
  # Configures the given Xcconfig with the the build settings for the given
73
- # framework path.
96
+ # library path.
74
97
  #
75
98
  # @param [Pathanme] framework_path
76
99
  # The path of the framework.
@@ -78,6 +101,9 @@ module Pod
78
101
  # @param [Xcodeproj::Config] xcconfig
79
102
  # The xcconfig to edit.
80
103
  #
104
+ # @param [Pathname] sandbox_root
105
+ # The path retrieved from Sandbox#root.
106
+ #
81
107
  def self.add_library_build_settings(library_path, xcconfig, sandbox_root)
82
108
  name = File.basename(library_path, '.a').sub(/\Alib/, '')
83
109
  dirname = '$(PODS_ROOT)/' + library_path.dirname.relative_path_from(sandbox_root).to_s
@@ -88,6 +114,58 @@ module Pod
88
114
  xcconfig.merge!(build_settings)
89
115
  end
90
116
 
117
+ # Add the code signing settings for generated targets to ensure that
118
+ # frameworks are correctly signed to be integrated and re-signed when
119
+ # building the application and embedding the framework
120
+ #
121
+ # @param [Target] target
122
+ # The target.
123
+ #
124
+ # @param [Xcodeproj::Config] xcconfig
125
+ # The xcconfig to edit.
126
+ #
127
+ def self.add_code_signing_settings(target, xcconfig)
128
+ build_settings = {}
129
+ if target.platform.to_sym == :osx
130
+ build_settings['CODE_SIGN_IDENTITY'] = ''
131
+ end
132
+ xcconfig.merge!(build_settings)
133
+ end
134
+
135
+ # Checks if the given target requires specific settings and configures
136
+ # the given Xcconfig.
137
+ #
138
+ # @param [Target] target
139
+ # The target.
140
+ #
141
+ # @param [Xcodeproj::Config] xcconfig
142
+ # The xcconfig to edit.
143
+ #
144
+ def self.add_target_specific_settings(target, xcconfig)
145
+ if target.requires_frameworks?
146
+ add_code_signing_settings(target, xcconfig)
147
+ end
148
+ add_language_specific_settings(target, xcconfig)
149
+ end
150
+
151
+ # Checks if the given target requires language specific settings and
152
+ # configures the given Xcconfig.
153
+ #
154
+ # @param [Target] target
155
+ # The target.
156
+ #
157
+ # @param [Xcodeproj::Config] xcconfig
158
+ # The xcconfig to edit.
159
+ #
160
+ def self.add_language_specific_settings(target, xcconfig)
161
+ if target.uses_swift?
162
+ build_settings = {
163
+ 'OTHER_SWIFT_FLAGS' => quote(['-D COCOAPODS']),
164
+ }
165
+ xcconfig.merge!(build_settings)
166
+ end
167
+ end
168
+
91
169
  # Adds the search paths of the developer frameworks to the specification
92
170
  # if needed. This is done because the `SenTestingKit` requires them and
93
171
  # adding them to each specification which requires it is repetitive and
@@ -1,3 +1,5 @@
1
+ require 'rubygems'
2
+
1
3
  module Pod
2
4
  # Provides support for the hook system of CocoaPods. The system is designed
3
5
  # especially for plugins. Interested clients can register to notifications by
@@ -14,27 +16,70 @@ module Pod
14
16
  # from CocoaPods 1.0).
15
17
  #
16
18
  module HooksManager
19
+ # Represents a single registered hook.
20
+ #
21
+ class Hook
22
+ # @return [String]
23
+ # The name of the hook's notification.
24
+ #
25
+ attr_reader :plugin_name
26
+
27
+ # @return [String]
28
+ # The name of the plugin the hook came from.
29
+ #
30
+ attr_reader :name
31
+
32
+ # @return [Proc]
33
+ # The block.
34
+ #
35
+ attr_reader :block
36
+
37
+ # @param [String] name @see {#name}.
38
+ #
39
+ # @param [String] plugin_name @see {#plugin_name}.
40
+ #
41
+ # @param [Proc] block @see {#block}.
42
+ #
43
+ def initialize(name, plugin_name, block)
44
+ raise ArgumentError, 'Missing name' unless name
45
+ raise ArgumentError, 'Missing block' unless block
46
+
47
+ UI.warn '[Hooks] The use of hooks without specifying a `plugin_name` ' \
48
+ 'has been deprecated.' unless plugin_name
49
+
50
+ @name = name
51
+ @plugin_name = plugin_name
52
+ @block = block
53
+ end
54
+ end
55
+
17
56
  class << self
18
- # @return [Hash{Symbol => Proc}] The list of the blocks that are
57
+ # @return [Hash{Symbol => Array<Proc>}] The list of the blocks that are
19
58
  # registered for each notification name.
20
59
  #
21
60
  attr_reader :registrations
22
61
 
23
62
  # Registers a block for the hook with the given name.
24
63
  #
25
- # @param [Symbol] name
64
+ # @param [String] plugin_name
65
+ # The name of the plugin the hook comes from.
66
+ #
67
+ # @param [Symbol] hook_name
26
68
  # The name of the notification.
27
69
  #
28
70
  # @param [Proc] block
29
71
  # The block.
30
72
  #
31
- def register(name, &block)
32
- raise ArgumentError, 'Missing name' unless name
33
- raise ArgumentError, 'Missing block' unless block
73
+ def register(plugin_name, hook_name = nil, &block)
74
+ # TODO: Backwards compatibility with nameless plugins from CP 0.34
75
+ if hook_name.nil?
76
+ hook_name = plugin_name
77
+ plugin_name = nil
78
+ end
34
79
 
35
80
  @registrations ||= {}
36
- @registrations[name] ||= []
37
- @registrations[name] << block
81
+ @registrations[hook_name] ||= []
82
+ @registrations[hook_name] << Hook.new(hook_name, plugin_name, block)
38
83
  end
39
84
 
40
85
  # Runs all the registered blocks for the hook with the given name.
@@ -45,15 +90,32 @@ module Pod
45
90
  # @param [Object] context
46
91
  # The context object which should be passed to the blocks.
47
92
  #
48
- def run(name, context)
93
+ # @param [Hash<String, Hash>] whitelisted_plugins
94
+ # The plugins that should be run, in the form of a hash keyed by
95
+ # plugin name, where the values are the custom options that should
96
+ # be passed to the hook's block if it supports taking a second
97
+ # argument.
98
+ #
99
+ def run(name, context, whitelisted_plugins = nil)
49
100
  raise ArgumentError, 'Missing name' unless name
50
101
  raise ArgumentError, 'Missing options' unless context
51
102
 
52
- if @registrations
53
- blocks = @registrations[name]
54
- if blocks
55
- blocks.each do |block|
56
- block.call(context)
103
+ if registrations
104
+ hooks = registrations[name]
105
+ if hooks
106
+ UI.message "- Running #{name.to_s.gsub('_', ' ')} hooks" do
107
+ hooks.each do |hook|
108
+ next if whitelisted_plugins && !whitelisted_plugins.key?(hook.plugin_name)
109
+ UI.message "- #{hook.plugin_name || 'unknown plugin'} from " \
110
+ "`#{hook.block.source_location.first}`" do
111
+ block = hook.block
112
+ if block.arity > 1
113
+ block.call(context, whitelisted_plugins[hook.plugin_name])
114
+ else
115
+ block.call(context)
116
+ end
117
+ end
118
+ end
57
119
  end
58
120
  end
59
121
  end