cocoapods 1.4.0 → 1.5.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +149 -0
  3. data/lib/cocoapods.rb +1 -0
  4. data/lib/cocoapods/command/outdated.rb +2 -2
  5. data/lib/cocoapods/command/repo/push.rb +5 -0
  6. data/lib/cocoapods/command/update.rb +21 -5
  7. data/lib/cocoapods/gem_version.rb +1 -1
  8. data/lib/cocoapods/generator/acknowledgements.rb +6 -3
  9. data/lib/cocoapods/generator/constant.rb +19 -0
  10. data/lib/cocoapods/generator/copy_resources_script.rb +15 -3
  11. data/lib/cocoapods/generator/embed_frameworks_script.rb +11 -2
  12. data/lib/cocoapods/generator/module_map.rb +56 -5
  13. data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +19 -13
  14. data/lib/cocoapods/generator/xcconfig/pod_xcconfig.rb +4 -6
  15. data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +25 -2
  16. data/lib/cocoapods/installer.rb +17 -8
  17. data/lib/cocoapods/installer/analyzer.rb +48 -38
  18. data/lib/cocoapods/installer/analyzer/analysis_result.rb +11 -0
  19. data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +7 -6
  20. data/lib/cocoapods/installer/analyzer/pod_variant.rb +8 -8
  21. data/lib/cocoapods/installer/analyzer/pod_variant_set.rb +3 -3
  22. data/lib/cocoapods/installer/analyzer/podfile_dependency_cache.rb +54 -0
  23. data/lib/cocoapods/installer/analyzer/specs_state.rb +16 -16
  24. data/lib/cocoapods/installer/analyzer/target_inspector.rb +7 -11
  25. data/lib/cocoapods/installer/pod_source_installer.rb +2 -3
  26. data/lib/cocoapods/installer/podfile_validator.rb +11 -10
  27. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +72 -28
  28. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +8 -2
  29. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +9 -0
  30. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +32 -24
  31. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +97 -54
  32. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +9 -11
  33. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +4 -9
  34. data/lib/cocoapods/installer/xcode/target_validator.rb +32 -18
  35. data/lib/cocoapods/project.rb +32 -17
  36. data/lib/cocoapods/resolver.rb +59 -31
  37. data/lib/cocoapods/resolver/lazy_specification.rb +28 -18
  38. data/lib/cocoapods/sandbox.rb +2 -4
  39. data/lib/cocoapods/sandbox/file_accessor.rb +25 -9
  40. data/lib/cocoapods/sandbox/headers_store.rb +31 -6
  41. data/lib/cocoapods/sandbox/path_list.rb +36 -46
  42. data/lib/cocoapods/target.rb +7 -4
  43. data/lib/cocoapods/target/aggregate_target.rb +10 -8
  44. data/lib/cocoapods/target/pod_target.rb +87 -20
  45. data/lib/cocoapods/user_interface/error_report.rb +1 -1
  46. data/lib/cocoapods/user_interface/inspector_reporter.rb +4 -4
  47. data/lib/cocoapods/validator.rb +40 -29
  48. metadata +11 -9
@@ -11,6 +11,11 @@ module Pod
11
11
  #
12
12
  attr_accessor :specs_by_target
13
13
 
14
+ # @return [Hash{Source => Array<Specification>}] the
15
+ # specifications grouped by spec repo source.
16
+ #
17
+ attr_accessor :specs_by_source
18
+
14
19
  # @return [Array<Specification>] the specifications of the resolved
15
20
  # version of Pods that should be installed.
16
21
  #
@@ -28,8 +33,14 @@ module Pod
28
33
 
29
34
  # @return [Hash{TargetDefinition => Array<TargetInspectionResult>}] the
30
35
  # results of inspecting the user targets
36
+ #
31
37
  attr_accessor :target_inspections
32
38
 
39
+ # @return [PodfileDependencyCache] the cache of all dependencies in the
40
+ # podfile.
41
+ #
42
+ attr_accessor :podfile_dependency_cache
43
+
33
44
  # @return [Hash{String=>Symbol}] A hash representing all the user build
34
45
  # configurations across all integration targets. Each key
35
46
  # corresponds to the name of a configuration and its value to
@@ -33,10 +33,9 @@ module Pod
33
33
  dependency_graph = Molinillo::DependencyGraph.new
