cocoapods 1.10.0 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +261 -5
  3. data/README.md +11 -11
  4. data/lib/cocoapods/command/outdated.rb +12 -1
  5. data/lib/cocoapods/command/repo/push.rb +17 -0
  6. data/lib/cocoapods/command/spec/cat.rb +3 -1
  7. data/lib/cocoapods/command/spec/lint.rb +1 -1
  8. data/lib/cocoapods/command/spec/which.rb +3 -1
  9. data/lib/cocoapods/command/spec.rb +18 -9
  10. data/lib/cocoapods/config.rb +1 -1
  11. data/lib/cocoapods/downloader/cache.rb +95 -6
  12. data/lib/cocoapods/downloader.rb +4 -2
  13. data/lib/cocoapods/external_sources/podspec_source.rb +1 -1
  14. data/lib/cocoapods/gem_version.rb +1 -1
  15. data/lib/cocoapods/generator/acknowledgements.rb +1 -1
  16. data/lib/cocoapods/generator/app_target_helper.rb +7 -3
  17. data/lib/cocoapods/generator/copy_dsyms_script.rb +4 -4
  18. data/lib/cocoapods/generator/copy_xcframework_script.rb +4 -48
  19. data/lib/cocoapods/generator/embed_frameworks_script.rb +2 -1
  20. data/lib/cocoapods/generator/script_phase_constants.rb +1 -0
  21. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +31 -4
  22. data/lib/cocoapods/installer/analyzer.rb +12 -8
  23. data/lib/cocoapods/installer/podfile_validator.rb +2 -2
  24. data/lib/cocoapods/installer/pre_integrate_hooks_context.rb +9 -0
  25. data/lib/cocoapods/installer/project_cache/project_cache_analyzer.rb +9 -2
  26. data/lib/cocoapods/installer/project_cache/project_installation_cache.rb +15 -2
  27. data/lib/cocoapods/installer/project_cache/target_cache_key.rb +7 -4
  28. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +149 -9
  29. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +10 -3
  30. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +25 -6
  31. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +6 -19
  32. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +70 -58
  33. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +48 -6
  34. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +2 -2
  35. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +2 -5
  36. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +1 -1
  37. data/lib/cocoapods/installer.rb +52 -4
  38. data/lib/cocoapods/resolver.rb +4 -4
  39. data/lib/cocoapods/sandbox/file_accessor.rb +57 -10
  40. data/lib/cocoapods/sandbox/headers_store.rb +3 -1
  41. data/lib/cocoapods/sandbox/path_list.rb +1 -1
  42. data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +1 -1
  43. data/lib/cocoapods/sources_manager.rb +14 -8
  44. data/lib/cocoapods/target/aggregate_target.rb +23 -1
  45. data/lib/cocoapods/target/build_settings.rb +45 -20
  46. data/lib/cocoapods/target/pod_target.rb +47 -22
  47. data/lib/cocoapods/target.rb +1 -1
  48. data/lib/cocoapods/user_interface.rb +4 -0
  49. data/lib/cocoapods/validator.rb +25 -5
  50. data/lib/cocoapods/version_metadata.rb +1 -1
  51. data/lib/cocoapods/xcode/xcframework/xcframework_slice.rb +10 -1
  52. data/lib/cocoapods/xcode/xcframework.rb +8 -3
  53. metadata +26 -19
@@ -34,6 +34,7 @@ module Pod
34
34
  target_installation_result.non_library_specs_by_native_target.each do |native_target, spec|
35
35
  add_embed_frameworks_script_phase(native_target, spec)
36
36
  add_copy_resources_script_phase(native_target, spec)
37
+ add_on_demand_resources(native_target, spec) if spec.app_specification?
37
38
  UserProjectIntegrator::TargetIntegrator.create_or_update_user_script_phases(script_phases_for_specs(spec), native_target)
38
39
  end
39
40
  add_copy_dsyms_script_phase(target_installation_result.native_target)
