cocoapods 1.10.0 → 1.16.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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +571 -7
  3. data/README.md +10 -11
  4. data/bin/sandbox-pod +1 -1
  5. data/lib/cocoapods/command/lib/lint.rb +4 -1
  6. data/lib/cocoapods/command/outdated.rb +12 -1
  7. data/lib/cocoapods/command/repo/push.rb +20 -0
  8. data/lib/cocoapods/command/setup.rb +2 -2
  9. data/lib/cocoapods/command/spec/cat.rb +3 -1
  10. data/lib/cocoapods/command/spec/create.rb +1 -0
  11. data/lib/cocoapods/command/spec/lint.rb +4 -1
  12. data/lib/cocoapods/command/spec/which.rb +3 -1
  13. data/lib/cocoapods/command/spec.rb +18 -9
  14. data/lib/cocoapods/config.rb +8 -7
  15. data/lib/cocoapods/downloader/cache.rb +98 -6
  16. data/lib/cocoapods/downloader.rb +4 -2
  17. data/lib/cocoapods/executable.rb +1 -1
  18. data/lib/cocoapods/external_sources/abstract_external_source.rb +1 -1
  19. data/lib/cocoapods/external_sources/path_source.rb +1 -1
  20. data/lib/cocoapods/external_sources/podspec_source.rb +1 -1
  21. data/lib/cocoapods/gem_version.rb +1 -1
  22. data/lib/cocoapods/generator/acknowledgements.rb +13 -1
  23. data/lib/cocoapods/generator/app_target_helper.rb +8 -4
  24. data/lib/cocoapods/generator/copy_dsyms_script.rb +4 -4
  25. data/lib/cocoapods/generator/copy_resources_script.rb +2 -1
  26. data/lib/cocoapods/generator/copy_xcframework_script.rb +52 -70
  27. data/lib/cocoapods/generator/embed_frameworks_script.rb +4 -3
  28. data/lib/cocoapods/generator/info_plist_file.rb +1 -1
  29. data/lib/cocoapods/generator/script_phase_constants.rb +1 -0
  30. data/lib/cocoapods/installer/analyzer/analysis_result.rb +3 -3
  31. data/lib/cocoapods/installer/analyzer/pod_variant.rb +1 -1
  32. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +38 -10
  33. data/lib/cocoapods/installer/analyzer.rb +21 -13
  34. data/lib/cocoapods/installer/base_install_hooks_context.rb +19 -4
  35. data/lib/cocoapods/installer/installation_options.rb +11 -0
  36. data/lib/cocoapods/installer/pod_source_downloader.rb +159 -0
  37. data/lib/cocoapods/installer/pod_source_installer.rb +10 -36
  38. data/lib/cocoapods/installer/podfile_validator.rb +2 -2
  39. data/lib/cocoapods/installer/pre_integrate_hooks_context.rb +9 -0
  40. data/lib/cocoapods/installer/project_cache/project_cache_analyzer.rb +14 -7
  41. data/lib/cocoapods/installer/project_cache/project_installation_cache.rb +15 -2
  42. data/lib/cocoapods/installer/project_cache/target_cache_key.rb +48 -7
  43. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +150 -9
  44. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +11 -3
  45. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +62 -9
  46. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +6 -19
  47. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +86 -59
  48. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +48 -6
  49. data/lib/cocoapods/installer/xcode/pods_project_generator/project_generator.rb +3 -1
  50. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +2 -2
  51. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +8 -5
  52. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +9 -3
  53. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +37 -2
  54. data/lib/cocoapods/installer/xcode/target_validator.rb +1 -1
  55. data/lib/cocoapods/installer.rb +150 -34
  56. data/lib/cocoapods/native_target_extension.rb +1 -1
  57. data/lib/cocoapods/open-uri.rb +1 -1
  58. data/lib/cocoapods/project.rb +8 -8
  59. data/lib/cocoapods/resolver/resolver_specification.rb +1 -1
  60. data/lib/cocoapods/resolver.rb +7 -7
  61. data/lib/cocoapods/sandbox/file_accessor.rb +67 -11
  62. data/lib/cocoapods/sandbox/headers_store.rb +3 -1
  63. data/lib/cocoapods/sandbox/path_list.rb +2 -2
  64. data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +1 -1
  65. data/lib/cocoapods/sandbox.rb +48 -12
  66. data/lib/cocoapods/sources_manager.rb +18 -9
  67. data/lib/cocoapods/target/aggregate_target.rb +23 -1
  68. data/lib/cocoapods/target/build_settings.rb +67 -22
  69. data/lib/cocoapods/target/pod_target.rb +49 -24
  70. data/lib/cocoapods/target.rb +1 -1
  71. data/lib/cocoapods/user_interface.rb +6 -2
  72. data/lib/cocoapods/validator.rb +58 -22
  73. data/lib/cocoapods/version_metadata.rb +1 -1
  74. data/lib/cocoapods/xcode/xcframework/xcframework_slice.rb +22 -7
  75. data/lib/cocoapods/xcode/xcframework.rb +9 -4
  76. data/lib/cocoapods.rb +2 -0
  77. metadata +35 -27
