cocoapods 1.5.2 → 1.6.1

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 (81) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +365 -1
  3. data/bin/pod +1 -1
  4. data/lib/cocoapods/command/cache/clean.rb +1 -1
  5. data/lib/cocoapods/command/init.rb +4 -2
  6. data/lib/cocoapods/command/install.rb +7 -0
  7. data/lib/cocoapods/command/lib/lint.rb +8 -1
  8. data/lib/cocoapods/command/outdated.rb +4 -9
  9. data/lib/cocoapods/command/repo/add.rb +1 -1
  10. data/lib/cocoapods/command/repo/list.rb +1 -1
  11. data/lib/cocoapods/command/repo/push.rb +17 -12
  12. data/lib/cocoapods/command/repo/remove.rb +1 -1
  13. data/lib/cocoapods/command/repo/update.rb +1 -1
  14. data/lib/cocoapods/command/setup.rb +1 -1
  15. data/lib/cocoapods/command/spec/create.rb +39 -39
  16. data/lib/cocoapods/command/spec/lint.rb +8 -1
  17. data/lib/cocoapods/command.rb +3 -1
  18. data/lib/cocoapods/config.rb +13 -2
  19. data/lib/cocoapods/downloader/cache.rb +1 -1
  20. data/lib/cocoapods/executable.rb +3 -3
  21. data/lib/cocoapods/external_sources/abstract_external_source.rb +23 -13
  22. data/lib/cocoapods/external_sources.rb +7 -4
  23. data/lib/cocoapods/gem_version.rb +1 -1
  24. data/lib/cocoapods/generator/acknowledgements/markdown.rb +6 -0
  25. data/lib/cocoapods/generator/acknowledgements/plist.rb +13 -2
  26. data/lib/cocoapods/generator/app_target_helper.rb +141 -17
  27. data/lib/cocoapods/generator/copy_resources_script.rb +14 -3
  28. data/lib/cocoapods/generator/dummy_source.rb +14 -5
  29. data/lib/cocoapods/generator/embed_frameworks_script.rb +37 -20
  30. data/lib/cocoapods/generator/header.rb +1 -1
  31. data/lib/cocoapods/generator/info_plist_file.rb +12 -4
  32. data/lib/cocoapods/generator/prefix_header.rb +2 -2
  33. data/lib/cocoapods/hooks_manager.rb +28 -17
  34. data/lib/cocoapods/installer/analyzer/analysis_result.rb +52 -22
  35. data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +14 -6
  36. data/lib/cocoapods/installer/analyzer/pod_variant.rb +4 -5
  37. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +3 -14
  38. data/lib/cocoapods/installer/analyzer/specs_state.rb +28 -4
  39. data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +27 -14
  40. data/lib/cocoapods/installer/analyzer/target_inspector.rb +17 -11
  41. data/lib/cocoapods/installer/analyzer.rb +391 -284
  42. data/lib/cocoapods/installer/installation_options.rb +2 -0
  43. data/lib/cocoapods/installer/pod_source_installer.rb +31 -43
  44. data/lib/cocoapods/installer/post_install_hooks_context.rb +72 -47
  45. data/lib/cocoapods/installer/pre_install_hooks_context.rb +22 -13
  46. data/lib/cocoapods/installer/source_provider_hooks_context.rb +3 -1
  47. data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +44 -11
  48. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +69 -29
  49. data/lib/cocoapods/installer/user_project_integrator.rb +6 -4
  50. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +25 -16
  51. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +104 -0
  52. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +23 -50
  53. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +296 -177
  54. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +51 -33
  55. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +93 -0
  56. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +62 -69
  57. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +72 -0
  58. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +130 -122
  59. data/lib/cocoapods/installer/xcode/target_validator.rb +15 -9
  60. data/lib/cocoapods/installer.rb +140 -63
  61. data/lib/cocoapods/project.rb +16 -14
  62. data/lib/cocoapods/resolver/resolver_specification.rb +41 -0
  63. data/lib/cocoapods/resolver.rb +79 -98
  64. data/lib/cocoapods/sandbox/file_accessor.rb +11 -6
  65. data/lib/cocoapods/sandbox/headers_store.rb +9 -8
  66. data/lib/cocoapods/sandbox/path_list.rb +5 -8
  67. data/lib/cocoapods/sandbox.rb +31 -43
  68. data/lib/cocoapods/sources_manager.rb +1 -1
  69. data/lib/cocoapods/target/aggregate_target.rb +143 -85
  70. data/lib/cocoapods/target/build_settings.rb +1124 -0
  71. data/lib/cocoapods/target/framework_paths.rb +36 -0
  72. data/lib/cocoapods/target/pod_target.rb +198 -295
  73. data/lib/cocoapods/target.rb +92 -37
  74. data/lib/cocoapods/user_interface.rb +5 -0
  75. data/lib/cocoapods/validator.rb +149 -44
  76. data/lib/cocoapods.rb +0 -1
  77. metadata +31 -23
  78. data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +0 -260
  79. data/lib/cocoapods/generator/xcconfig/pod_xcconfig.rb +0 -87
  80. data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +0 -558
  81. data/lib/cocoapods/generator/xcconfig.rb +0 -13