@@ -134,20 +135,26 @@ module Pod
134
135
  spec_paths_to_include << spec.name if dependent_target == target
135
136
  dependent_target.framework_paths.values_at(*spec_paths_to_include).flatten.compact
136
137
  end.uniq
138
+ xcframework_paths = dependent_targets.flat_map do |dependent_target|
139
+ spec_paths_to_include = dependent_target.library_specs.map(&:name)
140
+ spec_paths_to_include -= host_target_spec_names
141
+ spec_paths_to_include << spec.name if dependent_target == target
142
+ dependent_target.xcframeworks.values_at(*spec_paths_to_include).flatten.compact
143
+ end.uniq
137
144
 
138
- if use_input_output_paths? && !framework_paths.empty?
145
+ if use_input_output_paths? && !framework_paths.empty? || !xcframework_paths.empty?
139
146
  input_file_list_path = target.embed_frameworks_script_input_files_path_for_spec(spec)
140
147
  input_file_list_relative_path = "${PODS_ROOT}/#{input_file_list_path.relative_path_from(target.sandbox.root)}"
141
148
  input_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(input_file_list_path, input_file_list_relative_path)
142
- input_paths_by_config[input_paths_key] = [script_path] + UserProjectIntegrator::TargetIntegrator.embed_frameworks_input_paths(framework_paths, [])
149
+ input_paths_by_config[input_paths_key] = [script_path] + UserProjectIntegrator::TargetIntegrator.embed_frameworks_input_paths(framework_paths, xcframework_paths)
143
150
 
144
151
  output_file_list_path = target.embed_frameworks_script_output_files_path_for_spec(spec)
145
152
  output_file_list_relative_path = "${PODS_ROOT}/#{output_file_list_path.relative_path_from(target.sandbox.root)}"
146
153
  output_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(output_file_list_path, output_file_list_relative_path)
147
- output_paths_by_config[output_paths_key] = UserProjectIntegrator::TargetIntegrator.embed_frameworks_output_paths(framework_paths, [])
154
+ output_paths_by_config[output_paths_key] = UserProjectIntegrator::TargetIntegrator.embed_frameworks_output_paths(framework_paths, xcframework_paths)
148
155
  end
149
156
 
150
- if framework_paths.empty?
157
+ if framework_paths.empty? && xcframework_paths.empty?
151
158
  UserProjectIntegrator::TargetIntegrator.remove_embed_frameworks_script_phase_from_target(native_target)
152
159
  else
153
160
  UserProjectIntegrator::TargetIntegrator.create_or_update_embed_frameworks_script_phase_to_target(
@@ -183,7 +190,7 @@ module Pod
183
190
  output_file_list_relative_path = "${PODS_ROOT}/#{output_file_list_path.relative_path_from(target.sandbox.root)}"
184
191
  output_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(output_file_list_path, output_file_list_relative_path)
185
192
  output_paths_by_config[output_paths_key] = xcframeworks.map do |xcf|
186
- "#{Target::BuildSettings::XCFRAMEWORKS_BUILD_DIR_VARIABLE}/#{xcf.name}"
193
+ "#{Target::BuildSettings::XCFRAMEWORKS_BUILD_DIR_VARIABLE}/#{xcf.target_name}/#{xcf.name}.framework"
187
194
  end
188
195
  end
189
196
 
@@ -199,7 +206,7 @@ module Pod
199
206
  # vendored dSYMs.
200
207
  #
201
208
  # @param [PBXNativeTarget] native_target
202
- # the native target for which to add the the copy dSYM files build phase.
209
+ # the native target for which to add the copy dSYM files build phase.
203
210
  #
204
211
  # @return [void]
205
212
  #
@@ -242,6 +249,41 @@ module Pod
242
249
  UserProjectIntegrator::TargetIntegrator.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config)
243
250
  end
244
251
 