@@ -0,0 +1,159 @@
1
+
2
+ module Pod
3
+ class Installer
4
+ # Controller class responsible for downloading the activated specifications
5
+ # of a single Pod.
6
+ #
7
+ # @note This class needs to consider all the activated specs of a Pod.
8
+ #
9
+ class PodSourceDownloader
10
+ UNENCRYPTED_PROTOCOLS = %w(http git).freeze
11
+
12
+ # @return [Sandbox] The installation target.
13
+ #
14
+ attr_reader :sandbox
15
+
16
+ # @return [Podfile] the podfile that should be integrated with the user
17
+ # projects.
18
+ #
19
+ attr_reader :podfile
20
+
21
+ # @return [Hash{Symbol=>Array}] The specifications that need to be
22
+ # installed grouped by platform.
23
+ #
24
+ attr_reader :specs_by_platform
25
+
26
+ # @return [Boolean] Whether the installer is allowed to touch the cache.
27
+ #
28
+ attr_reader :can_cache
29
+ alias can_cache? can_cache
30
+
31
+ # Initialize a new instance
32
+ #
33
+ # @param [Sandbox] sandbox @see #sandbox
34
+ # @param [Podfile] podfile @see #podfile
35
+ # @param [Hash{Symbol=>Array}] specs_by_platform @see #specs_by_platform
36
+ # @param [Boolean] can_cache @see #can_cache
37
+ #
38
+ def initialize(sandbox, podfile, specs_by_platform, can_cache: true)
39
+ @sandbox = sandbox
40
+ @podfile = podfile
41
+ @specs_by_platform = specs_by_platform
42
+ @can_cache = can_cache
43
+ end
44
+
45
+ # @return [String] A string suitable for debugging.
46
+ #
47
+ def inspect
48
+ "<#{self.class} sandbox=#{sandbox.root} pod=#{root_spec.name}"
49
+ end
50
+
51
+ # @return [String] The name of the pod this downloader is downloading.
52
+ #
53
+ def name
54
+ root_spec.name
55
+ end
56
+
57
+ #-----------------------------------------------------------------------#
58
+
59
+ public
60
+
61
+ # @!group Downloading
62
+
63
+ # Creates the target in the Pods project and the relative support files.
64
+ #
65
+ # @return [void]
66
+ #
67
+ def download!
68
+ verify_source_is_secure(root_spec)
69
+ download_result = Downloader.download(download_request, root, :can_cache => can_cache?)
70
+
71
+ if (specific_source = download_result.checkout_options) && specific_source != root_spec.source
72
+ sandbox.store_checkout_source(root_spec.name, specific_source)
73
+ end
74
+
75
+ sandbox.store_downloaded_pod(root_spec.name)
76
+ end
77
+
78
+ #-----------------------------------------------------------------------#
79
+
80
+ private
81
+
82
+ # @!group Download Steps
83
+
84
+ # Verify the source of the spec is secure, which is used to show a warning to the user if that isn't the case
85
+ # This method doesn't verify all protocols, but currently only prohibits unencrypted 'http://' and 'git://''
86
+ # connections.
87
+ #
88
+ # @return [void]
89
+ #
90
+ def verify_source_is_secure(root_spec)
91
+ return if root_spec.source.nil? || (root_spec.source[:http].nil? && root_spec.source[:git].nil?)
92
+ source = if !root_spec.source[:http].nil?
93
+ URI(root_spec.source[:http].to_s)
94
+ elsif !root_spec.source[:git].nil?
95
+ git_source = root_spec.source[:git].to_s
96
+ return unless git_source =~ /^#{URI::DEFAULT_PARSER.make_regexp}$/
97
+ URI(git_source)
98
+ end
99
+ if UNENCRYPTED_PROTOCOLS.include?(source.scheme) && source.host != 'localhost'
100
+ UI.warn "'#{root_spec.name}' uses the unencrypted '#{source.scheme}' protocol to transfer the Pod. " \
101
+ 'Please be sure you\'re in a safe network with only trusted hosts. ' \
102
+ 'Otherwise, please reach out to the library author to notify them of this security issue.'
103
+ end
104
+ end
105
+
106
+ def download_request
107
+ Downloader::Request.new(
108
+ :spec => root_spec,
109
+ :released => released?,
110
+ )
111
+ end
112
+
113
+ #-----------------------------------------------------------------------#
114
+
115
+ private
116
+
117
+ # @!group Convenience methods.
118
+
119
+ # @return [Array<Specifications>] the specification of the Pod used in
120
+ # this installation.
121
+ #
122
+ def specs
123
+ specs_by_platform.values.flatten
124
+ end
125
+
126
+ # @return [Specification] the root specification of the Pod.
127
+ #
128
+ def root_spec
129
+ specs.first.root
130
+ end
131
+
132
+ # @return [Pathname] the folder where the source of the Pod is located.
133
+ #
134
+ def root
135
+ sandbox.pod_dir(root_spec.name)
136
+ end
137
+
138
+ # @return [Boolean] whether the source has been pre downloaded in the
139
+ # resolution process to retrieve its podspec.
140
+ #
141
+ def predownloaded?
142
+ sandbox.predownloaded_pods.include?(root_spec.name)
143
+ end
144
+
145
+ # @return [Boolean] whether the pod uses the local option and thus
146
+ # CocoaPods should not interfere with the files of the user.
147
+ #
148
+ def local?
149
+ sandbox.local?(root_spec.name)
150
+ end
151
+
152
+ def released?
153
+ sandbox.specification(root_spec.name) != root_spec
154
+ end
155
+
156
+ #-----------------------------------------------------------------------#
157
+ end
158
+ end
159
+ end
@@ -8,8 +8,6 @@ module Pod
8
8
  # @note This class needs to consider all the activated specs of a Pod.