@@ -1,3 +1,5 @@
1
+ require 'cocoapods/target/build_settings'
2
+
1
3
  module Pod
2
4
  # Model class which describes a Pods target.
3
5
  #
@@ -7,6 +9,8 @@ module Pod
7
9
  #
8
10
  class Target
9
11
  DEFAULT_VERSION = '1.0.0'.freeze
12
+ DEFAULT_NAME = 'Default'.freeze
13
+ DEFAULT_BUILD_CONFIGURATIONS = { 'Release' => :release, 'Debug' => :debug }.freeze
10
14
 
11
15
  # @return [Sandbox] The sandbox where the Pods should be installed.
12
16
  #
@@ -15,13 +19,43 @@ module Pod
15
19
  # @return [Boolean] Whether the target needs to be implemented as a framework.
16
20
  # Computed by analyzer.
17
21
  #
18
- attr_accessor :host_requires_frameworks
22
+ attr_reader :host_requires_frameworks
19
23
  alias_method :host_requires_frameworks?, :host_requires_frameworks
20
24
 
25
+ # @return [Hash{String=>Symbol}] A hash representing the user build
26
+ # configurations where each key corresponds to the name of a
27
+ # configuration and its value to its type (`:debug` or `:release`).
28
+ #
29
+ attr_reader :user_build_configurations
30
+
31
+ # @return [Array<String>] The value for the ARCHS build setting.
32
+ #
33
+ attr_reader :archs
34
+
35
+ # @return [Platform] the platform of this target.
36
+ #
37
+ attr_reader :platform
38
+
39
+ # @return [BuildSettings] the build settings for this target.
40
+ #
41
+ attr_reader :build_settings
42
+
21
43
  # Initialize a new target
22
44
  #
23
- def initialize
24
- @archs = []
45
+ # @param [Sandbox] sandbox @see #sandbox
46
+ # @param [Boolean] host_requires_frameworks @see #host_requires_frameworks
47
+ # @param [Hash{String=>Symbol}] user_build_configurations @see #user_build_configurations
48
+ # @param [Array<String>] archs @see #archs
49
+ # @param [Platform] platform @see #platform
50
+ #
51
+ def initialize(sandbox, host_requires_frameworks, user_build_configurations, archs, platform)
52
+ @sandbox = sandbox
53
+ @host_requires_frameworks = host_requires_frameworks
54
+ @user_build_configurations = user_build_configurations
55
+ @archs = archs
56
+ @platform = platform
57
+
58
+ @build_settings = create_build_settings
25
59
  end
26
60
 
27
61
  # @return [String] the name of the library.
@@ -30,6 +64,40 @@ module Pod
30
64
  label
31
65
  end
32
66
 
