cocoapods 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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