34
34
 
35
35
  if lockfile
36
- explicit_dependencies = lockfile.to_hash['DEPENDENCIES'] || []
37
- explicit_dependencies.each do |string|
38
- dependency = Dependency.new(string)
39
- dependency_graph.add_vertex(dependency.name, nil, true)
36
+ explicit_dependencies = lockfile.dependencies
37
+ explicit_dependencies.each do |dependency|
38
+ dependency_graph.add_vertex(dependency.name, dependency, true)
40
39
  end
41
40
 
42
41
  pods = lockfile.to_hash['PODS'] || []
@@ -46,7 +45,7 @@ module Pod
46
45
 
47
46
  pods_to_update = pods_to_update.flat_map do |u|
48
47
  root_name = Specification.root_name(u).downcase
49
- dependency_graph.vertices.keys.select { |n| Specification.root_name(n).downcase == root_name }
48
+ dependency_graph.vertices.each_key.select { |n| Specification.root_name(n).downcase == root_name }
50
49
  end
51
50
 
52
51
  pods_to_update.each do |u|
@@ -73,7 +72,9 @@ module Pod
73
72
  if pods_to_unlock.include?(dependency.root_name)
74
73
  dependency = Dependency.new(dependency.name)
75
74
  end
76
- dependency_graph.add_child_vertex(dependency.name, parents.empty? ? dependency : nil, parents, nil)
75
+ vertex = dependency_graph.add_child_vertex(dependency.name, nil, parents, nil)
76
+ dependency = vertex.payload.merge(dependency) if vertex.payload
77
+ vertex.payload = dependency
77
78
  dependency
78
79
  end
79
80
 
@@ -5,19 +5,19 @@ module Pod
5
5
  class PodVariant
6
6
  # @return [Array<Specification>] the spec and subspecs for the target
7
7
  #
8
- attr_accessor :specs
8
+ attr_reader :specs
9
9
 
10
10
  # @return [Array<Specification>] the test specs for the target
11
11
  #
12
- attr_accessor :test_specs
12
+ attr_reader :test_specs
13
13
 
14
14
  # @return [Platform] the platform
15
15
  #
16
- attr_accessor :platform
16
+ attr_reader :platform
17
17
 
18
18
  # @return [Bool] whether this pod should be built as framework
19
19
  #
20
- attr_accessor :requires_frameworks
20
+ attr_reader :requires_frameworks
21
21
  alias_method :requires_frameworks?, :requires_frameworks
22
22
 
23
23
  # @return [Specification] the root specification
@@ -34,10 +34,10 @@ module Pod
34
34
  # @param [Bool] requires_frameworks @see #requires_frameworks?
35
35
  #
36
36
  def initialize(specs, test_specs, platform, requires_frameworks = false)
37
- self.specs = specs
38
- self.test_specs = test_specs
39
- self.platform = platform
40
- self.requires_frameworks = requires_frameworks
37
+ @specs = specs
38
+ @test_specs = test_specs
39
+ @platform = platform
40
+ @requires_frameworks = requires_frameworks
41
41
  end
42
42
 
43
43
  # @note Test specs are intentionally not included as part of the equality for pod variants since a
@@ -5,16 +5,16 @@ module Pod
5
5
  class Analyzer
6
6
  # Collects all {PodVariant}.
7
7
  class PodVariantSet
8
- # @return [Array<PodVariant>] the different variants.
8
+ # @return [Array<PodVariant>] the different variants within this set.
9
9
  #
10
- attr_accessor :variants
10
+ attr_reader :variants
11
11
 
12
12
  # Initialize a new instance.
13
13
  #
14
14
  # @param [Array<PodVariant>] variants @see #variants
15
15
  #
16
16
  def initialize(variants)
17
- self.variants = variants
17
+ @variants = variants
18
18
  end
19
19
 
20
20
  # Describes what makes each {PodVariant} distinct among the others.