67
+ alias to_s name
68
+
69
+ # @return [String] the label for the target.
70
+ #
71
+ def label
72
+ DEFAULT_NAME
73
+ end
74
+
75
+ # @return [String] The version associated with this target
76
+ #
77
+ def version
78
+ DEFAULT_VERSION
79
+ end
80
+
81
+ # @return [Boolean] Whether the target uses Swift code
82
+ #
83
+ def uses_swift?
84
+ false
85
+ end
86
+
87
+ # @return [Boolean] Whether the target should build a static framework.
88
+ #
89
+ def static_framework?
90
+ false
91
+ end
92
+
93
+ # @return [String] the name to use for the source code module constructed
94
+ # for this target, and which will be used to import the module in
95
+ # implementation source files.
96
+ #
97
+ def product_module_name
98
+ c99ext_identifier(label)
99
+ end
100
+
33
101
  # @return [String] the name of the product.
34
102
  #
35
103
  def product_name
@@ -85,6 +153,8 @@ module Pod
85
153
 
86
154
  #-------------------------------------------------------------------------#
87
155
 
156
+ # @!group Framework support
157
+
88
158
  # @return [Boolean] whether the generated target needs to be implemented
89
159
  # as a framework
90
160
  #
@@ -92,33 +162,6 @@ module Pod
92
162
  host_requires_frameworks? || false
93
163
  end
94
164
 
95
- # @return [Boolean] Whether the target should build a static framework.
96
- #
97
- def static_framework?
98
- return if is_a?(Pod::AggregateTarget)
99
- return if specs.empty?
100
- specs.all? { |spec| spec.root.static_framework }
101
- end
102
-
103
- #-------------------------------------------------------------------------#
104
-
105
- # @!group Information storage
106
-
107
- # @return [Hash{String=>Symbol}] A hash representing the user build
108
- # configurations where each key corresponds to the name of a
109
- # configuration and its value to its type (`:debug` or `:release`).
110
- #
111
- attr_accessor :user_build_configurations
112
-
113
- # @return [PBXNativeTarget] the target generated in the Pods project for
114
- # this library.
115
- #
116
- attr_accessor :native_target
117
-
118
- # @return [Array<String>] The value for the ARCHS build setting.
119
- #
120
- attr_accessor :archs
121
-
122
165
  #-------------------------------------------------------------------------#
123
166
 
124
167
  # @!group Support files
@@ -153,10 +196,24 @@ module Pod
153
196
  module_map_path.parent + "#{label}-umbrella.h"
154
197
  end
155
198
 
199
+ def umbrella_header_path_to_write
200
+ module_map_path_to_write.parent + "#{label}-umbrella.h"
201
+ end
202
+
156
203
  # @return [Pathname] the absolute path of the LLVM module map file that
157
204
  # defines the module structure for the compiler.
158
205
  #
159
206
  def module_map_path
207
+ module_map_path_to_write
208
+ end
209
+
210
+ # @!private
211
+ #
212
+ # @return [Pathname] the absolute path of the module map file that
213
+ # CocoaPods writes. This can be different from `module_map_path`
214
+ # if the module map gets symlinked.
215
+ #
216
+ def module_map_path_to_write
160
217
  basename = "#{label}.modulemap"
161
218
  support_files_dir + basename
162
219
  end
@@ -170,7 +227,7 @@ module Pod
170
227
  # @return [Pathname] the absolute path of the Info.plist file.
171
228
  #
172
229
  def info_plist_path
173
- support_files_dir + 'Info.plist'
230
+ support_files_dir + "#{label}-Info.plist"
174
231
  end
175
232
 
176
233
  # @return [Pathname] the path of the dummy source generated by CocoaPods
@@ -179,12 +236,6 @@ module Pod
179
236
  support_files_dir + "#{label}-dummy.m"
180
237
  end
181
238
 
182
- # @return [String] The version associated with this target
183
- #
184
- def version
185
- DEFAULT_VERSION
186
- end
187
-
188
239
  #-------------------------------------------------------------------------#
