cocoapods 1.10.0 → 1.11.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 (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
@@ -35,7 +35,7 @@ module Pod
35
35
  #
36
36
  attr_reader :podfile
37
37
 
38
- # @return [Lockfile] The Lockfile, if available, that stores the information about the Pods previously installed.
38
+ # @return [Lockfile, nil] The Lockfile, if available, that stores the information about the Pods previously installed.
39
39
  #
40
40
  attr_reader :lockfile
41
41
 
@@ -67,7 +67,7 @@ module Pod
67
67
  #
68
68
  # @param [Sandbox] sandbox @see #sandbox
69
69
  # @param [Podfile] podfile @see #podfile
70
- # @param [Lockfile] lockfile @see #lockfile
70
+ # @param [Lockfile, nil] lockfile @see #lockfile
71
71
  # @param [Array<Source>] plugin_sources @see #plugin_sources
72
72
  # @param [Boolean] has_dependencies @see #has_dependencies
73
73
  # @param [Hash, Boolean, nil] pods_to_update @see #pods_to_update
@@ -565,12 +565,11 @@ module Pod
565
565
  pod_targets_by_build_config = Hash.new([].freeze)
566
566
  build_configurations.each { |config| pod_targets_by_build_config[config] = [] }
567
567
 
568
+ dependencies_by_root_name = @podfile_dependency_cache.target_definition_dependencies(target_definition).group_by(&:root_name)
569
+
568
570
  pod_targets_by_target_definition[target_definition].each do |pod_target|
569
571
  pod_name = pod_target.pod_name
570
-
571
- dependencies = @podfile_dependency_cache.target_definition_dependencies(target_definition).select do |dependency|
572
- Specification.root_name(dependency.name) == pod_name
573
- end
572
+ dependencies = dependencies_by_root_name[pod_name] || []
574
573
 
575
574
  build_configurations.each do |configuration_name|
576
575
  whitelists = dependencies.map do |dependency|
@@ -714,7 +713,12 @@ module Pod
714
713
  dependencies.map do |root_spec, deps|
715
714
  pod_targets_by_name[root_spec.name].find do |t|
716
715
  next false if t.platform.symbolic_name != target.platform.symbolic_name ||
717
- t.build_as_framework? != target.build_as_framework? # rather than target type or requires_frameworks? since we want to group by what was specified in that _target definition_
716
+ # In the case of variants we must ensure that the platform this target is meant for is the same
717
+ # as the one we are interested in.
718
+ t.target_definitions.first.platform != target.target_definitions.first.platform ||
719
+ # rather than target type or requires_frameworks? since we want to group by what was specified in that
720
+ # _target definition_.
721
+ t.build_as_framework? != target.build_as_framework?
718
722
  spec_names = t.specs.map(&:name)
719
723
  deps.all? { |dep| spec_names.include?(dep.name) }
720
724
  end
@@ -1115,7 +1119,7 @@ module Pod
1115
1119
  def generate_sandbox_state(specifications)
1116
1120
  sandbox_state = nil
1117
1121
  UI.section 'Comparing resolved specification to the sandbox manifest' do
1118
- sandbox_analyzer = SandboxAnalyzer.new(sandbox, specifications, update_mode?)
1122
+ sandbox_analyzer = SandboxAnalyzer.new(sandbox, podfile, specifications, update_mode?)
1119
1123
  sandbox_state = sandbox_analyzer.analyze
1120
1124
  sandbox_state.print
1121
1125
  end
@@ -8,11 +8,11 @@ module Pod
8
8
  #
9
9
  attr_reader :podfile
10
10
 
11
- # @return [Array<String>] any errors that have occured during the validation
11
+ # @return [Array<String>] any errors that have occurred during the validation
12
12
  #
13
13
  attr_reader :errors
14
14
 
15
- # @return [Array<String>] any warnings that have occured during the validation
15
+ # @return [Array<String>] any warnings that have occurred during the validation
16
16
  #
17
17
  attr_reader :warnings
18
18
 
@@ -0,0 +1,9 @@
1
+ module Pod
2
+ class Installer
3
+ # Context object designed to be used with the HooksManager which describes
4
+ # the context of the installer.
5
+ #
6
+ class PreIntegrateHooksContext < BaseInstallHooksContext
7
+ end
8
+ end
9
+ end
@@ -34,6 +34,10 @@ module Pod
34
34
  #
35
35
  attr_reader :aggregate_targets
36
36
 
37
+ # @return [Hash<Symbol, Object>] Hash of installation options.
38
+ #
39
+ attr_reader :installation_options
40
+
37
41
  # @return [Bool] Flag indicating if we want to ignore the cache and force a clean installation.
38
42
  #
39
43
  attr_reader :clean_install
@@ -47,9 +51,10 @@ module Pod
47
51
  # @param [Hash<String, Hash>] podfile_plugins @see #podfile_plugins
48
52
  # @param [Array<PodTarget>] pod_targets @see #pod_targets
49
53
  # @param [Array<AggregateTarget>] aggregate_targets @see #aggregate_targets
54
+ # @param [Hash<Symbol, Object>] installation_options @see #installation_options
50
55
  # @param [Bool] clean_install @see #clean_install
51
56
  #
52
- def initialize(sandbox, cache, build_configurations, project_object_version, podfile_plugins, pod_targets, aggregate_targets,
57
+ def initialize(sandbox, cache, build_configurations, project_object_version, podfile_plugins, pod_targets, aggregate_targets, installation_options,
53
58
  clean_install: false)
54
59
  @sandbox = sandbox
55
60
  @cache = cache
@@ -58,6 +63,7 @@ module Pod
58
63
  @pod_targets = pod_targets
59
64
  @aggregate_targets = aggregate_targets
60
65
  @project_object_version = project_object_version
66
+ @installation_options = installation_options
61
67
  @clean_install = clean_install
62
68
  end
63
69
 
@@ -78,7 +84,8 @@ module Pod
78
84
  # Bail out early since these properties affect all targets and their associate projects.
79
85
  if cache.build_configurations != build_configurations ||
80
86
  cache.project_object_version != project_object_version ||
81
- YAMLHelper.convert(cache.podfile_plugins) != YAMLHelper.convert(podfile_plugins)
87
+ YAMLHelper.convert(cache.podfile_plugins) != YAMLHelper.convert(podfile_plugins) ||
88
+ YAMLHelper.convert(cache.installation_options) != YAMLHelper.convert(installation_options)
82
89
  UI.message 'Ignoring project cache due to project configuration changes.'
83
90
  return full_install_results
84
91
  end
@@ -26,18 +26,25 @@ module Pod
26
26
  #
27
27
  attr_reader :podfile_plugins
28
28
 
29
+ # @return [Hash<Symbol, Object>]
30
+ # Configured installation options
31
+ #
32
+ attr_reader :installation_options
33
+
29
34
  # Initializes a new instance.
30
35
  #
31
36
  # @param [Hash{String => TargetCacheKey}] cache_key_by_target_label @see #cache_key_by_target_label
32
37
  # @param [Hash{String => Symbol}] build_configurations @see #build_configurations
33
38
  # @param [Integer] project_object_version @see #project_object_version
34
39
  # @param [Hash<String, Hash>] podfile_plugins @see #podfile_plugins
40
+ # @param [Hash<Symbol, Object>] installation_options @see #installation_options
35
41
  #
36
- def initialize(cache_key_by_target_label = {}, build_configurations = nil, project_object_version = nil, podfile_plugins = {})
42
+ def initialize(cache_key_by_target_label = {}, build_configurations = nil, project_object_version = nil, podfile_plugins = {}, installation_options = {})
37
43
  @cache_key_by_target_label = cache_key_by_target_label
38
44
  @build_configurations = build_configurations
39
45
  @project_object_version = project_object_version
40
46
  @podfile_plugins = podfile_plugins
47
+ @installation_options = installation_options
41
48
  end
42
49
 
43
50
  def update_cache_key_by_target_label!(cache_key_by_target_label)
@@ -56,6 +63,10 @@ module Pod
56
63
  @podfile_plugins = podfile_plugins
57
64
  end
58
65
 
66
+ def update_installation_options!(installation_options)
67
+ @installation_options = installation_options
68
+ end
69
+
59
70
  def save_as(path)
60
71
  Pathname(path).dirname.mkpath
61
72
  Sandbox.update_changed_file(path, YAMLHelper.convert(to_hash))
@@ -71,7 +82,8 @@ module Pod
71
82
  project_object_version = contents['OBJECT_VERSION']
72
83
  build_configurations = contents['BUILD_CONFIGURATIONS']
73
84
  podfile_plugins = contents['PLUGINS']
74
- ProjectInstallationCache.new(cache_key_by_target_label, build_configurations, project_object_version, podfile_plugins)
85
+ installation_options = contents['INSTALLATION_OPTIONS']
86
+ ProjectInstallationCache.new(cache_key_by_target_label, build_configurations, project_object_version, podfile_plugins, installation_options)
75
87
  end
76
88
 
77
89
  def to_hash
@@ -82,6 +94,7 @@ module Pod
82
94
  contents['BUILD_CONFIGURATIONS'] = build_configurations if build_configurations
83
95
  contents['OBJECT_VERSION'] = project_object_version if project_object_version
84
96
  contents['PLUGINS'] = podfile_plugins if podfile_plugins
97
+ contents['INSTALLATION_OPTIONS'] = installation_options if installation_options
85
98
  contents
86
99
  end
87
100
  end
@@ -136,7 +136,7 @@ module Pod
136
136
  'PROJECT_NAME' => pod_target.project_name,
137
137
  }
138
138
  if is_local_pod
139
- relative_file_paths = pod_target.all_files.map { |f| Pathname.new(f).relative_path_from(sandbox.root).to_s }
139
+ relative_file_paths = pod_target.all_files.map { |f| f.relative_path_from(sandbox.root).to_s }
140
140
  contents['FILES'] = relative_file_paths.sort_by(&:downcase)
141
141
  end
142
142
  contents['CHECKOUT_OPTIONS'] = checkout_options if checkout_options
@@ -161,9 +161,12 @@ module Pod
161
161
  contents = {
162
162
  'BUILD_SETTINGS_CHECKSUM' => build_settings,
163
163
  }
164
- if aggregate_target.includes_resources?
165
- relative_file_paths = aggregate_target.resource_paths_by_config.values.flatten.uniq
166
- contents['FILES'] = relative_file_paths.sort_by(&:downcase)
164
+ if aggregate_target.includes_resources? || aggregate_target.includes_on_demand_resources?
165
+ relative_resource_file_paths = aggregate_target.resource_paths_by_config.values.flatten.uniq
166
+ relative_on_demand_resource_file_paths = aggregate_target.on_demand_resources.map do |res|
167
+ res.relative_path_from(sandbox.project_path.dirname).to_s
168
+ end
169
+ contents['FILES'] = (relative_resource_file_paths + relative_on_demand_resource_file_paths).sort_by(&:downcase)
167
170
  end
168
171
  TargetCacheKey.new(sandbox, :aggregate, contents)
169
172
  end
@@ -32,7 +32,8 @@ module Pod
32
32
  # For messages extensions, this only applies if it's embedded in a messages
33
33
  # application.
34
34
  #
35
- EMBED_FRAMEWORK_TARGET_TYPES = [:application, :application_on_demand_install_capable, :unit_test_bundle, :ui_test_bundle, :watch2_extension, :messages_application].freeze
35
+ EMBED_FRAMEWORK_TARGET_TYPES = [:application, :application_on_demand_install_capable, :unit_test_bundle,
36
+ :ui_test_bundle, :watch2_extension, :messages_application].freeze
36
37
 
37
38
  # @return [String] the name of the embed frameworks phase
38
39
  #
@@ -326,11 +327,18 @@ module Pod
326
327
 
327
328
  def reorder_script_phase(native_target, script_phase, execution_position)
328
329
  return if execution_position == :any || execution_position.to_s.empty?
329
- target_phase_type = Xcodeproj::Project::Object::PBXSourcesBuildPhase
330
+ target_phase_type = case execution_position
331
+ when :before_compile, :after_compile
332
+ Xcodeproj::Project::Object::PBXSourcesBuildPhase
333
+ when :before_headers, :after_headers
334
+ Xcodeproj::Project::Object::PBXHeadersBuildPhase
335
+ else
336
+ raise ArgumentError, "Unknown execution position `#{execution_position}`"
337
+ end
330
338
  order_before = case execution_position
331
- when :before_compile
339
+ when :before_compile, :before_headers
332
340
  true
333
- when :after_compile
341
+ when :after_compile, :after_headers
334
342
  false
335
343
  else
336
344
  raise ArgumentError, "Unknown execution position `#{execution_position}`"
@@ -387,10 +395,10 @@ module Pod
387
395
 
388
396
  # Returns the framework input paths for the given framework paths
389
397
  #
390
- # @param [Hash<Array<Xcode::FrameworkPaths>>] framework_paths
398
+ # @param [Array<Xcode::FrameworkPaths>] framework_paths
391
399
  # The target's framework paths to map to input paths.
392
400
  #
393
- # @param [Hash<Array<XCFramework>>] xcframeworks
401
+ # @param [Array<XCFramework>] xcframeworks
394
402
  # The target's xcframeworks to map to input paths.
395
403
  #
396
404
  # @return [Array<String>] The embed frameworks script input paths
@@ -426,6 +434,119 @@ module Pod
426
434
  end
427
435
  paths + xcframework_paths
428
436
  end
437
+
438
+ # Updates a projects native targets to include on demand resources specified by the supplied parameters.
439
+ # Note that currently, only app level targets are allowed to include on demand resources.
440
+ #
441
+ # @param [Sandbox] sandbox
442
+ # The sandbox to use for calculating ODR file references.
443
+ #
444
+ # @param [Xcodeproj::Project] project
445
+ # The project to update known asset tags as well as add the ODR group.
446
+ #
447
+ # @param [Xcodeproj::PBXNativeTarget, Array<Xcodeproj::PBXNativeTarget>] native_targets
448
+ # The native targets to integrate on demand resources into.
449
+ #
450
+ # @param [Sandbox::FileAccessor, Array<Sandbox::FileAccessor>] file_accessors
451
+ # The file accessors that that provide the ODRs to integrate.
452
+ #
453
+ # @param [Xcodeproj::PBXGroup] parent_odr_group
454
+ # The group to use as the parent to add ODR file references into.
455
+ #
456
+ # @param [String] target_odr_group_name
457
+ # The name to use for the group created that contains the ODR file references.
458
+ #
459
+ # @return [void]
460
+ #
461
+ def update_on_demand_resources(sandbox, project, native_targets, file_accessors, parent_odr_group,
462
+ target_odr_group_name)
463
+ category_to_tags = {}
464
+ file_accessors = Array(file_accessors)
465
+ native_targets = Array(native_targets)
466
+
467
+ # Target no longer provides ODR references so remove everything related to this target.
468
+ if file_accessors.all? { |fa| fa.on_demand_resources.empty? }
469
+ old_target_odr_group = parent_odr_group[target_odr_group_name]
470
+ old_odr_file_refs = old_target_odr_group&.recursive_children_groups&.each_with_object({}) do |group, hash|
471
+ hash[group.name] = group.files
472
+ end || {}
473
+ native_targets.each do |native_target|
474
+ native_target.remove_on_demand_resources(old_odr_file_refs)
475
+ update_on_demand_resources_build_settings(native_target, nil => old_odr_file_refs.keys)
476
+ end
477
+ old_target_odr_group&.remove_from_project
478
+ return
479
+ end
480
+
481
+ target_odr_group = parent_odr_group[target_odr_group_name] || parent_odr_group.new_group(target_odr_group_name)
482
+ current_file_refs = target_odr_group.recursive_children_groups.flat_map(&:files)
483
+
484
+ added_file_refs = file_accessors.flat_map do |file_accessor|
485
+ target_odr_files_refs = Hash[file_accessor.on_demand_resources.map do |tag, value|
486
+ tag_group = target_odr_group[tag] || target_odr_group.new_group(tag)
487
+ category_to_tags[value[:category]] ||= []
488
+ category_to_tags[value[:category]] << tag
489
+ resources_file_refs = value[:paths].map do |resource|
490
+ odr_resource_file_ref = Pathname.new(resource).relative_path_from(sandbox.root)
491
+ tag_group.find_file_by_path(odr_resource_file_ref.to_s) || tag_group.new_file(odr_resource_file_ref)
492
+ end
493
+ [tag, resources_file_refs]
494
+ end]
495
+ native_targets.each do |native_target|
496
+ native_target.add_on_demand_resources(target_odr_files_refs)
497
+ end
498
+ target_odr_files_refs.values.flatten
499
+ end
500
+
501
+ # if the target ODR file references were updated, make sure we remove the ones that are no longer present
502
+ # for the target.
503
+ remaining_refs = current_file_refs - added_file_refs
504
+ remaining_refs.each do |ref|
505
+ native_targets.each do |user_target|
506
+ user_target.resources_build_phase.remove_file_reference(ref)
507
+ end
508
+ ref.remove_from_project
509
+ end
510
+ target_odr_group.recursive_children_groups.each { |g| g.remove_from_project if g.empty? }
511
+
512
+ attributes = project.root_object.attributes
513
+ attributes['KnownAssetTags'] = (attributes['KnownAssetTags'] ||= []) | category_to_tags.values.flatten
514
+ project.root_object.attributes = attributes
515
+
516
+ native_targets.each do |native_target|
517
+ update_on_demand_resources_build_settings(native_target, category_to_tags)
518
+ end
519
+ end
520
+
521
+ def update_on_demand_resources_build_settings(native_target, category_to_tags)
522
+ %w[ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS ON_DEMAND_RESOURCES_PREFETCH_ORDER].each do |category_key|
523
+ native_target.build_configurations.each do |c|
524
+ key = case category_key
525
+ when 'ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS'
526
+ :initial_install
527
+ when 'ON_DEMAND_RESOURCES_PREFETCH_ORDER'
528
+ :prefetched
529
+ else
530
+ :download_on_demand
531
+ end
532
+ tags_for_category = (c.build_settings[category_key] || '').split
533
+ category_to_tags_dup = category_to_tags.dup
534
+ tags_to_add = category_to_tags_dup.delete(key) || []
535
+ tags_to_delete = category_to_tags_dup.values.flatten
536
+ tags_for_category = (tags_for_category + tags_to_add - tags_to_delete).flatten.compact.uniq
537
+ if tags_for_category.empty?
538
+ val = c.build_settings.delete(category_key)
539
+ native_target.project.mark_dirty! unless val.nil?
540
+ else
541
+ tags = tags_for_category.join(' ')
542
+ unless c.build_settings[category_key] == tags
543
+ c.build_settings[category_key] = tags
544
+ native_target.project.mark_dirty!
545
+ end
546
+ end
547
+ end
548
+ end
549
+ end
429
550
  end
430
551
 
431
552
  # Integrates the user project targets. Only the targets that do **not**
@@ -445,6 +566,7 @@ module Pod
445
566
  add_copy_resources_script_phase
446
567
  add_check_manifest_lock_script_phase
447
568
  add_user_script_phases
569
+ add_on_demand_resources
448
570
  end
449
571
  end
450
572
 
@@ -509,10 +631,12 @@ module Pod
509
631
  output_paths_by_config = {}
510
632
  if use_input_output_paths
511
633
  target.resource_paths_by_config.each do |config, resource_paths|
512
- input_paths_key = XCFileListConfigKey.new(target.copy_resources_script_input_files_path(config), target.copy_resources_script_input_files_relative_path)
634
+ input_paths_key = XCFileListConfigKey.new(target.copy_resources_script_input_files_path(config),
635
+ target.copy_resources_script_input_files_relative_path)
513
636
  input_paths_by_config[input_paths_key] = [script_path] + resource_paths
514
637
 
515
- output_paths_key = XCFileListConfigKey.new(target.copy_resources_script_output_files_path(config), target.copy_resources_script_output_files_relative_path)
638
+ output_paths_key = XCFileListConfigKey.new(target.copy_resources_script_output_files_path(config),
639
+ target.copy_resources_script_output_files_relative_path)
516
640
  output_paths_by_config[output_paths_key] = TargetIntegrator.resource_output_paths(resource_paths)
517
641
  end
518
642
  end
@@ -520,7 +644,9 @@ module Pod
520
644
  native_targets.each do |native_target|
521
645
  # Static library targets cannot include resources. Skip this phase from being added instead.
522
646
  next if native_target.symbol_type == :static_library
523
- TargetIntegrator.create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths_by_config, output_paths_by_config)
647
+ TargetIntegrator.create_or_update_copy_resources_script_phase_to_target(native_target, script_path,
648
+ input_paths_by_config,
649
+ output_paths_by_config)
524
650
  end