@@ -0,0 +1,54 @@
1
+ module Pod
2
+ class Installer
3
+ class Analyzer
4
+ # Caches podfile & target definition dependencies, so they do not need to be re-computed
5
+ # from the internal hash on each access
6
+ #
7
+ class PodfileDependencyCache
8
+ # @return [Array<Pod::Dependency>]
9
+ # All the dependencies in the podfile
10
+ #
11
+ attr_reader :podfile_dependencies
12
+
13
+ def initialize(podfile_dependencies, dependencies_by_target_definition)
14
+ @podfile_dependencies = podfile_dependencies
15
+ @dependencies_by_target_definition = dependencies_by_target_definition
16
+ end
17
+
18
+ # Returns the dependencies for the given target definition
19
+ #
20
+ def target_definition_dependencies(target_definition)
21
+ @dependencies_by_target_definition[target_definition] ||
22
+ raise(ArgumentError, "dependencies for #{target_definition.inspect} do not exist in the cache")
23
+ end
24
+
25
+ # Returns a list of all of the target definitions in the Podfile
26
+ #
27
+ def target_definition_list
28
+ @dependencies_by_target_definition.keys
29
+ end
30
+
31
+ # Creates a {PodfileDependencyCache} from the given {Podfile}
32
+ #
33
+ # @param [Podfile] podfile
34
+ # The {Podfile} from which dependencies should be cached
35
+ #
36
+ # @return [PodfileDependencyCache]
37
+ # A warmed, immutable cache of all the dependencies in the {Podfile}
38
+ #
39
+ def self.from_podfile(podfile)
40
+ podfile_dependencies = []
41
+ dependencies_by_target_definition = {}
42
+ podfile.target_definition_list.each do |target_definition|
43
+ deps = target_definition.dependencies.freeze
44
+ podfile_dependencies.concat deps
45
+ dependencies_by_target_definition[target_definition] = deps
46
+ end
47
+ podfile_dependencies.uniq!
48
+
49
+ new(podfile_dependencies.freeze, dependencies_by_target_definition.freeze)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -12,6 +12,22 @@ module Pod
12
12
  # subspecs are added instead of the name of the Pods.
13
13
  #
14
14
  class SpecsState
15
+ # @return [Set<String>] the names of the pods that were added.
16
+ #
17
+ attr_reader :added
18
+
19
+ # @return [Set<String>] the names of the pods that were changed.
20
+ #
21
+ attr_reader :changed
22
+
23
+ # @return [Set<String>] the names of the pods that were deleted.
24
+ #
25
+ attr_reader :deleted
26
+
27
+ # @return [Set<String>] the names of the pods that were unchanged.
28
+ #
29
+ attr_reader :unchanged
30
+
15
31
  # Initialize a new instance
16
32
  #
17
33
  # @param [Hash{Symbol=>String}] pods_by_state
@@ -38,22 +54,6 @@ module Pod
38
54
  end
39
55
  end
40
56
 
41
- # @return [Set<String>] the names of the pods that were added.
42
- #
43
- attr_accessor :added
44
-
45
- # @return [Set<String>] the names of the pods that were changed.
46
- #
47
- attr_accessor :changed
48
-
49
- # @return [Set<String>] the names of the pods that were deleted.
50
- #
51
- attr_accessor :deleted
52
-
53
- # @return [Set<String>] the names of the pods that were unchanged.
54
- #
55
- attr_accessor :unchanged
56
-
57
57
  # Displays the state of each pod.
58
58
  #
59
59
  # @return [void]
@@ -8,11 +8,12 @@ module Pod
8
8
 
9
9
  # @return [TargetDefinition] the target definition to inspect
10
10
  #
11
- attr_accessor :target_definition
11
+ attr_reader :target_definition
12
12
 
13
13
  # @return [Pathname] the root of the CocoaPods installation where the
14
14
  # Podfile is located
15
- attr_accessor :installation_root
15
+ #
16
+ attr_reader :installation_root
16
17
 
17
18
  # Initialize a new instance
18
19
  #
@@ -33,7 +34,7 @@ module Pod
33
34
  #
34
35
  # @return [TargetInspectionResult]
35
36
  #
36
- def compute_results
37
+ def compute_results(user_project)
37
38
  raise ArgumentError, 'Cannot compute results without a user project set' unless user_project
38
39
 
39
40
  targets = compute_targets(user_project)
@@ -81,11 +82,6 @@ module Pod
81
82
  path
82
83
  end
83
84
 
84
- # @return [Xcodeproj::Project] the user's Xcode project, used for target
85
- # inspection
86
- #
87
- attr_accessor :user_project
88
-
89
85
  #-----------------------------------------------------------------------#