189
240
 
190
241
  private
@@ -202,5 +253,9 @@ module Pod
202
253
  def c99ext_identifier(name)
203
254
  name.gsub(/^([0-9])/, '_\1').gsub(/[^a-zA-Z0-9_]/, '_')
204
255
  end
256
+
257
+ def create_build_settings
258
+ BuildSettings.new(self)
259
+ end
205
260
  end
206
261
  end
@@ -62,6 +62,7 @@ module Pod
62
62
  self.indentation_level += relative_indentation
63
63
  self.title_level += 1
64
64
  yield if block_given?
65
+ ensure
65
66
  self.indentation_level -= relative_indentation
66
67
  self.title_level -= 1
67
68
  end
@@ -83,6 +84,7 @@ module Pod
83
84
  self.indentation_level += relative_indentation
84
85
  self.title_level += 1
85
86
  yield if block_given?
87
+ ensure
86
88
  self.indentation_level -= relative_indentation
87
89
  self.title_level -= 1
88
90
  end
@@ -114,6 +116,7 @@ module Pod
114
116
  self.indentation_level += relative_indentation
115
117
  self.title_level += 1
116
118
  yield if block_given?
119
+ ensure
117
120
  self.indentation_level -= relative_indentation
118
121
  self.title_level -= 1
119
122
  end
@@ -140,6 +143,7 @@ module Pod
140
143
 
141
144
  self.indentation_level += relative_indentation
142
145
  yield if block_given?
146
+ ensure
143
147
  self.indentation_level -= relative_indentation
144
148
  end
145
149
 
@@ -160,6 +164,7 @@ module Pod
160
164
  self.indentation_level += 2
161
165
  @treat_titles_as_messages = true
162
166
  yield if block_given?
167
+ ensure
163
168
  @treat_titles_as_messages = false
164
169
  self.indentation_level -= 2
165
170
  end
@@ -18,6 +18,10 @@ module Pod
18
18
  #
19
19
  DEFAULT_SWIFT_VERSION = '3.2'.freeze
20
20
 
21
+ # The valid platforms for linting
22
+ #
23
+ VALID_PLATFORMS = Platform.all.freeze
24
+
21
25
  # @return [Specification::Linter] the linter instance from CocoaPods
22
26
  # Core.
23
27
  #
@@ -31,13 +35,28 @@ module Pod
31
35
  # @param [Array<String>] source_urls
32
36
  # the Source URLs to use in creating a {Podfile}.
33
37
  #
34
- def initialize(spec_or_path, source_urls)
38
+ # @param. [Array<String>] platforms
39
+ # the platforms to lint.
40
+ #
41
+ def initialize(spec_or_path, source_urls, platforms = [])
35
42
  @linter = Specification::Linter.new(spec_or_path)
36
43
  @source_urls = if @linter.spec && @linter.spec.dependencies.empty? && @linter.spec.recursive_subspecs.all? { |s| s.dependencies.empty? }
37
44
  []
38
45
  else
39
46
  source_urls.map { |url| config.sources_manager.source_with_name_or_url(url) }.map(&:url)
40
47
  end
48
+
49
+ @platforms = platforms.map do |platform|
50
+ result = case platform.to_s.downcase
51
+ # Platform doesn't recognize 'macos' as being the same as 'osx' when initializing
52
+ when 'macos' then Platform.macos
53
+ else Platform.new(platform, nil)
54
+ end
55
+ unless valid_platform?(result)
56
+ raise Informative, "Unrecognized platform `#{platform}`. Valid platforms: #{VALID_PLATFORMS.join(', ')}"
57
+ end
58
+ result
59
+ end
41
60
  end
42
61
 
43
62
  #-------------------------------------------------------------------------#
@@ -55,6 +74,28 @@ module Pod
55
74
  @linter.file
56
75
  end
57
76
 
