cocoapods 1.0.0 → 1.1.0

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +329 -0
  3. data/lib/cocoapods/command/init.rb +6 -6
  4. data/lib/cocoapods/command/ipc/list.rb +40 -0
  5. data/lib/cocoapods/command/ipc/podfile.rb +31 -0
  6. data/lib/cocoapods/command/ipc/repl.rb +51 -0
  7. data/lib/cocoapods/command/ipc/spec.rb +29 -0
  8. data/lib/cocoapods/command/ipc/update_search_index.rb +24 -0
  9. data/lib/cocoapods/command/ipc.rb +18 -0
  10. data/lib/cocoapods/command/lib/create.rb +105 -0
  11. data/lib/cocoapods/command/lib/lint.rb +111 -0
  12. data/lib/cocoapods/command/lib.rb +3 -207
  13. data/lib/cocoapods/command/repo/push.rb +44 -20
  14. data/lib/cocoapods/command/setup.rb +2 -1
  15. data/lib/cocoapods/command/spec/lint.rb +4 -0
  16. data/lib/cocoapods/command.rb +2 -1
  17. data/lib/cocoapods/config.rb +4 -1
  18. data/lib/cocoapods/downloader/cache.rb +1 -0
  19. data/lib/cocoapods/downloader.rb +20 -0
  20. data/lib/cocoapods/executable.rb +1 -1
  21. data/lib/cocoapods/gem_version.rb +1 -1
  22. data/lib/cocoapods/generator/acknowledgements/plist.rb +4 -1
  23. data/lib/cocoapods/generator/copy_resources_script.rb +4 -10
  24. data/lib/cocoapods/generator/header.rb +2 -1
  25. data/lib/cocoapods/generator/prefix_header.rb +0 -12
  26. data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +38 -5
  27. data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +5 -4
  28. data/lib/cocoapods/installer/analyzer/pod_variant_set.rb +5 -1
  29. data/lib/cocoapods/installer/analyzer/target_inspector.rb +24 -1
  30. data/lib/cocoapods/installer/analyzer.rb +161 -1
  31. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +29 -9
  32. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +204 -0
  33. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +314 -0
  34. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +401 -0
  35. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +214 -0
  36. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +265 -0
  37. data/lib/cocoapods/installer/xcode.rb +7 -0
  38. data/lib/cocoapods/installer.rb +50 -214
  39. data/lib/cocoapods/resolver.rb +15 -9
  40. data/lib/cocoapods/sandbox/headers_store.rb +4 -10
  41. data/lib/cocoapods/sandbox/path_list.rb +20 -9
  42. data/lib/cocoapods/sources_manager.rb +7 -10
  43. data/lib/cocoapods/target/aggregate_target.rb +20 -0
  44. data/lib/cocoapods/target/pod_target.rb +37 -7
  45. data/lib/cocoapods/user_interface/error_report.rb +7 -0
  46. data/lib/cocoapods/user_interface/inspector_reporter.rb +109 -0
  47. data/lib/cocoapods/user_interface.rb +7 -5
  48. data/lib/cocoapods/validator.rb +59 -11
  49. metadata +112 -83
  50. data/lib/cocoapods/command/inter_process_communication.rb +0 -177
  51. data/lib/cocoapods/installer/file_references_installer.rb +0 -310
  52. data/lib/cocoapods/installer/migrator.rb +0 -86
  53. data/lib/cocoapods/installer/target_installer/aggregate_target_installer.rb +0 -191
  54. data/lib/cocoapods/installer/target_installer/pod_target_installer.rb +0 -368
  55. data/lib/cocoapods/installer/target_installer.rb +0 -210