90
86
 
91
87
  private
@@ -115,7 +111,7 @@ module Pod
115
111
  [target]
116
112
  end
117
113
 
118
- # @param [Array<PBXNativeTarget] the user's targets of the project of
114
+ # @param [Array<PBXNativeTarget] user_targets the user's targets of the project of
119
115
  # #target_definition which needs to be integrated
120
116
  #
121
117
  # @return [Hash{String=>Symbol}] A hash representing the user build
@@ -132,7 +128,7 @@ module Pod
132
128
  end
133
129
  end
134
130
 
135
- # @param [Array<PBXNativeTarget] the user's targets of the project of
131
+ # @param [Array<PBXNativeTarget] user_targets the user's targets of the project of
136
132
  # #target_definition which needs to be integrated
137
133
  #
138
134
  # @return [Platform] The platform of the user's targets
@@ -171,7 +167,7 @@ module Pod
171
167
 
172
168
  # Computes the architectures relevant for the user's targets.
173
169
  #
174
- # @param [Array<PBXNativeTarget] the user's targets of the project of
170
+ # @param [Array<PBXNativeTarget] user_targets the user's targets of the project of
175
171
  # #target_definition which needs to be integrated
176
172
  #
177
173
  # @return [Array<String>]
@@ -132,9 +132,8 @@ module Pod
132
132
  #
133
133
  def verify_source_is_secure(root_spec)
134
134
  return if root_spec.source.nil? || root_spec.source[:http].nil?
135
- http_source = root_spec.source[:http]
136
- return if http_source.downcase.start_with?('https://')
137
-
135
+ http_source = URI(root_spec.source[:http])
136
+ return if http_source.scheme == 'https' || http_source.scheme == 'file'
138
137
  UI.warn "'#{root_spec.name}' uses the unencrypted http protocol to transfer the Pod. " \
139
138
  'Please be sure you\'re in a safe network with only trusted hosts in there. ' \
140
139
  'Please reach out to the library author to notify them of this security issue.'
@@ -17,11 +17,16 @@ module Pod
17
17
  attr_reader :warnings
18
18
 
19
19
  # Initialize a new instance
20
+ #
20
21
  # @param [Podfile] podfile
21
22
  # The podfile to validate
22
23
  #
23
- def initialize(podfile)
24
+ # @param [Analyzer::PodfileDependencyCache] podfile_dependency_cache
25
+ # An (optional) cache of all the dependencies in the podfile
26
+ #
27
+ def initialize(podfile, podfile_dependency_cache = Analyzer::PodfileDependencyCache.from_podfile(podfile))
24
28
  @podfile = podfile
29
+ @podfile_dependency_cache = podfile_dependency_cache
25
30
  @errors = []
26
31
  @warnings = []
27
32
  @validated = false
@@ -67,11 +72,7 @@ module Pod
67
72
  end
68
73
 
69
74
  def validate_pod_directives
70
- dependencies = podfile.target_definitions.flat_map do |_, target|
71
- target.dependencies
72
- end.uniq
73
-
74
- dependencies.each do |dependency|
75
+ @podfile_dependency_cache.podfile_dependencies.each do |dependency|
75
76
  validate_conflicting_external_sources!(dependency)
76
77
  end
77
78
  end
@@ -106,7 +107,7 @@ module Pod
106
107
  # @return [void]
107
108
  #
108
109
  def validate_dependencies_are_present!
109
- if podfile.target_definitions.values.all?(&:empty?)
110
+ if @podfile_dependency_cache.target_definition_list.all?(&:empty?)
110
111
  add_warning 'The Podfile does not contain any dependencies.'
111
112
  end
112
113
  end
@@ -116,8 +117,8 @@ module Pod
116
117
  # target, or be inherited by a target where `inheritance == complete`.
117
118
  #
118
119
  def validate_no_abstract_only_pods!
119
- all_dependencies = podfile.dependencies
120
- concrete_dependencies = podfile.target_definition_list.reject(&:abstract?).flat_map(&:dependencies).uniq
120
+ all_dependencies = @podfile_dependency_cache.podfile_dependencies
121
+ concrete_dependencies = @podfile_dependency_cache.target_definition_list.reject(&:abstract?).flat_map { |td| @podfile_dependency_cache.target_definition_dependencies(td) }
121
122
  abstract_only_dependencies = all_dependencies - concrete_dependencies