77
+ # Returns a list of platforms to lint for a given Specification
78
+ #
79
+ # @param [Specification] spec
80
+ # The specification to lint
81
+ #
82
+ # @return [Array<Platform>] platforms to lint for the given specification
83
+ #
84
+ def platforms_to_lint(spec)
85
+ return spec.available_platforms if @platforms.empty?
86
+
87
+ # Validate that the platforms specified are actually supported by the spec
88
+ results = @platforms.map do |platform|
89
+ matching_platform = spec.available_platforms.find { |p| p.name == platform.name }
90
+ unless matching_platform
91
+ raise Informative, "Platform `#{platform}` is not supported by specification `#{spec}`."
92
+ end
93
+ matching_platform
94
+ end.uniq
95
+
96
+ results
97
+ end
98
+
58
99
  # @return [Sandbox::FileAccessor] the file accessor for the spec.
59
100
  #
60
101
  attr_accessor :file_accessor
@@ -202,6 +243,10 @@ module Pod
202
243
  #
203
244
  attr_accessor :use_frameworks
204
245
 
246
+ # @return [Boolean] Whether modular headers should be used for the installation.
247
+ #
248
+ attr_accessor :use_modular_headers
249
+
205
250
  # @return [Boolean] Whether attributes that affect only public sources
206
251
  # Bool be skipped.
207
252
  #
@@ -309,7 +354,9 @@ module Pod
309
354
  validate_documentation_url(spec)
310
355
  validate_source_url(spec)
311
356
 
312
- valid = spec.available_platforms.send(fail_fast ? :all? : :each) do |platform|
357
+ platforms = platforms_to_lint(spec)
358
+
359
+ valid = platforms.send(fail_fast ? :all? : :each) do |platform|
313
360
  UI.message "\n\n#{spec} - Analyzing on #{platform} platform.".green.reversed
314
361
  @consumer = spec.consumer(platform)
315
362
  setup_validation_environment
@@ -464,7 +511,8 @@ module Pod
464
511
  end
465
512
 
466
513
  def download_pod
467
- podfile = podfile_from_spec(consumer.platform_name, deployment_target, use_frameworks, consumer.spec.test_specs.map(&:name))
514
+ test_spec_names = consumer.spec.test_specs.select { |ts| ts.supported_on_platform?(consumer.platform_name) }.map(&:name)
515
+ podfile = podfile_from_spec(consumer.platform_name, deployment_target, use_frameworks, test_spec_names, use_modular_headers)
468
516
  sandbox = Sandbox.new(config.sandbox_root)
469
517
  @installer = Installer.new(sandbox, podfile)
470
518
  @installer.use_default_plugins = false
@@ -475,7 +523,8 @@ module Pod
475
523
 
476
524
  def create_app_project
477
525
  app_project = Xcodeproj::Project.new(validation_dir + 'App.xcodeproj')
478
- Pod::Generator::AppTargetHelper.add_app_target(app_project, consumer.platform_name, deployment_target)
526
+ app_target = Pod::Generator::AppTargetHelper.add_app_target(app_project, consumer.platform_name, deployment_target)
527
+ Pod::Generator::AppTargetHelper.add_swift_version(app_target, swift_version)
479
528
  app_project.save
480
529
  app_project.recreate_user_schemes
481
530
  end
@@ -484,9 +533,9 @@ module Pod
484
533
  app_project = Xcodeproj::Project.open(validation_dir + 'App.xcodeproj')
485
534
  app_target = app_project.targets.first
486
535
  pod_target = @installer.pod_targets.find { |pt| pt.pod_name == spec.root.name }
487
- Pod::Generator::AppTargetHelper.add_app_project_import(app_project, app_target, pod_target, consumer.platform_name, use_frameworks)
488
- Pod::Generator::AppTargetHelper.add_swift_version(app_target, swift_version)
536
+ Pod::Generator::AppTargetHelper.add_app_project_import(app_project, app_target, pod_target, consumer.platform_name)
489
537
  Pod::Generator::AppTargetHelper.add_xctest_search_paths(app_target) if @installer.pod_targets.any? { |pt| pt.spec_consumers.any? { |c| c.frameworks.include?('XCTest') } }