525
651
  end
526
652
 
@@ -624,6 +750,20 @@ module Pod
624
750
  end
625
751
  end
626
752
 
753
+ def add_on_demand_resources
754
+ target.pod_targets.each do |pod_target|
755
+ # When integrating with the user's project we are only interested in integrating ODRs from library specs
756
+ # and not test specs or app specs.
757
+ library_file_accessors = pod_target.file_accessors.select { |fa| fa.spec.library_specification? }
758
+ target_odr_group_name = "#{pod_target.label}-OnDemandResources"
759
+ # The 'Pods' group would always be there for production code however for tests its sometimes not added.
760
+ # This ensures its always present and makes it easier for existing and new tests.
761
+ parent_odr_group = target.user_project.main_group['Pods'] || target.user_project.new_group('Pods')
762
+ TargetIntegrator.update_on_demand_resources(target.sandbox, target.user_project, target.user_targets,
763
+ library_file_accessors, parent_odr_group, target_odr_group_name)
764
+ end
765
+ end
766
+
627
767
  private
628
768
 
629
769
  # @!group Private Helpers
@@ -45,6 +45,11 @@ module Pod
45
45
  #
46
46
  attr_reader :info_plist_entries
47
47
 
48
+ # @return [String] product_basename
49
+ # The product basename to use for the target.
50
+ #
51
+ attr_reader :product_basename
52
+
48
53
  # Initialize a new instance