9
9
  #
10
10
  class PodSourceInstaller
11
- UNENCRYPTED_PROTOCOLS = %w(http git).freeze
12
-
13
11
  # @return [Sandbox] The installation target.
14
12
  #
15
13
  attr_reader :sandbox
@@ -114,43 +112,12 @@ module Pod
114
112
  # @return [void]
115
113
  #
116
114
  def download_source
117
- verify_source_is_secure(root_spec)
118
- download_result = Downloader.download(download_request, root, :can_cache => can_cache?)
119
-
120
- if (specific_source = download_result.checkout_options) && specific_source != root_spec.source
121
- sandbox.store_checkout_source(root_spec.name, specific_source)
115
+ unless downloaded?
116
+ downloader = PodSourceDownloader.new(sandbox, podfile, specs_by_platform, :can_cache => can_cache?)
117
+ downloader.download!
122
118
  end
123
119
  end
124
120
 
125
- # Verify the source of the spec is secure, which is used to show a warning to the user if that isn't the case
126
- # This method doesn't verify all protocols, but currently only prohibits unencrypted 'http://' and 'git://''
127
- # connections.
128
- #
129
- # @return [void]
130
- #
131
- def verify_source_is_secure(root_spec)
132
- return if root_spec.source.nil? || (root_spec.source[:http].nil? && root_spec.source[:git].nil?)
133
- source = if !root_spec.source[:http].nil?
134
- URI(root_spec.source[:http].to_s)
135
- elsif !root_spec.source[:git].nil?
136
- git_source = root_spec.source[:git].to_s
137
- return unless git_source =~ /^#{URI.regexp}$/
138
- URI(git_source)
139
- end
140
- if UNENCRYPTED_PROTOCOLS.include?(source.scheme) && source.host != 'localhost'
141
- UI.warn "'#{root_spec.name}' uses the unencrypted '#{source.scheme}' protocol to transfer the Pod. " \
142
- 'Please be sure you\'re in a safe network with only trusted hosts. ' \
143
- 'Otherwise, please reach out to the library author to notify them of this security issue.'
144
- end
145
- end
146
-
147
- def download_request
148
- Downloader::Request.new(
149
- :spec => root_spec,
150
- :released => released?,
151
- )
152
- end
153
-
154
121
  #-----------------------------------------------------------------------#