252
+ # Adds the ODRs that are related to this app spec. This includes the app spec dependencies as well as the ODRs
253
+ # coming from the app spec itself.
254
+ #
255
+ # @param [Xcodeproj::PBXNativeTarget] native_target
256
+ # the native target for which to add the ODR file references into.
257
+ #
258
+ # @param [Specification] app_spec
259
+ # the app spec to integrate ODRs for.
260
+ #
261
+ # @return [void]
262
+ #
263
+ def add_on_demand_resources(native_target, app_spec)
264
+ dependent_targets = target.dependent_targets_for_app_spec(app_spec)
265
+ parent_odr_group = native_target.project.group_for_spec(app_spec.name)
266
+
267
+ # Add ODRs of the app spec dependencies first.
268
+ dependent_targets.each do |pod_target|
269
+ file_accessors = pod_target.file_accessors.select do |fa|
270
+ fa.spec.library_specification? ||
271
+ fa.spec.test_specification? && pod_target.test_app_hosts_by_spec[fa.spec]&.first == app_spec
272
+ end
273
+ target_odr_group_name = "#{pod_target.label}-OnDemandResources"
274
+ UserProjectIntegrator::TargetIntegrator.update_on_demand_resources(target.sandbox, native_target.project,
275
+ native_target, file_accessors,
276
+ parent_odr_group, target_odr_group_name)
277
+ end
278
+
279
+ # Now add the ODRs of our own app spec declaration.
280
+ file_accessor = target.file_accessors.find { |fa| fa.spec == app_spec }
281
+ target_odr_group_name = "#{target.subspec_label(app_spec)}-OnDemandResources"
282
+ UserProjectIntegrator::TargetIntegrator.update_on_demand_resources(target.sandbox, native_target.project,
283
+ native_target, file_accessor,
284
+ parent_odr_group, target_odr_group_name)
285
+ end
286
+
245
287
  # @return [String] the message that should be displayed for the target
246
288
  # integration.
247
289
  #
@@ -79,12 +79,12 @@ module Pod
79
79
  # @param [Specification] spec
80
80
  # The specification to base from in order to find the native target.
81
81
  #
82
- # @return [PBXNativeTarget] the native target to use or `nil` if none is found.
82
+ # @return [PBXNativeTarget, Nil] the native target to use or `nil` if none is found.
83
83
  #
84
84
  def native_target_for_spec(spec)
85
85
  return native_target if spec.library_specification?
86
86
  return test_native_target_from_spec(spec) if spec.test_specification?
87
- return app_native_target_from_spec(spec) if spec.app_specification?
87
+ app_native_target_from_spec(spec) if spec.app_specification?
88
88
  end
89
89
 
90
90
  # @return [Hash{PBXNativeTarget => Specification}] a hash where the keys are the test native targets and the value
@@ -56,11 +56,8 @@ module Pod
56
56
  name = target.label
57
57
  platform = target.platform.name
58
58
  language = target.uses_swift? ? :swift : :objc
59
- native_target = project.new_target(product_type, name, platform, deployment_target, nil, language)
60
-
61
- product_name = target.product_name
62
- product = native_target.product_reference
63
- product.name = product_name
59
+ native_target = project.new_target(product_type, name, platform, deployment_target, nil, language, target.product_basename)
60
+ native_target.product_reference.name = name
64
61
 
65
62
  target.user_build_configurations.each do |bc_name, type|
66
63
  native_target.add_build_configuration(bc_name, type)
@@ -247,7 +247,7 @@ module Pod
247
247
  end
248
248
  is_custom_host = !hosted_test_specs_by_host.empty?
249
249
  specs.each do |spec|
250
- scheme_name = spec.spec_type == :library ? pod_target.label : pod_target.non_library_spec_label(spec)
250
+ scheme_name = pod_target.spec_label(spec)
251
251
  scheme_configuration = pod_target.scheme_for_spec(spec)
252
252
  if !scheme_configuration.empty? || is_custom_host
253
253
  scheme_path = Xcodeproj::XCScheme.user_data_dir(project.path) + "#{scheme_name}.xcscheme"