538
+ Pod::Generator::AppTargetHelper.add_empty_swift_file(app_project, app_target) if @installer.pod_targets.any?(&:uses_swift?)
490
539
  app_project.save
491
540
  Xcodeproj::XCScheme.share_scheme(app_project.path, 'App')
492
541
  # Share the pods xcscheme only if it exists. For pre-built vendored pods there is no xcscheme generated.
@@ -501,43 +550,33 @@ module Pod
501
550
  perform_post_install_actions).each { |m| @installer.send(m) }
502
551
 
503
552
  deployment_target = spec.subspec_by_name(subspec_name).deployment_target(consumer.platform_name)
504
- configure_pod_targets(@installer.aggregate_targets, deployment_target)
553
+ configure_pod_targets(@installer.aggregate_targets, @installer.target_installation_results, deployment_target)
505
554
  @installer.pods_project.save
506
555
  end
507
556
 
508
- def configure_pod_targets(targets, deployment_target)
509
- test_only_pod_targets = @installer.pod_targets - targets.flat_map(&:pod_targets)
510
- targets.each do |target|
511
- target.pod_targets.each do |pod_target|
512
- update_pod_target_build_settings(pod_target)
513
- if pod_target.uses_swift?
514
- pod_target.test_native_targets.each do |test_native_target|
515
- test_native_target.build_configuration_list.build_configurations.each do |build_configuration|
516
- build_configuration.build_settings['SWIFT_VERSION'] = swift_version
517
- end
557
+ def configure_pod_targets(targets, target_installation_results, deployment_target)
558
+ target_installation_results.first.values.each do |pod_target_installation_result|
559
+ pod_target = pod_target_installation_result.target
560
+ native_target = pod_target_installation_result.native_target
561
+ native_target.build_configuration_list.build_configurations.each do |build_configuration|
562
+ (build_configuration.build_settings['OTHER_CFLAGS'] ||= '$(inherited)') << ' -Wincomplete-umbrella'
563
+ build_configuration.build_settings['SWIFT_VERSION'] = (pod_target.swift_version || swift_version) if pod_target.uses_swift?
564
+ end
565
+ pod_target_installation_result.test_specs_by_native_target.each do |test_native_target, test_specs|
566
+ if pod_target.uses_swift_for_test_spec?(test_specs.first)
567
+ test_native_target.build_configuration_list.build_configurations.each do |build_configuration|
568
+ build_configuration.build_settings['SWIFT_VERSION'] = swift_version
518
569
  end
519
570
  end
520
571
  end
572
+ end
573
+ targets.each do |target|
521
574
  if target.pod_targets.any?(&:uses_swift?) && consumer.platform_name == :ios &&
522
575
  (deployment_target.nil? || Version.new(deployment_target).major < 8)
523
576
  uses_xctest = target.spec_consumers.any? { |c| (c.frameworks + c.weak_frameworks).include? 'XCTest' }
524
577
  error('swift', 'Swift support uses dynamic frameworks and is therefore only supported on iOS > 8.') unless uses_xctest
525
578
  end
526
579
  end
527
- # Wire up Swift version to pod targets used only by tests.
528
- test_only_pod_targets.each do |test_pod_target|
529
- update_pod_target_build_settings(test_pod_target)
530
- end
531
- end
532
-
533
- def update_pod_target_build_settings(pod_target)
534
- native_target = pod_target.native_target
535
- unless native_target.nil?
536
- native_target.build_configuration_list.build_configurations.each do |build_configuration|
537
- (build_configuration.build_settings['OTHER_CFLAGS'] ||= '$(inherited)') << ' -Wincomplete-umbrella'
538
- build_configuration.build_settings['SWIFT_VERSION'] = (pod_target.swift_version || swift_version) if pod_target.uses_swift?
539
- end
540
- end
541
580
  end