155
122
 
156
123
  private
@@ -186,6 +153,13 @@ module Pod
186
153
  sandbox.pod_dir(root_spec.name)
187
154
  end
188
155
 
156
+ # @return [Boolean] whether the source has already been downloaded prior
157
+ # to the installation process.
158
+ #
159
+ def downloaded?
160
+ sandbox.downloaded_pods.include?(root_spec.name)
161
+ end
162
+
189
163
  # @return [Boolean] whether the source has been pre downloaded in the
190
164
  # resolution process to retrieve its podspec.
191
165
  #
@@ -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,7 +34,11 @@ module Pod
34
34
  #
35
35
  attr_reader :aggregate_targets
36
36
 
37
- # @return [Bool] Flag indicating if we want to ignore the cache and force a clean installation.
37
+ # @return [Hash<Symbol, Object>] Hash of installation options.
38
+ #
39
+ attr_reader :installation_options
40
+
41
+ # @return [Boolean] Flag indicating if we want to ignore the cache and force a clean installation.
38
42
  #
39
43
  attr_reader :clean_install
40
44
 
@@ -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
50
- # @param [Bool] clean_install @see #clean_install
54
+ # @param [Hash<Symbol, Object>] installation_options @see #installation_options
55
+ # @param [Boolean] 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
@@ -132,10 +139,10 @@ module Pod
132
139
  when PodTarget
133
140
  local = sandbox.local?(target.pod_name)
134
141
  checkout_options = sandbox.checkout_sources[target.pod_name]
135
- [label, TargetCacheKey.from_pod_target(sandbox, target, :is_local_pod => local,
136
- :checkout_options => checkout_options)]
142
+ [label, TargetCacheKey.from_pod_target(sandbox, target_by_label, target,
143
+ :is_local_pod => local, :checkout_options => checkout_options)]
137
144
  when AggregateTarget
138
- [label, TargetCacheKey.from_aggregate_target(sandbox, target)]
145
+ [label, TargetCacheKey.from_aggregate_target(sandbox, target_by_label, target)]
139
146
  else
140
147
  raise "[BUG] Unknown target type #{target}"
141
148
  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
@@ -58,6 +58,10 @@ module Pod
58
58
  other_files = other.key_hash['FILES']
59
59
  return :project if this_files != other_files
60
60
 
61
+ this_resources = key_hash['RESOURCES']
62
+ other_resources = other.key_hash['RESOURCES']
63
+ return :project if this_resources != other_resources
64
+
61
65
  this_build_settings = key_hash['BUILD_SETTINGS_CHECKSUM']
62
66
  other_build_settings = other.key_hash['BUILD_SETTINGS_CHECKSUM']
63
67
  return :project if this_build_settings != other_build_settings
@@ -98,6 +102,9 @@ module Pod
98
102
  if specs = cache_hash['SPECS']
99
103
  cache_hash['SPECS'] = specs.sort_by(&:downcase)
100
104
  end
105
+ if resources = cache_hash['RESOURCES']
106
+ cache_hash['RESOURCES'] = resources.sort_by(&:downcase)
107
+ end
101
108
  type = cache_hash['CHECKSUM'] ? :pod_target : :aggregate
102
109
  TargetCacheKey.new(sandbox, type, cache_hash)
103
110
  end
@@ -106,10 +113,13 @@ module Pod
106
113
  #
107
114
  # @param [Sandbox] sandbox The sandbox to use to construct a TargetCacheKey object.
108
115
  #
116
+ # @param [Hash] target_by_label
117
+ # Maps target names to PodTarget objects.
118
+ #
109
119
  # @param [PodTarget] pod_target
110
120
  # The pod target used to construct a TargetCacheKey object.
111
121
  #
112
- # @param [Bool] is_local_pod
122
+ # @param [Boolean] is_local_pod
113
123
  # Used to also include its local files in the cache key.
114
124
  #
115
125
  # @param [Hash] checkout_options
@@ -117,7 +127,7 @@ module Pod
117
127
  #
118
128
  # @return [TargetCacheKey]
119
129
  #