@@ -36,6 +36,7 @@ module Pod
36
36
  autoload :PreInstallHooksContext, 'cocoapods/installer/pre_install_hooks_context'
37
37
  autoload :BaseInstallHooksContext, 'cocoapods/installer/base_install_hooks_context'
38
38
  autoload :PostIntegrateHooksContext, 'cocoapods/installer/post_integrate_hooks_context'
39
+ autoload :PreIntegrateHooksContext, 'cocoapods/installer/pre_integrate_hooks_context'
39
40
  autoload :SourceProviderHooksContext, 'cocoapods/installer/source_provider_hooks_context'
40
41
  autoload :PodfileValidator, 'cocoapods/installer/podfile_validator'
41
42
  autoload :PodSourceInstaller, 'cocoapods/installer/pod_source_installer'
@@ -175,6 +176,7 @@ module Pod
175
176
  end
176
177
 
177
178
  def integrate
179
+ run_podfile_pre_integrate_hooks
178
180
  generate_pods_project
179
181
  if installation_options.integrate_targets?
180
182
  integrate_user_project
@@ -199,7 +201,7 @@ module Pod
199
201
 
200
202
  force_clean_install = clean_install || project_cache_version.version != Version.create(VersionMetadata.project_cache_version)
201
203
  cache_result = ProjectCache::ProjectCacheAnalyzer.new(sandbox, installation_cache, analysis_result.all_user_build_configurations,
202
- object_version, plugins, pod_targets, aggregate_targets, :clean_install => force_clean_install).analyze
204
+ object_version, plugins, pod_targets, aggregate_targets, installation_options.to_h, :clean_install => force_clean_install).analyze
203
205
  aggregate_targets_to_generate = cache_result.aggregate_targets_to_generate || []
204
206
  pod_targets_to_generate = cache_result.pod_targets_to_generate
205
207
  (aggregate_targets_to_generate + pod_targets_to_generate).each do |target|
@@ -627,6 +629,15 @@ module Pod
627
629
  title_options)
628
630
  end
629
631
 
632
+ # Runs the registered callbacks for the plugins pre integrate hooks.
633
+ #
634
+ def run_plugins_pre_integrate_hooks
635
+ if any_plugin_pre_integrate_hooks?
636
+ context = PreIntegrateHooksContext.generate(sandbox, pods_project, aggregate_targets)
637
+ HooksManager.run(:pre_integrate, context, plugins)
638
+ end
639
+ end
640
+
630
641
  # Runs the registered callbacks for the plugins post install hooks.
631
642
  #
632
643
  def run_plugins_post_install_hooks
@@ -650,6 +661,12 @@ module Pod
650
661
  end
651
662
  end
652
663
 
664
+ # @return [Boolean] whether there are any plugin pre-integrate hooks to run
665
+ #
666
+ def any_plugin_pre_integrate_hooks?
667
+ HooksManager.hooks_to_run(:pre_integrate, plugins).any?
668
+ end
669
+
653
670
  # @return [Boolean] whether there are any plugin post-install hooks to run
654
671
  #
655
672
  def any_plugin_post_install_hooks?
@@ -747,7 +764,7 @@ module Pod
747
764
  def warn_for_installed_script_phases
748
765
  pods_to_install = sandbox_state.added | sandbox_state.changed
749
766
  pod_targets.group_by(&:pod_name).each do |name, pod_targets|
750
- if pods_to_install.include?(name)
767
+ if pods_to_install.include?(name) && !sandbox.local?(name)
751
768
  script_phase_count = pod_targets.inject(0) { |sum, target| sum + target.script_phases.count }
752
769
  unless script_phase_count.zero?
753
770
  UI.warn "#{name} has added #{script_phase_count} #{'script phase'.pluralize(script_phase_count)}. " \
@@ -766,9 +783,11 @@ module Pod
766
783
  #
767
784
  def warn_for_removing_git_master_specs_repo