122
123
  abstract_only_dependencies.each do |dep|
123
124
  add_error "The dependency `#{dep}` is not used in any concrete target."
@@ -125,7 +126,7 @@ module Pod
125
126
  end
126
127
 
127
128
  def validate_no_duplicate_targets!
128
- podfile.target_definition_list.group_by { |td| [td.name, td.user_project_path] }.
129
+ @podfile_dependency_cache.target_definition_list.group_by { |td| [td.name, td.user_project_path] }.
129
130
  each do |(name, project), definitions|
130
131
  next unless definitions.size > 1
131
132
  error = "The target `#{name}` is declared twice"
@@ -40,6 +40,10 @@ module Pod
40
40
  #
41
41
  COPY_PODS_RESOURCES_PHASE_NAME = 'Copy Pods Resources'.freeze
42
42
 
43
+ # @return [Integer] the maximum number of input and output paths to use for a script phase
44
+ #
45
+ MAX_INPUT_OUTPUT_PATHS = 1000
46
+
43
47
  # @return [AggregateTarget] the target that should be integrated.
44
48
  #
45
49
  attr_reader :target
@@ -71,15 +75,11 @@ module Pod
71
75
  #
72
76
  # @return [void]
73
77
  #
74
- def add_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths = [], output_paths = [])
78
+ def create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths = [], output_paths = [])
75
79
  phase = TargetIntegrator.create_or_update_build_phase(native_target, BUILD_PHASE_PREFIX + EMBED_FRAMEWORK_PHASE_NAME)
76
80
  phase.shell_script = %("#{script_path}"\n)
77
- unless input_paths.empty?
78
- phase.input_paths = input_paths
79
- end
80
- unless output_paths.empty?
81
- phase.output_paths = output_paths
82
- end
81
+ phase.input_paths = input_paths
82
+ phase.output_paths = output_paths
83
83
  end
84
84
 
85
85
  # Delete a 'Embed Pods Frameworks' Copy Files Build Phase if present
@@ -111,16 +111,23 @@ module Pod
111
111
  #
112
112
  # @return [void]
113
113
  #
114
- def add_copy_resources_script_phase_to_target(native_target, script_path, input_paths = [], output_paths = [])
114
+ def create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths = [], output_paths = [])
115
115
  phase_name = COPY_PODS_RESOURCES_PHASE_NAME
116
116
  phase = TargetIntegrator.create_or_update_build_phase(native_target, BUILD_PHASE_PREFIX + phase_name)
117
117
  phase.shell_script = %("#{script_path}"\n)
118
- unless input_paths.empty?
119
- phase.input_paths = input_paths
120
- end
121
- unless output_paths.empty?
122
- phase.output_paths = output_paths
123
- end
118
+ phase.input_paths = input_paths
119
+ phase.output_paths = output_paths
120
+ end
121
+
122
+ # Delete a 'Copy Pods Resources' script phase if present
123
+ #
124
+ # @param [PBXNativeTarget] native_target
125
+ # The native target to remove the script phase from.
126
+ #
127
+ def remove_copy_resources_script_phase_from_target(native_target)
128
+ build_phase = native_target.shell_script_build_phases.find { |bp| bp.name && bp.name.end_with?(COPY_PODS_RESOURCES_PHASE_NAME) }
129
+ return unless build_phase.present?
130
+ native_target.build_phases.delete(build_phase)
124
131
  end
125
132
 
126
133
  # Creates or update a shell script build phase for the given target.
@@ -191,9 +198,31 @@ module Pod
191
198
  end
192
199
  end
193
200
 
201
+ # Script phases can have a limited number of input and output paths due to each one being exported to `env`.
202
+ # A large number can cause a build failure because of limitations in `env`. See issue
203
+ # https://github.com/CocoaPods/CocoaPods/issues/7362.
204
+ #
205
+ # @param [Array<String>] input_paths
206
+ # The input paths to trim.
207
+ #
208
+ # @param [Array<String>] output_paths
209
+ # The output paths to trim.
210
+ #
211
+ # @return [void]
212
+ #
213
+ def validate_input_output_path_limit(input_paths, output_paths)
214
+ if (input_paths.count + output_paths.count) > MAX_INPUT_OUTPUT_PATHS
215
+ input_paths.clear
216
+ output_paths.clear
217
+ end
218
+ end
219
+
194
220
  # Returns an extension in the target that corresponds to the