120
- def self.from_pod_target(sandbox, pod_target, is_local_pod: false, checkout_options: nil)
130
+ def self.from_pod_target(sandbox, target_by_label, pod_target, is_local_pod: false, checkout_options: nil)
121
131
  build_settings = {}
122
132
  build_settings[pod_target.label.to_s] = Hash[pod_target.build_settings.map do |k, v|
123
133
  [k, Digest::MD5.hexdigest(v.xcconfig.to_s)]
@@ -129,6 +139,20 @@ module Pod
129
139
  build_settings[name] = Hash[settings_by_config.map { |k, v| [k, Digest::MD5.hexdigest(v.xcconfig.to_s)] }]
130
140
  end
131
141
 
142
+ # find resources from upstream dependencies that will be named in the `{name}-resources.sh` script
143
+ resource_dependencies = []
144
+ pod_target.dependencies.each do |name|
145
+ next unless target_by_label[name]
146
+
147
+ upstream = target_by_label[name]
148
+
149
+ # pod target
150
+ resource_dependencies.append(upstream.resource_paths.values.flatten) if upstream.respond_to?(:resource_paths)
151
+
152
+ # aggregate target
153
+ resource_dependencies.append(upstream.resource_paths_by_config.values.flatten) if upstream.respond_to?(:resource_paths_by_config)
154
+ end
155
+
132
156
  contents = {
133
157
  'CHECKSUM' => pod_target.root_spec.checksum,
134
158
  'SPECS' => pod_target.specs.map(&:to_s).sort_by(&:downcase),
@@ -136,10 +160,11 @@ module Pod
136
160
  'PROJECT_NAME' => pod_target.project_name,
137
161
  }
138
162
  if is_local_pod
139
- relative_file_paths = pod_target.all_files.map { |f| Pathname.new(f).relative_path_from(sandbox.root).to_s }
163
+ relative_file_paths = pod_target.all_files.map { |f| f.relative_path_from(sandbox.root).to_s }
140
164
  contents['FILES'] = relative_file_paths.sort_by(&:downcase)
141
165
  end
142
166
  contents['CHECKOUT_OPTIONS'] = checkout_options if checkout_options
167
+ contents['RESOURCES'] = resource_dependencies.flatten.uniq.sort_by(&:downcase) if resource_dependencies.any?
143
168
  TargetCacheKey.new(sandbox, :pod_target, contents)
144
169
  end
145
170
 
@@ -152,18 +177,34 @@ module Pod
152
177
  #
153
178
  # @return [TargetCacheKey]
154
179
  #
155
- def self.from_aggregate_target(sandbox, aggregate_target)
180
+ def self.from_aggregate_target(sandbox, target_by_label, aggregate_target)
156
181
  build_settings = {}
157
182
  aggregate_target.user_build_configurations.keys.each do |configuration|
158
183
  build_settings[configuration] = Digest::MD5.hexdigest(aggregate_target.build_settings(configuration).xcconfig.to_s)
159
184
  end
160
185
 
186
+ # find resources from upstream dependencies that will be named in the `{name}-resources.sh` script
187
+ resource_dependencies = []
188
+ aggregate_target.pod_targets.each do |name|
189
+ upstream = target_by_label[name]
190
+
191
+ # pod target
192
+ resource_dependencies.append(upstream.resource_paths.values.flatten) if upstream.respond_to?(:resource_paths)
193
+
194
+ # aggregate target
195
+ resource_dependencies.append(upstream.resource_paths_by_config.values.flatten) if upstream.respond_to?(:resource_paths_by_config)
196
+ end
197
+
161
198
  contents = {
162
199
  'BUILD_SETTINGS_CHECKSUM' => build_settings,
163
200
  }
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)
201
+ if aggregate_target.includes_resources? || aggregate_target.includes_on_demand_resources?
202
+ relative_resource_file_paths = aggregate_target.resource_paths_by_config.values.flatten.uniq
203
+ relative_on_demand_resource_file_paths = aggregate_target.on_demand_resources.map do |res|
204
+ res.relative_path_from(sandbox.project_path.dirname).to_s
205
+ end
206
+ contents['FILES'] = (relative_resource_file_paths + relative_on_demand_resource_file_paths).sort_by(&:downcase)
207
+ contents['RESOURCES'] = resource_dependencies.flatten.uniq.sort_by(&:downcase) if resource_dependencies.any?
167
208
  end
168
209
  TargetCacheKey.new(sandbox, :aggregate, contents)
169
210
  end