768
785
  return unless installation_options.warn_for_unused_master_specs_repo?
769
- podfile_master_source = podfile.sources.find { |source| source == MASTER_SPECS_REPO_GIT_URL }
786
+ plugin_sources = run_source_provider_hooks
787
+ all_sources = podfile.sources + plugin_sources.map(&:url)
788
+ master_source = all_sources.find { |source| source == MASTER_SPECS_REPO_GIT_URL }
770
789
  master_repo = config.sources_manager.all.find { |s| s.url == MASTER_SPECS_REPO_GIT_URL }
771
- if podfile_master_source.nil? && !master_repo.nil?
790
+ if master_source.nil? && !master_repo.nil?
772
791
  UI.warn 'Your project does not explicitly specify the CocoaPods master specs repo. Since CDN is now used as the' \
773
792
  ' default, you may safely remove it from your repos directory via `pod repo remove master`. To suppress this warning' \
774
793
  ' please add `warn_for_unused_master_specs_repo => false` to your Podfile.'
@@ -815,6 +834,7 @@ module Pod
815
834
  installation_cache.update_project_object_version!(cache_analysis_result.project_object_version)
816
835
  installation_cache.update_build_configurations!(cache_analysis_result.build_configurations)
817
836
  installation_cache.update_podfile_plugins!(plugins)
837
+ installation_cache.update_installation_options!(installation_options.to_h)
818
838
  installation_cache.save_as(sandbox.project_installation_cache_path)
819
839
 