542
581
 
543
582
  def validate_vendored_dynamic_frameworks
@@ -597,10 +636,14 @@ module Pod
597
636
  UI.message "\nTesting with `xcodebuild`.\n".yellow do
598
637
  pod_target = @installer.pod_targets.find { |pt| pt.pod_name == spec.root.name }
599
638
  consumer.spec.test_specs.each do |test_spec|
600
- scheme = pod_target.native_target_for_spec(test_spec)
601
- output = xcodebuild('test', scheme, 'Debug')
602
- parsed_output = parse_xcodebuild_output(output)
603
- translate_output_to_linter_messages(parsed_output)
639
+ if !test_spec.supported_on_platform?(consumer.platform_name)
640
+ UI.warn "Skipping test spec `#{test_spec.name}` on platform `#{consumer.platform_name}` since it is not supported.\n".yellow
641
+ else
642
+ scheme = @installer.target_installation_results.first[pod_target.name].native_target_for_spec(test_spec)
643
+ output = xcodebuild('test', scheme, 'Debug')
644
+ parsed_output = parse_xcodebuild_output(output)
645
+ translate_output_to_linter_messages(parsed_output)
646
+ end
604
647
  end
605
648
  end
606
649
  end
@@ -624,10 +667,8 @@ module Pod
624
667
  FILE_PATTERNS.each do |attr_name|
625
668
  if respond_to?("_validate_#{attr_name}", true)
626
669
  send("_validate_#{attr_name}")
627
- end
628
-
629
- if !file_accessor.spec_consumer.send(attr_name).empty? && file_accessor.send(attr_name).empty?
630
- error('file patterns', "The `#{attr_name}` pattern did not match any file.")
670
+ else
671
+ validate_nonempty_patterns(attr_name, :error)
631
672
  end
632
673
  end
633
674
 
@@ -638,12 +679,26 @@ module Pod
638
679
  end
639
680
  end
640
681
 
682
+ # Validates that the file patterns in `attr_name` match at least 1 file.
683
+ #
684
+ # @param [String,Symbol] attr_name the name of the attribute to check (ex. :public_header_files)
685
+ #
686
+ # @param [String,Symbol] message_type the type of message to send if the patterns are empty (ex. :error)
687
+ #
688
+ def validate_nonempty_patterns(attr_name, message_type)
689
+ return unless !file_accessor.spec_consumer.send(attr_name).empty? && file_accessor.send(attr_name).empty?
690
+
691
+ add_result(message_type, 'file patterns', "The `#{attr_name}` pattern did not match any file.")
692
+ end
693
+
641
694
  def _validate_private_header_files
642
695
  _validate_header_files(:private_header_files)
696
+ validate_nonempty_patterns(:private_header_files, :warning)
643
697
  end
644
698
 
645
699
  def _validate_public_header_files
646
700
  _validate_header_files(:public_header_files)
701
+ validate_nonempty_patterns(:public_header_files, :warning)
647
702
  end
648
703
 
649
704
  def _validate_license
@@ -801,27 +856,30 @@ module Pod
801
856
  # @note The generated podfile takes into account whether the linter is
802
857
  # in local mode.
803
858
  #
804
- def podfile_from_spec(platform_name, deployment_target, use_frameworks = true, test_spec_names = [])
859
+ def podfile_from_spec(platform_name, deployment_target, use_frameworks = true, test_spec_names = [], use_modular_headers = false)
805
860
  name = subspec_name || spec.name
806
861
  podspec = file.realpath
807
862
  local = local?
808
863
  urls = source_urls
809
864
  Pod::Podfile.new do
810
865
  install! 'cocoapods', :deterministic_uuids => false
866
+ # By default inhibit warnings for all pods, except the one being validated.
867
+ inhibit_all_warnings!
811
868
  urls.each { |u| source(u) }
812
869
  target 'App' do
813
870
  use_frameworks!(use_frameworks)