49
54
  #
50
55
  # @param [Sandbox] sandbox @see #sandbox
@@ -55,8 +60,9 @@ module Pod
55
60
  # @param [String] app_target_label see #app_target_label
56
61
  # @param [Boolean] add_main see #add_main
57
62
  # @param [Hash] info_plist_entries see #info_plist_entries
63
+ # @param [String] product_basename see #product_basename
58
64
  #
59
- def initialize(sandbox, project, platform, subgroup_name, group_name, app_target_label, add_main: true, add_launchscreen_storyboard: platform == :ios, info_plist_entries: {})
65
+ def initialize(sandbox, project, platform, subgroup_name, group_name, app_target_label, add_main: true, add_launchscreen_storyboard: platform == :ios, info_plist_entries: {}, product_basename: nil)
60
66
  @sandbox = sandbox
61
67
  @project = project
62
68
  @platform = platform
@@ -66,6 +72,7 @@ module Pod
66
72
  @add_main = add_main
67
73
  @add_launchscreen_storyboard = add_launchscreen_storyboard
68
74
  @info_plist_entries = info_plist_entries
75
+ @product_basename = product_basename || app_target_label
69
76
  target_group = project.pod_group(group_name)
70
77
  @group = target_group[subgroup_name] || target_group.new_group(subgroup_name)
71
78
  end
@@ -75,9 +82,9 @@ module Pod
75
82
  def install!
76
83
  platform_name = platform.name
77
84
  app_host_target = Pod::Generator::AppTargetHelper.add_app_target(project, platform_name, deployment_target,
78
- app_target_label)
85
+ app_target_label, product_basename)
79
86
  app_host_target.build_configurations.each do |configuration|
80
- configuration.build_settings['PRODUCT_NAME'] = app_target_label
87
+ configuration.build_settings['PRODUCT_NAME'] = product_basename
81
88
  configuration.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}'
82
89
  if platform == :osx
83
90
  configuration.build_settings['CODE_SIGN_IDENTITY'] = ''