195
221
  # resource's input extension.
196
222
  #
223
+ # @param [String] input_extension
224
+ # The input extension to map to.
225
+ #
197
226
  # @return [String] The output extension.
198
227
  #
199
228
  def output_extension_for_resource(input_extension)
@@ -204,9 +233,27 @@ module Pod
204
233
  when '.xcdatamodel' then '.mom'
205
234
  when '.xcdatamodeld' then '.momd'
206
235
  when '.xcmappingmodel' then '.cdm'
236
+ when '.xcassets' then '.car'
207
237
  else input_extension
208
238
  end
209
239
  end
240
+
241
+ # Returns the resource output paths for all given input paths.
242
+ #
243
+ # @param [Array<String>] resource_input_paths
244
+ # The input paths to map to.
245
+ #
246
+ # @return [Array<String>] The resource output paths.
247
+ #
248
+ def resource_output_paths(resource_input_paths)
249
+ resource_input_paths.map do |resource_input_path|
250
+ base_path = '${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}'
251
+ extname = File.extname(resource_input_path)
252
+ basename = extname == '.xcassets' ? 'Assets' : File.basename(resource_input_path)
253
+ output_extension = TargetIntegrator.output_extension_for_resource(extname)
254
+ File.join(base_path, File.basename(basename, extname) + output_extension)
255
+ end.uniq
256
+ end
210
257
  end
211
258
 
212
259
  # Integrates the user project targets. Only the targets that do **not**
@@ -277,19 +324,15 @@ module Pod
277
324
  native_targets.each do |native_target|
278
325
  script_path = target.copy_resources_script_relative_path
279
326
  resource_paths_by_config = target.resource_paths_by_config
280
- input_paths = []
281
- output_paths = []
282
- unless resource_paths_by_config.values.all?(&:empty?)
327
+ if resource_paths_by_config.values.all?(&:empty?)
328
+ TargetIntegrator.remove_copy_resources_script_phase_from_target(native_target)
329
+ else
283
330
  resource_paths_flattened = resource_paths_by_config.values.flatten.uniq
284
331
  input_paths = [target.copy_resources_script_relative_path, *resource_paths_flattened]
285
- # convert input paths to output paths according to extensions
286
- output_paths = resource_paths_flattened.map do |input_path|
287
- base_path = '${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}'
288
- output_extension = TargetIntegrator.output_extension_for_resource(File.extname(input_path))
289
- File.join(base_path, File.basename(input_path, File.extname(input_path)) + output_extension)
290
- end.uniq
332
+ output_paths = TargetIntegrator.resource_output_paths(resource_paths_flattened)
333
+ TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
334
+ TargetIntegrator.create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths, output_paths)
291
335
  end
292
- TargetIntegrator.add_copy_resources_script_phase_to_target(native_target, script_path, input_paths, output_paths)
293
336
  end
294
337
  end
295
338
 
@@ -316,13 +359,14 @@ module Pod
316
359
  native_targets_to_embed_in.each do |native_target|
317
360
  script_path = target.embed_frameworks_script_relative_path
318
361
  framework_paths_by_config = target.framework_paths_by_config.values.flatten.uniq
319
- input_paths = []
320
- output_paths = []
321
- unless framework_paths_by_config.all?(&:empty?)
362
+ if framework_paths_by_config.all?(&:empty?)
363
+ TargetIntegrator.remove_embed_frameworks_script_phase_from_target(native_target)
364
+ else
322
365
  input_paths = [target.embed_frameworks_script_relative_path, *framework_paths_by_config.map { |fw| [fw[:input_path], fw[:dsym_input_path]] }.flatten.compact]
323
366
  output_paths = framework_paths_by_config.map { |fw| [fw[:output_path], fw[:dsym_output_path]] }.flatten.compact.uniq
367
+ TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
368
+ TargetIntegrator.create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths, output_paths)
324
369
  end
325
- TargetIntegrator.add_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths, output_paths)
326
370
  end
327
371
  end
328
372