871
+ use_modular_headers! if use_modular_headers
814
872
  platform(platform_name, deployment_target)
815
873
  if local
816
- pod name, :path => podspec.dirname.to_s
874
+ pod name, :path => podspec.dirname.to_s, :inhibit_warnings => false
817
875
  else
818
- pod name, :podspec => podspec.to_s
876
+ pod name, :podspec => podspec.to_s, :inhibit_warnings => false
819
877
  end
820
878
  test_spec_names.each do |test_spec_name|
821
879
  if local
822
- pod test_spec_name, :path => podspec.dirname.to_s
880
+ pod test_spec_name, :path => podspec.dirname.to_s, :inhibit_warnings => false
823
881
  else
824
- pod test_spec_name, :podspec => podspec.to_s
882
+ pod test_spec_name, :podspec => podspec.to_s, :inhibit_warnings => false
825
883
  end
826
884
  end
827
885
  end
@@ -863,6 +921,14 @@ module Pod
863
921
  when :ios
864
922
  command += %w(CODE_SIGN_IDENTITY=- -sdk iphonesimulator)
865
923
  command += Fourflusher::SimControl.new.destination(:oldest, 'iOS', deployment_target)
924
+ xcconfig = consumer.pod_target_xcconfig
925
+ if xcconfig
926
+ archs = xcconfig['VALID_ARCHS']
927
+ if archs && (archs.include? 'armv7') && !(archs.include? 'i386') && (archs.include? 'x86_64')
928
+ # Prevent Xcodebuild from testing the non-existent i386 simulator if armv7 is specified without i386
929
+ command += %w(ARCHS=x86_64)
930
+ end
931
+ end
866
932
  when :watchos
867
933
  command += %w(CODE_SIGN_IDENTITY=- -sdk watchsimulator)
868
934
  command += Fourflusher::SimControl.new.destination(:oldest, 'watchOS', deployment_target)
@@ -889,6 +955,45 @@ module Pod
889
955
  Executable.execute_command('xcodebuild', command, raise_on_failure)
890
956
  end
891
957
 
958
+ # Whether the platform with the specified name is valid
959
+ #
960
+ # @param [Platform] platform
961
+ # The platform to check
962
+ #
963
+ # @return [Bool] True if the platform is valid
964
+ #
965
+ def valid_platform?(platform)
966
+ VALID_PLATFORMS.any? { |p| p.name == platform.name }
967
+ end
968
+
969
+ # Whether the platform is supported by the specification
970
+ #
971
+ # @param [Platform] platform
972
+ # The platform to check
973
+ #
974
+ # @param [Specification] specification
975
+ # The specification which must support the provided platform
976
+ #
977
+ # @return [Bool] Whether the platform is supported by the specification
978
+ #
979
+ def supported_platform?(platform, spec)
980
+ available_platforms = spec.available_platforms
981
+
982
+ available_platforms.any? { |p| p.name == platform.name }
983
+ end
984
+
985
+ # Whether the provided name matches the platform
986
+ #
987
+ # @param [Platform] platform
988
+ # The platform
989
+ #
990
+ # @param [String] name
991
+ # The name to check against the provided platform
992
+ #
993
+ def platform_name_match?(platform, name)
994
+ [platform.name, platform.string_name].any? { |n| n.casecmp(name) == 0 }
995
+ end
996
+
892
997
  #-------------------------------------------------------------------------#
893
998
  end
894
999
  end
data/lib/cocoapods.rb CHANGED
@@ -66,7 +66,6 @@ module Pod
66
66
  autoload :ModuleMap, 'cocoapods/generator/module_map'
67
67
  autoload :PrefixHeader, 'cocoapods/generator/prefix_header'
68
68
  autoload :UmbrellaHeader, 'cocoapods/generator/umbrella_header'
69
- autoload :XCConfig, 'cocoapods/generator/xcconfig'
70
69
  autoload :AppTargetHelper, 'cocoapods/generator/app_target_helper'
71
70
  end
72
71