@@ -0,0 +1,204 @@
1
+ module Pod
2
+ class Installer
3
+ class Xcode
4
+ class PodsProjectGenerator
5
+ # Creates the targets which aggregate the Pods libraries in the Pods
6
+ # project and the relative support files.
7
+ #
8
+ class AggregateTargetInstaller < TargetInstaller
9
+ # Creates the target in the Pods project and the relative support files.
10
+ #
11
+ # @return [void]
12
+ #
13
+ def install!
14
+ UI.message "- Installing target `#{target.name}` #{target.platform}" do
15
+ add_target
16
+ create_support_files_dir
17
+ create_support_files_group
18
+ create_xcconfig_file
19
+ if target.requires_frameworks?
20
+ create_info_plist_file
21
+ create_module_map
22
+ create_umbrella_header
23
+ end
24
+ # Because embedded targets live in their host target, CocoaPods
25
+ # copies all of the embedded target's pod_targets to its host
26
+ # targets. Having this script for the embedded target would
27
+ # cause an App Store rejection because frameworks cannot be
28
+ # embedded in embedded targets.
29
+ #
30
+ create_embed_frameworks_script unless target.requires_host_target?
31
+ create_bridge_support_file
32
+ create_copy_resources_script
33
+ create_acknowledgements
34
+ create_dummy_source
35
+ end
36
+ end
37
+
38
+ #-----------------------------------------------------------------------#
39
+
40
+ private
41
+
42
+ # @return [TargetDefinition] the target definition of the library.
43
+ #
44
+ def target_definition
45
+ target.target_definition
46
+ end
47
+
48
+ # Ensure that vendored static frameworks and libraries are not linked
49
+ # twice to the aggregate target, which shares the xcconfig of the user
50
+ # target.
51
+ #
52
+ def custom_build_settings
53
+ settings = {
54
+ 'CODE_SIGN_IDENTITY[sdk=appletvos*]' => '',
55
+ 'CODE_SIGN_IDENTITY[sdk=iphoneos*]' => '',
56
+ 'CODE_SIGN_IDENTITY[sdk=watchos*]' => '',
57
+ 'MACH_O_TYPE' => 'staticlib',
58
+ 'OTHER_LDFLAGS' => '',
59
+ 'OTHER_LIBTOOLFLAGS' => '',
60
+ 'PODS_ROOT' => '$(SRCROOT)',
61
+ 'PRODUCT_BUNDLE_IDENTIFIER' => 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}',
62
+ 'SKIP_INSTALL' => 'YES',
63
+ }
64
+ super.merge(settings)
65
+ end
66
+
67
+ # Creates the group that holds the references to the support files
68
+ # generated by this installer.
69
+ #
70
+ # @return [void]
71
+ #
72
+ def create_support_files_group
73
+ parent = project.support_files_group
74
+ name = target.name
75
+ dir = target.support_files_dir
76
+ @support_files_group = parent.new_group(name, dir)
77
+ end
78
+
79
+ # Generates the contents of the xcconfig file and saves it to disk.
80
+ #
81
+ # @return [void]
82
+ #
83
+ def create_xcconfig_file
84
+ native_target.build_configurations.each do |configuration|
85
+ path = target.xcconfig_path(configuration.name)
86
+ gen = Generator::XCConfig::AggregateXCConfig.new(target, configuration.name)
87
+ gen.save_as(path)
88
+ target.xcconfigs[configuration.name] = gen.xcconfig
89
+ xcconfig_file_ref = add_file_to_support_group(path)
90
+ configuration.base_configuration_reference = xcconfig_file_ref
91
+ end
92
+ end
93
+
94
+ # Generates the bridge support metadata if requested by the {Podfile}.
95
+ #
96
+ # @note The bridge support metadata is added to the resources of the
97
+ # target because it is needed for environments interpreted at
98
+ # runtime.
99
+ #
100
+ # @return [void]
101
+ #
102
+ def create_bridge_support_file
103
+ if target.podfile.generate_bridge_support?
104
+ path = target.bridge_support_path
105
+ headers = native_target.headers_build_phase.files.map { |bf| sandbox.root + bf.file_ref.path }
106
+ generator = Generator::BridgeSupport.new(headers)
107
+ generator.save_as(path)
108
+ add_file_to_support_group(path)
109
+ @bridge_support_file = path.relative_path_from(sandbox.root)
110
+ end
111
+ end
112
+
113
+ # Uniqued Resources grouped by config
114
+ #
115
+ # @return [Hash{ Symbol => Array<Pathname> }]
116
+ #
117
+ def resources_by_config
118
+ library_targets = target.pod_targets.reject do |pod_target|
119
+ pod_target.should_build? && pod_target.requires_frameworks?
120
+ end
121
+ target.user_build_configurations.keys.each_with_object({}) do |config, resources_by_config|
122
+ resources_by_config[config] = library_targets.flat_map do |library_target|
123
+ next [] unless library_target.include_in_build_config?(target_definition, config)
124
+ resource_paths = library_target.file_accessors.flat_map do |accessor|
125
+ accessor.resources.flat_map { |res| res.relative_path_from(project.path.dirname) }
126
+ end
127
+ resource_bundles = library_target.file_accessors.flat_map do |accessor|
128
+ accessor.resource_bundles.keys.map { |name| "#{library_target.configuration_build_dir}/#{name.shellescape}.bundle" }
129
+ end
130
+ (resource_paths + resource_bundles + [bridge_support_file].compact).uniq
131
+ end
132
+ end
133
+ end
134
+
135
+ # Creates a script that copies the resources to the bundle of the client
136
+ # target.
137
+ #
138
+ # @note The bridge support file needs to be created before the prefix
139
+ # header, otherwise it will not be added to the resources script.
140
+ #
141
+ # @return [void]
142
+ #
143
+ def create_copy_resources_script
144
+ path = target.copy_resources_script_path
145
+ generator = Generator::CopyResourcesScript.new(resources_by_config, target.platform)
146
+ generator.save_as(path)
147
+ add_file_to_support_group(path)
148
+ end
149
+
150
+ # Creates a script that embeds the frameworks to the bundle of the client
151
+ # target.
152
+ #
153
+ # @note We can't use Xcode default copy bundle resource phase, because
154
+ # we need to ensure that we only copy the resources, which are
155
+ # relevant for the current build configuration.
156
+ #
157
+ # @return [void]
158
+ #
159
+ def create_embed_frameworks_script
160
+ path = target.embed_frameworks_script_path
161
+ frameworks_by_config = {}
162
+ target.user_build_configurations.keys.each do |config|
163
+ relevant_pod_targets = target.pod_targets.select do |pod_target|
164
+ pod_target.include_in_build_config?(target_definition, config)
165
+ end
166
+ frameworks_by_config[config] = relevant_pod_targets.flat_map do |pod_target|
167
+ frameworks = pod_target.file_accessors.flat_map(&:vendored_dynamic_artifacts).map { |fw| "${PODS_ROOT}/#{fw.relative_path_from(sandbox.root)}" }
168
+ frameworks << pod_target.build_product_path('$BUILT_PRODUCTS_DIR') if pod_target.should_build? && pod_target.requires_frameworks?
169
+ frameworks
170
+ end
171
+ end
172
+ generator = Generator::EmbedFrameworksScript.new(frameworks_by_config)
173
+ generator.save_as(path)
174
+ add_file_to_support_group(path)
175
+ end
176
+
177
+ # Generates the acknowledgement files (markdown and plist) for the target.
178
+ #
179
+ # @return [void]
180
+ #
181
+ def create_acknowledgements
182
+ basepath = target.acknowledgements_basepath
183
+ Generator::Acknowledgements.generators.each do |generator_class|
184
+ path = generator_class.path_from_basepath(basepath)
185
+ file_accessors = target.pod_targets.map(&:file_accessors).flatten
186
+ generator = generator_class.new(file_accessors)
187
+ generator.save_as(path)
188
+ add_file_to_support_group(path)
189
+ end
190
+ end
191
+
192
+ # @return [Pathname] the path of the bridge support file relative to the
193
+ # sandbox.
194
+ #
195
+ # @return [Nil] if no bridge support file was generated.
196
+ #
197
+ attr_reader :bridge_support_file
198
+
199
+ #-----------------------------------------------------------------------#
200
+ end
201
+ end
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,314 @@
1
+ module Pod
2
+ class Installer
3
+ class Xcode
4
+ class PodsProjectGenerator
5
+ # Controller class responsible of installing the file references of the
6
+ # specifications in the Pods project.
7
+ #
8
+ class FileReferencesInstaller
9
+ # @return [Sandbox] The sandbox of the installation.
10
+ #
11
+ attr_reader :sandbox
12
+
13
+ # @return [Array<PodTarget>] The pod targets of the installation.
14
+ #
15
+ attr_reader :pod_targets
16
+
17
+ # @return [Project] The Pods project.
18
+ #
19
+ attr_reader :pods_project
20
+
21
+ # Initialize a new instance
22
+ #
23
+ # @param [Sandbox] sandbox @see sandbox
24
+ # @param [Array<PodTarget>] pod_targets @see pod_targets
25
+ # @param [Project] pods_project @see pod_project
26
+ #
27
+ def initialize(sandbox, pod_targets, pods_project)
28
+ @sandbox = sandbox
29
+ @pod_targets = pod_targets
30
+ @pods_project = pods_project
31
+ end
32
+
33
+ # Installs the file references.
34
+ #
35
+ # @return [void]
36
+ #
37
+ def install!
38
+ refresh_file_accessors
39
+ add_source_files_references
40
+ add_frameworks_bundles
41
+ add_vendored_libraries
42
+ add_resources
43
+ link_headers
44
+ end
45
+
46
+ #-----------------------------------------------------------------------#
47
+
48
+ private
49
+
50
+ # @!group Installation Steps
51
+
52
+ # Reads the file accessors contents from the file system.
53
+ #
54
+ # @note The contents of the file accessors are modified by the clean
55
+ # step of the #{PodSourceInstaller} and by the pre install hooks.
56
+ #
57
+ # @return [void]
58
+ #
59
+ def refresh_file_accessors
60
+ file_accessors.each do |fa|
61
+ fa.path_list.read_file_system
62
+ end
63
+ end
64
+
65
+ # Adds the source files of the Pods to the Pods project.
66
+ #
67
+ # @note The source files are grouped by Pod and in turn by subspec
68
+ # (recursively).
69
+ #
70
+ # @return [void]
71
+ #
72
+ def add_source_files_references
73
+ UI.message '- Adding source files to Pods project' do
74
+ add_file_accessors_paths_to_pods_group(:source_files, nil, true)
75
+ end
76
+ end
77
+
78
+ # Adds the bundled frameworks to the Pods project
79
+ #
80
+ # @return [void]
81
+ #
82
+ def add_frameworks_bundles
83
+ UI.message '- Adding frameworks to Pods project' do
84
+ add_file_accessors_paths_to_pods_group(:vendored_frameworks, :frameworks)
85
+ end
86
+ end
87
+
88
+ # Adds the bundled libraries to the Pods project
89
+ #
90
+ # @return [void]
91
+ #
92
+ def add_vendored_libraries
93
+ UI.message '- Adding libraries to Pods project' do
94
+ add_file_accessors_paths_to_pods_group(:vendored_libraries, :frameworks)
95
+ end
96
+ end
97
+
98
+ # Adds the resources of the Pods to the Pods project.
99
+ #
100
+ # @note The source files are grouped by Pod and in turn by subspec
101
+ # (recursively) in the resources group.
102
+ #
103
+ # @return [void]
104
+ #
105
+ def add_resources
106
+ UI.message '- Adding resources to Pods project' do
107
+ add_file_accessors_paths_to_pods_group(:resources, :resources, true)
108
+ add_file_accessors_paths_to_pods_group(:resource_bundle_files, :resources, true)
109
+ end
110
+ end
111
+
112
+ # Creates the link to the headers of the Pod in the sandbox.
113
+ #
114
+ # @return [void]
115
+ #
116
+ def link_headers
117
+ UI.message '- Linking headers' do
118
+ pod_targets.each do |pod_target|
119
+ pod_target.file_accessors.each do |file_accessor|
120
+ framework_exp = /\.framework\//
121
+ headers_sandbox = Pathname.new(file_accessor.spec.root.name)
122
+
123
+ # When integrating Pod as frameworks, built Pods are built into
124
+ # frameworks, whose headers are included inside the built
125
+ # framework. Those headers do not need to be linked from the
126
+ # sandbox.
127
+ unless pod_target.requires_frameworks? && pod_target.should_build?
128
+ pod_target.build_headers.add_search_path(headers_sandbox, pod_target.platform)
129
+ sandbox.public_headers.add_search_path(headers_sandbox, pod_target.platform)
130
+
131
+ header_mappings(headers_sandbox, file_accessor, file_accessor.headers).each do |namespaced_path, files|
132
+ pod_target.build_headers.add_files(namespaced_path, files.reject { |f| f.to_path =~ framework_exp })
133
+ end
134
+
135
+ header_mappings(headers_sandbox, file_accessor, file_accessor.public_headers).each do |namespaced_path, files|
136
+ sandbox.public_headers.add_files(namespaced_path, files.reject { |f| f.to_path =~ framework_exp })
137
+ end
138
+ end
139
+
140
+ unless pod_target.requires_frameworks?
141
+ vendored_frameworks_header_mappings(headers_sandbox, file_accessor).each do |namespaced_path, files|
142
+ sandbox.public_headers.add_files(namespaced_path, files)
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ #-----------------------------------------------------------------------#
151
+
152
+ private
153
+
154
+ # @!group Private Helpers
155
+
156
+ # @return [Array<Sandbox::FileAccessor>] The file accessors for all the
157
+ # specs platform combinations.
158
+ #
159
+ def file_accessors
160
+ @file_accessors ||= pod_targets.map(&:file_accessors).flatten.compact
161
+ end
162
+
163
+ # Adds file references to the list of the paths returned by the file
164
+ # accessor with the given key to the given group of the Pods project.
165
+ #
166
+ # @param [Symbol] file_accessor_key
167
+ # The method of the file accessor which would return the list of
168
+ # the paths.
169
+ #
170
+ # @param [Symbol] group_key
171
+ # The key of the group of the Pods project.
172
+ #
173
+ # @param [Bool] reflect_file_system_structure_for_development
174
+ # Whether organizing a local pod's files in subgroups inside
175
+ # the pod's group is allowed.
176
+ #
177
+ # @return [void]
178
+ #
179
+ def add_file_accessors_paths_to_pods_group(file_accessor_key, group_key = nil, reflect_file_system_structure_for_development = false)
180
+ file_accessors.each do |file_accessor|
181
+ pod_name = file_accessor.spec.name
182
+ local = sandbox.local?(pod_name)
183
+ paths = file_accessor.send(file_accessor_key)
184
+ paths = allowable_project_paths(paths)
185
+ paths.each do |path|
186
+ group = pods_project.group_for_spec(file_accessor.spec.name, group_key)
187
+ pods_project.add_file_reference(path, group, local && reflect_file_system_structure_for_development)
188
+ end
189
+ end
190
+ end
191
+
192
+ # Filters a list of paths down to those paths which can be added to
193
+ # the Xcode project. Some paths are intermediates and only their children
194
+ # should be added, while some paths are treated as bundles and their
195
+ # children should not be added directly.
196
+ #
197
+ # @param [Array<Pathname>] paths
198
+ # The paths to files or directories on disk.
199
+ #
200
+ # @return [Array<Pathname>] The paths which can be added to the Xcode project
201
+ #
202
+ def allowable_project_paths(paths)
203
+ lproj_paths = Set.new
204
+ lproj_paths_with_files = Set.new
205
+ allowable_paths = paths.select do |path|
206
+ path_str = path.to_s
207
+
208
+ # We add the directory for a Core Data model, but not the items in it.
209
+ next if path_str =~ /.*\.xcdatamodeld\/.+/i
210
+
211
+ # We add the directory for a Core Data migration mapping, but not the items in it.
212
+ next if path_str =~ /.*\.xcmappingmodel\/.+/i
213
+
214
+ # We add the directory for an asset catalog, but not the items in it.
215
+ next if path_str =~ /.*\.xcassets\/.+/i
216
+
217
+ if path_str =~ /\.lproj(\/|$)/i
218
+ # If the element is an .lproj directory then save it and potentially
219
+ # add it later if we don't find any contained items.
220
+ if path_str =~ /\.lproj$/i && path.directory?
221
+ lproj_paths << path
222
+ next
223
+ end
224
+
225
+ # Collect the paths for the .lproj directories that contain files.
226
+ lproj_path = /(^.*\.lproj)\/.*/i.match(path_str)[1]
227
+ lproj_paths_with_files << Pathname(lproj_path)
228
+
229
+ # Directories nested within an .lproj directory are added as file
230
+ # system references so their contained items are not added directly.
231
+ next if path.dirname.dirname == lproj_path
232
+ end
233
+
234
+ true
235
+ end
236
+
237
+ # Only add the path for the .lproj directories that do not have anything
238
+ # within them added as well. This generally happens if the glob within the
239
+ # resources directory was not a recursive glob.
240
+ allowable_paths + lproj_paths.subtract(lproj_paths_with_files).to_a
241
+ end
242
+
243
+ # Computes the destination sub-directory in the sandbox
244
+ #
245
+ # @param [Pathname] headers_sandbox
246
+ # The sandbox where the header links should be stored for this
247
+ # Pod.
248
+ #
249
+ # @param [Sandbox::FileAccessor] file_accessor
250
+ # The consumer file accessor for which the headers need to be
251
+ # linked.
252
+ #
253
+ # @param [Array<Pathname>] headers
254
+ # The absolute paths of the headers which need to be mapped.
255
+ #
256
+ # @return [Hash{Pathname => Array<Pathname>}] A hash containing the
257
+ # headers folders as the keys and the absolute paths of the
258
+ # header files as the values.
259
+ #
260
+ def header_mappings(headers_sandbox, file_accessor, headers)
261
+ consumer = file_accessor.spec_consumer
262
+ dir = headers_sandbox
263
+ dir += consumer.header_dir if consumer.header_dir
264
+
265
+ mappings = {}
266
+ headers.each do |header|
267
+ sub_dir = dir
268
+ if consumer.header_mappings_dir
269
+ header_mappings_dir = file_accessor.path_list.root + consumer.header_mappings_dir
270
+ relative_path = header.relative_path_from(header_mappings_dir)
271
+ sub_dir += relative_path.dirname
272
+ end
273
+ mappings[sub_dir] ||= []
274
+ mappings[sub_dir] << header
275
+ end
276
+ mappings
277
+ end
278
+
279
+ # Computes the destination sub-directory in the sandbox for headers
280
+ # from inside vendored frameworks.
281
+ #
282
+ # @param [Pathname] headers_sandbox
283
+ # The sandbox where the header links should be stored for this
284
+ # Pod.
285
+ #
286
+ # @param [Sandbox::FileAccessor] file_accessor
287
+ # The consumer file accessor for which the headers need to be
288
+ # linked.
289
+ #
290
+ def vendored_frameworks_header_mappings(headers_sandbox, file_accessor)
291
+ mappings = {}
292
+ file_accessor.vendored_frameworks.each do |framework|
293
+ headers_dir = Sandbox::FileAccessor.vendored_frameworks_headers_dir(framework)
294
+ headers = Sandbox::FileAccessor.vendored_frameworks_headers(framework)
295
+ framework_name = framework.basename(framework.extname)
296
+ dir = headers_sandbox + framework_name
297
+ headers.each do |header|
298
+ # the relative path of framework headers should be kept,
299
+ # not flattened like is done for most public headers.
300
+ relative_path = header.relative_path_from(headers_dir)
301
+ sub_dir = dir + relative_path.dirname
302
+ mappings[sub_dir] ||= []
303
+ mappings[sub_dir] << header
304
+ end
305
+ end
306
+ mappings
307
+ end
308
+
309
+ #-----------------------------------------------------------------------#
310
+ end
311
+ end
312
+ end
313
+ end
314
+ end