820
840
  metadata_cache.update_metadata!(target_installation_results.pod_target_installation_results || {},
@@ -873,6 +893,34 @@ module Pod
873
893
  "\n\n#{e.message}\n\n#{e.backtrace * "\n"}"
874
894
  end
875
895
 
896
+ # Runs the post integrate hooks of the installed specs and of the Podfile.
897
+ #
898
+ # @note Post integrate hooks run _after_ saving of project, so that they
899
+ # can alter it after it is written to the disk.
900
+ #
901
+ # @return [void]
902
+ #
903
+ def run_podfile_pre_integrate_hooks
904
+ UI.message '- Running pre integrate hooks' do
905
+ executed = run_podfile_pre_integrate_hook
906
+ UI.message '- Podfile' if executed
907
+ end
908
+ end
909
+
910
+ # Runs the pre integrate hook of the Podfile.
911
+ #
912
+ # @raise Raises an informative if the hooks raises.
913
+ #
914
+ # @return [Boolean] Whether the hook was run.
915
+ #
916
+ def run_podfile_pre_integrate_hook
917
+ podfile.pre_integrate!(self)
918
+ rescue => e
919
+ raise Informative, 'An error occurred while processing the pre-integrate ' \
920
+ 'hook of the Podfile.' \
921
+ "\n\n#{e.message}\n\n#{e.backtrace * "\n"}"
922
+ end
923
+
876
924
  # Runs the post install hooks of the installed specs and of the Podfile.
877
925
  #
878
926
  # @note Post install hooks run _before_ saving of project, so that they
@@ -162,9 +162,8 @@ module Pod
162
162
  Array(@podfile_requirements_by_root_name[dependency.root_name])
163
163
  end
164
164
 
165
- specifications_for_dependency(dependency, additional_requirements)
165
+ specifications_for_dependency(dependency, additional_requirements).freeze
166
166
  end
167
- @search[dependency].dup
168
167
  end
169
168
 
170
169
  # Returns the dependencies of `specification`.
@@ -175,8 +174,9 @@ module Pod
175
174
  # dependencies are being asked for.
176
175
  #
177
176
  def dependencies_for(specification)
177
+ root_name = Specification.root_name(specification.name)
178
178
  specification.all_dependencies.map do |dependency|
179
- if dependency.root_name == Specification.root_name(specification.name)
179
+ if dependency.root_name == root_name
180
180
  dependency.dup.tap { |d| d.specific_version = specification.version }
181
181
  else
182
182
  dependency
@@ -264,7 +264,7 @@ module Pod
264
264
  # @param [{String => Array<Conflict>}] conflicts the current conflicts.
265
265
  #
266
266
  def sort_dependencies(dependencies, activated, conflicts)
267
- dependencies.sort_by do |dependency|
267
+ dependencies.sort_by! do |dependency|
268
268
  name = name_for(dependency)
269
269
  [
270
270
  activated.vertex_named(name).payload ? 0 : 1,
@@ -128,6 +128,7 @@ module Pod
128
128
  #
129
129
  def public_headers(include_frameworks = false)
130
130
  public_headers = public_header_files
131
+ project_headers = project_header_files
131
132
  private_headers = private_header_files
132
133
  if public_headers.nil? || public_headers.empty?
133
134
  header_files = headers
@@ -135,7 +136,13 @@ module Pod
135
136
  header_files = public_headers
136
137
  end
137
138
  header_files += vendored_frameworks_headers if include_frameworks
138
- header_files - private_headers
139
+ header_files - project_headers - private_headers
140
+ end
141
+
142
+ # @return [Array<Pathname>] The project headers of the specification.
143
+ #
144
+ def project_headers
145
+ project_header_files
139
146
  end
140
147
 
141
148
  # @return [Array<Pathname>] The private headers of the specification.
@@ -172,6 +179,15 @@ module Pod
172
179
  end
173
180
  end
174
181
 
182
+ # @return [Array<Pathname>] The paths of the dynamic xcframework bundles
183
+ # that come shipped with the Pod.
184
+ #
185
+ def vendored_static_xcframeworks
186
+ vendored_xcframeworks.select do |path|
187
+ Xcode::XCFramework.new(spec.name, path).build_type == BuildType.static_framework
188
+ end
189
+ end
190
+
175
191
  # @return [Array<Pathname>] The paths of the static (fake) framework
176
192
  # bundles that come shipped with the Pod.
177
193
  #
@@ -191,7 +207,7 @@ module Pod
191
207
  # @param [Array<FileAccessor>] file_accessors
192
208
  # The list of all file accessors to compute.
193
209
  #
194
- # @return [Array<String>] The list of all file accessors that a target will integrate into the project.
210
+ # @return [Array<Pathname>] The list of all file accessors that a target will integrate into the project.
195
211
  #
196
212
  def self.all_files(file_accessors)
197
213
  files = [
@@ -203,10 +219,11 @@ module Pod
203
219
  file_accessors.map(&:preserve_paths),
204
220
  file_accessors.map(&:readme),
205
221
  file_accessors.map(&:resources),
222
+ file_accessors.map(&:on_demand_resources_files),
206
223
  file_accessors.map(&:source_files),
207
224
  file_accessors.map(&:module_map),
208
225
  ]
209
- files.flatten.compact.map(&:to_s).uniq
226
+ files.flatten.compact.uniq
210
227
  end
211
228
 
212
229
  # @param [Pathname] framework
@@ -229,14 +246,17 @@ module Pod
229
246
  Pathname.glob(headers_dir + '**/' + GLOB_PATTERNS[:public_header_files])
230
247
  end
231
248
 
232
- # @param [Pathname] framework
249
+ # @param [String] target_name
250
+ # The target name this .xcframework belongs to
251
+ #
252
+ # @param [Pathname] framework_path
233
253
  # The path to the .xcframework
234
254
  #
235
255
  # @return [Array<Pathname>] The paths to all the headers included in the
236
256
  # vendored xcframework
237
257
  #
238
- def self.vendored_xcframework_headers(framework)
239
- xcframework = Xcode::XCFramework.new(framework)
258
+ def self.vendored_xcframework_headers(target_name, framework_path)
259
+ xcframework = Xcode::XCFramework.new(target_name, framework_path)
240
260
  xcframework.slices.flat_map do |slice|
241
261
  vendored_frameworks_headers(slice.path)
242
262
  end
@@ -250,7 +270,7 @@ module Pod
250
270
  self.class.vendored_frameworks_headers(framework)
251
271
  end.uniq
252
272
  paths.concat Array.new(vendored_xcframeworks.flat_map do |framework|
253
- self.class.vendored_xcframework_headers(framework)
273
+ self.class.vendored_xcframework_headers(spec.name, framework)
254
274
  end)
255
275
  paths
256
276
  end
@@ -289,7 +309,7 @@ module Pod
289
309
  # that come shipped with the Pod.
290
310
  #
291
311
  def vendored_static_artifacts
292
- vendored_static_libraries + vendored_static_frameworks
312
+ vendored_static_libraries + vendored_static_frameworks + vendored_static_xcframeworks
293
313
  end
294
314
 
295
315
  # @return [Hash{String => Array<Pathname>}] A hash that describes the
@@ -314,6 +334,26 @@ module Pod
314
334
  resource_bundles.values.flatten
315
335
  end
316
336
 
337
+ # @return [Hash{String => Hash] The expanded paths of the on demand resources specified
338
+ # keyed by their tag including their category.
339
+ #
340
+ def on_demand_resources
341
+ result = {}
342
+ spec_consumer.on_demand_resources.each do |tag_name, file_patterns|
343
+ paths = expanded_paths(file_patterns[:paths],
344
+ :exclude_patterns => spec_consumer.exclude_files,
345
+ :include_dirs => true)
346
+ result[tag_name] = { :paths => paths, :category => file_patterns[:category] }
347
+ end
348
+ result
349
+ end
350
+
351
+ # @return [Array<Pathname>] The expanded paths of the on demand resources.
352
+ #
353
+ def on_demand_resources_files
354
+ on_demand_resources.values.flat_map { |v| v[:paths] }
355
+ end
356
+
317
357
  # @return [Pathname] The of the prefix header file of the specification.
318
358
  #
319
359
  def prefix_header
@@ -322,7 +362,7 @@ module Pod
322
362
  end
323
363
  end
324
364
 
325
- # @return [Pathname] The path of the auto-detected README file.
365
+ # @return [Pathname, nil] The path of the auto-detected README file.
326
366
  #
327
367
  def readme
328
368
  path_list.glob([GLOB_PATTERNS[:readme]]).first
@@ -404,7 +444,14 @@ module Pod
404
444
  paths_for_attribute(:public_header_files)
405
445
  end
406
446
 
407
- # @return [Array<Pathname>] The paths of the user-specified public header
447
+ # @return [Array<Pathname>] The paths of the user-specified project header
448
+ # files.
449
+ #
450
+ def project_header_files
451
+ paths_for_attribute(:project_header_files)
452
+ end
453
+
454
+ # @return [Array<Pathname>] The paths of the user-specified private header
408
455
  # files.
409
456
  #
410
457
  def private_header_files
@@ -51,7 +51,9 @@ module Pod
51
51
  #
52
52
  def search_paths(platform, target_name = nil, use_modular_headers = false)
53
53
  key = SEARCH_PATHS_KEY.new(platform.name, target_name, use_modular_headers)
54
- return @search_paths_cache[key] if @search_paths_cache.key?(key)
54
+ if (cached = @search_paths_cache[key])
55
+ return cached
56
+ end
55
57
  search_paths = @search_paths.select do |entry|
56
58
  matches_platform = entry[:platform] == platform.name
57
59
  matches_target = target_name.nil? || (File.basename(entry[:path]) == target_name)
@@ -23,7 +23,7 @@ module Pod
23
23
  # @param [Pathname] root @see #root
24
24
  #
25
25
  def initialize(root)
26
- root_dir = ActiveSupport::Multibyte::Unicode.normalize(root.to_s)
26
+ root_dir = root.to_s.unicode_normalize(:nfkc)
27
27
  @root = Pathname.new(root_dir)
28
28
  @glob_cache = {}
29
29
  end