cocoapods 1.7.5 → 1.8.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +175 -11
  3. data/LICENSE +13 -8
  4. data/README.md +2 -1
  5. data/lib/cocoapods/command/init.rb +18 -16
  6. data/lib/cocoapods/command/install.rb +2 -1
  7. data/lib/cocoapods/command/lib/create.rb +1 -2
  8. data/lib/cocoapods/command/lib/lint.rb +12 -11
  9. data/lib/cocoapods/command/repo/add.rb +2 -2
  10. data/lib/cocoapods/command/repo/list.rb +7 -5
  11. data/lib/cocoapods/command/repo/push.rb +15 -12
  12. data/lib/cocoapods/command/setup.rb +2 -88
  13. data/lib/cocoapods/command/spec/lint.rb +10 -9
  14. data/lib/cocoapods/command/update.rb +5 -4
  15. data/lib/cocoapods/config.rb +9 -8
  16. data/lib/cocoapods/external_sources/path_source.rb +1 -1
  17. data/lib/cocoapods/gem_version.rb +1 -1
  18. data/lib/cocoapods/generator/embed_frameworks_script.rb +1 -1
  19. data/lib/cocoapods/generator/info_plist_file.rb +2 -2
  20. data/lib/cocoapods/installer.rb +32 -12
  21. data/lib/cocoapods/installer/analyzer.rb +132 -97
  22. data/lib/cocoapods/installer/analyzer/target_inspector.rb +6 -8
  23. data/lib/cocoapods/installer/installation_options.rb +4 -0
  24. data/lib/cocoapods/installer/pod_source_installer.rb +17 -1
  25. data/lib/cocoapods/installer/podfile_validator.rb +26 -6
  26. data/lib/cocoapods/installer/project_cache/project_cache_analyzer.rb +37 -27
  27. data/lib/cocoapods/installer/project_cache/project_cache_version.rb +1 -1
  28. data/lib/cocoapods/installer/project_cache/project_installation_cache.rb +3 -3
  29. data/lib/cocoapods/installer/project_cache/project_metadata_cache.rb +12 -6
  30. data/lib/cocoapods/installer/project_cache/target_cache_key.rb +32 -8
  31. data/lib/cocoapods/installer/project_cache/target_metadata.rb +6 -2
  32. data/lib/cocoapods/installer/sandbox_dir_cleaner.rb +12 -0
  33. data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +1 -1
  34. data/lib/cocoapods/installer/xcode/multi_pods_project_generator.rb +3 -1
  35. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_dependency_installer.rb +2 -2
  36. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +18 -3
  37. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +53 -11
  38. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +92 -60
  39. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +66 -50
  40. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +12 -0
  41. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +6 -2
  42. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +2 -2
  43. data/lib/cocoapods/installer/xcode/target_validator.rb +30 -14
  44. data/lib/cocoapods/native_target_extension.rb +11 -5
  45. data/lib/cocoapods/open-uri.rb +1 -1
  46. data/lib/cocoapods/project.rb +13 -7
  47. data/lib/cocoapods/resolver.rb +63 -53
  48. data/lib/cocoapods/resolver/lazy_specification.rb +14 -5
  49. data/lib/cocoapods/sandbox.rb +35 -2
  50. data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +3 -4
  51. data/lib/cocoapods/sources_manager.rb +72 -43
  52. data/lib/cocoapods/target.rb +7 -1
  53. data/lib/cocoapods/target/aggregate_target.rb +13 -8
  54. data/lib/cocoapods/target/build_settings.rb +33 -10
  55. data/lib/cocoapods/target/pod_target.rb +114 -30
  56. data/lib/cocoapods/user_interface/error_report.rb +9 -5
  57. data/lib/cocoapods/validator.rb +55 -11
  58. data/lib/cocoapods/version_metadata.rb +14 -1
  59. metadata +6 -7
  60. data/lib/cocoapods/command/spec/env_spec.rb +0 -53
@@ -42,17 +42,26 @@ module Pod
42
42
  end
43
43
 
44
44
  class External
45
- def all_specifications(_warn_for_multiple_pod_sources)
46
- [specification]
45
+ def all_specifications(_warn_for_multiple_pod_sources, requirement)
46
+ if requirement.satisfied_by? specification.version
47
+ [specification]
48
+ else
49
+ []
50
+ end
47
51
  end
48
52
  end
49
53
 
50
54
  # returns the highest versioned spec last
51
- def all_specifications(warn_for_multiple_pod_sources)
52
- @all_specifications ||= begin
55
+ def all_specifications(warn_for_multiple_pod_sources, requirement)
56
+ @all_specifications ||= {}
57
+ @all_specifications[requirement] ||= begin
53
58
  sources_by_version = {}
54
59
  versions_by_source.each do |source, versions|
55
- versions.each { |v| (sources_by_version[v] ||= []) << source }
60
+ versions.each do |v|
61
+ next unless requirement.satisfied_by?(v)
62
+
63
+ (sources_by_version[v] ||= []) << source
64
+ end
56
65
  end
57
66
 
58
67
  if warn_for_multiple_pod_sources
@@ -286,7 +286,7 @@ module Pod
286
286
  spec =
287
287
  case podspec
288
288
  when String
289
- output_path.open('w') { |f| f.puts(podspec) }
289
+ Sandbox.update_changed_file(output_path, podspec)
290
290
  Specification.from_file(output_path)
291
291
  when Pathname
292
292
  unless podspec.exist?
@@ -296,7 +296,7 @@ module Pod
296
296
  Specification.from_file(podspec)
297
297
  when Specification
298
298
  raise ArgumentError, 'can only store Specification objects as json' unless json
299
- output_path.open('w') { |f| f.puts(podspec.to_pretty_json) }
299
+ Sandbox.update_changed_file(output_path, podspec.to_pretty_json)
300
300
  podspec.dup
301
301
  else
302
302
  raise ArgumentError, "Unknown type for podspec: #{podspec.inspect}"
@@ -379,6 +379,18 @@ module Pod
379
379
  checkout_sources.delete(root_name)
380
380
  end
381
381
 
382
+ # Removes local podspec a Pod.
383
+ #
384
+ # @param [String] name
385
+ # The name of the Pod.
386
+ #
387
+ # @return [void]
388
+ #
389
+ def remove_local_podspec(name)
390
+ local_podspec = specification_path(name)
391
+ FileUtils.rm(local_podspec) if local_podspec
392
+ end
393
+
382
394
  # @return [Hash{String=>Hash}] The options necessary to recreate the exact
383
395
  # checkout of a given Pod grouped by its name.
384
396
  #
@@ -432,6 +444,27 @@ module Pod
432
444
  development_pods[root_name]
433
445
  end
434
446
 
447
+ # @!group Convenience Methods
448
+
449
+ # Writes a file if it does not exist or if its contents have changed.
450
+ #
451
+ # @param [Pathname] path
452
+ # The path to read from and write to.
453
+ #
454
+ # @param [String] contents
455
+ # The contents to write if they do not match or the file does not exist.
456
+ #
457
+ # @return [void]
458
+ #
459
+ def self.update_changed_file(path, contents)
460
+ if path.exist?
461
+ content_stream = StringIO.new(contents)
462
+ identical = File.open(path, 'rb') { |f| FileUtils.compare_stream(f, content_stream) }
463
+ return if identical
464
+ end
465
+ File.open(path, 'w') { |f| f.write(contents) }
466
+ end
467
+
435
468
  #-------------------------------------------------------------------------#
436
469
  end
437
470
  end
@@ -48,14 +48,13 @@ module Pod
48
48
  # @return [Array<Strings>] The paths that can be deleted.
49
49
  #
50
50
  def clean_paths
51
- cached_used = used_files
51
+ cached_used = used_files.map(&:downcase)
52
52
  glob_options = File::FNM_DOTMATCH | File::FNM_CASEFOLD
53
53
  files = Pathname.glob(root + '**/*', glob_options).map(&:to_s)
54
-
54
+ cached_used_set = cached_used.to_set
55
55
  files.reject do |candidate|
56
56
  candidate = candidate.downcase
57
- candidate.end_with?('.', '..') || cached_used.any? do |path|
58
- path = path.downcase
57
+ candidate.end_with?('.', '..') || cached_used_set.include?(candidate) || cached_used.any? do |path|
59
58
  path.include?(candidate) || candidate.include?(path)
60
59
  end
61
60
  end
@@ -1,5 +1,6 @@
1
1
  require 'cocoapods-core/source'
2
2
  require 'set'
3
+ require 'rest'
3
4
 
4
5
  module Pod
5
6
  class Source
@@ -15,40 +16,64 @@ module Pod
15
16
  # The URL of the source.
16
17
  #
17
18
  def find_or_create_source_with_url(url)
18
- unless source = source_with_url(url)
19
- name = name_for_url(url)
20
- # Hack to ensure that `repo add` output is shown.
21
- previous_title_level = UI.title_level
22
- UI.title_level = 0
23
- begin
24
- case
25
- when name =~ /^master(-\d+)?$/
26
- Command::Setup.parse([]).run
27
- when url =~ /\.git$/
28
- Command::Repo::Add.parse([name, url]).run
29
- when url =~ %r{^https:\/\/}
30
- Command::Repo::AddCDN.parse([name, url]).run
31
- else
32
- Command::Repo::Add.parse([name, url]).run
33
- end
34
- rescue Informative => e
35
- message = "Unable to add a source with url `#{url}` " \
36
- "named `#{name}`.\n"
37
- message << "(#{e})\n" if Config.instance.verbose?
38
- message << 'You can try adding it manually in ' \
39
- "`#{Config.instance.repos_dir}` or via `pod repo add`."
40
- raise Informative, message
41
- ensure
42
- UI.title_level = previous_title_level
19
+ source_with_url(url) || create_source_with_url(url)
20
+ end
21
+
22
+ # Adds the source whose {Source#url} is equal to `url`,
23
+ # in a manner similarly to `pod repo add` if it is not found.
24
+ #
25
+ # @raise If no source with the given `url` could be created,
26
+ #
27
+ # @return [Source] The source whose {Source#url} is equal to `url`,
28
+ #
29
+ # @param [String] url
30
+ # The URL of the source.
31
+ #
32
+ def create_source_with_url(url)
33
+ name = name_for_url(url)
34
+ is_cdn = cdn_url?(url)
35
+
36
+ # Hack to ensure that `repo add` output is shown.
37
+ previous_title_level = UI.title_level
38
+ UI.title_level = 0
39
+
40
+ begin
41
+ if is_cdn
42
+ Command::Repo::AddCDN.parse([name, url]).run
43
+ else
44
+ Command::Repo::Add.parse([name, url]).run
43
45
  end
44
- source = source_with_url(url)
46
+ rescue Informative => e
47
+ message = "Unable to add a source with url `#{url}` " \
48
+ "named `#{name}`.\n"
49
+ message << "(#{e})\n" if Config.instance.verbose?
50
+ message << 'You can try adding it manually in ' \
51
+ "`#{Config.instance.repos_dir}` or via `pod repo add`."
52
+ raise Informative, message
53
+ ensure
54
+ UI.title_level = previous_title_level
45
55
  end
56
+ source = source_with_url(url)
46
57
 
47
58
  raise "Unable to create a source with URL #{url}" unless source
48
59
 
49
60
  source
50
61
  end
51
62
 
63
+ # Determines whether `url` is a CocoaPods CDN URL.
64
+ #
65
+ # @return [Boolean] whether `url` is a CocoaPods CDN URL,
66
+ #
67
+ # @param [String] url
68
+ # The URL of the source.
69
+ #
70
+ def cdn_url?(url)
71
+ url =~ %r{^https:\/\/} &&
72
+ REST.head(url + '/all_pods.txt').ok?
73
+ rescue => e
74
+ raise Informative, "Couldn't determine repo type for URL: `#{url}`: #{e}"
75
+ end
76
+
52
77
  # Returns the source whose {Source#name} or {Source#url} is equal to the
53
78
  # given `name_or_url`.
54
79
  #
@@ -82,22 +107,35 @@ module Pod
82
107
  #
83
108
  def update(source_name = nil, show_output = false)
84
109
  if source_name
85
- sources = [git_source_named(source_name)]
110
+ sources = [updateable_source_named(source_name)]
86
111
  else
87
- sources = git_sources
112
+ sources = updateable_sources
88
113
  end
89
114
 
90
115
  changed_spec_paths = {}
91
- sources.each do |source|
92
- UI.section "Updating spec repo `#{source.name}`" do
93
- changed_source_paths = source.update(show_output)
94
- changed_spec_paths[source] = changed_source_paths if changed_source_paths.count > 0
95
- source.verify_compatibility!
116
+ # Ceate the Spec_Lock file if needed and lock it so that concurrent
117
+ # repo updates do not cause each other to fail
118
+ File.open("#{Config.instance.repos_dir}/Spec_Lock", File::CREAT) do |f|
119
+ f.flock(File::LOCK_EX)
120
+ sources.each do |source|
121
+ UI.section "Updating spec repo `#{source.name}`" do
122
+ changed_source_paths = source.update(show_output)
123
+ changed_spec_paths[source] = changed_source_paths if changed_source_paths.count > 0
124
+ source.verify_compatibility!
125
+ end
96
126
  end
97
127
  end
98
128
  # Perform search index update operation in background.
99
129
  update_search_index_if_needed_in_background(changed_spec_paths)
100
130
  end
131
+
132
+ # Adds the provided source to the list of sources
133
+ #
134
+ # @param [Source] source the source to add
135
+ #
136
+ def add_source(source)
137
+ all << source unless all.any? { |s| s.url == source || s.name == source.name }
138
+ end
101
139
  end
102
140
 
103
141
  extend Executable
@@ -131,16 +169,7 @@ module Pod
131
169
  end
132
170
  end
133
171
 
134
- class MasterSource
135
- def update_git_repo(show_output = false)
136
- if repo.join('.git', 'shallow').file?
137
- UI.info "Performing a deep fetch of the `#{name}` specs repo to improve future performance" do
138
- git!(%W(-C #{repo} fetch --unshallow))
139
- end
140
- end
141
- super
142
- end
143
-
172
+ class TrunkSource
144
173
  def verify_compatibility!
145
174
  super
146
175
  latest_cocoapods_version = metadata.latest_cocoapods_version && Gem::Version.create(metadata.latest_cocoapods_version)
@@ -41,7 +41,7 @@ module Pod
41
41
  #
42
42
  attr_reader :build_settings
43
43
 
44
- # @return [Type] the build type for this target.
44
+ # @return [Target::BuildType] the build type for this target.
45
45
  #
46
46
  attr_reader :build_type
47
47
  private :build_type
@@ -290,6 +290,12 @@ module Pod
290
290
  support_files_dir + "#{label}-Info.plist"
291
291
  end
292
292
 
293
+ # @return [Hash] additional entries for the generated Info.plist
294
+ #
295
+ def info_plist_entries
296
+ {}
297
+ end
298
+
293
299
  # @return [Pathname] the path of the dummy source generated by CocoaPods
294
300
  #
295
301
  def dummy_source_path
@@ -7,7 +7,8 @@ module Pod
7
7
  class AggregateTarget < Target
8
8
  # Product types where the product's frameworks must be embedded in a host target
9
9
  #
10
- EMBED_FRAMEWORKS_IN_HOST_TARGET_TYPES = [:app_extension, :framework, :static_library, :messages_extension, :watch_extension, :xpc_service].freeze
10
+ EMBED_FRAMEWORKS_IN_HOST_TARGET_TYPES = [:app_extension, :framework, :static_library, :messages_extension,
11
+ :watch_extension, :xpc_service].freeze
11
12
 
12
13
  # @return [TargetDefinition] the target definition of the Podfile that
13
14
  # generated this target.
@@ -118,7 +119,9 @@ module Pod
118
119
  # that this is a library
119
120
  return false if user_project.nil?
120
121
  symbol_types = user_targets.map(&:symbol_type).uniq
121
- raise ArgumentError, "Expected single kind of user_target for #{name}. Found #{symbol_types.join(', ')}." unless symbol_types.count == 1
122
+ unless symbol_types.count == 1
123
+ raise ArgumentError, "Expected single kind of user_target for #{name}. Found #{symbol_types.join(', ')}."
124
+ end
122
125
  [:framework, :dynamic_library, :static_library].include? symbol_types.first
123
126
  end
124
127
 
@@ -134,7 +137,9 @@ module Pod
134
137
  # target that would require a host target
135
138
  return false if user_project.nil?
136
139
  symbol_types = user_targets.map(&:symbol_type).uniq
137
- raise ArgumentError, "Expected single kind of user_target for #{name}. Found #{symbol_types.join(', ')}." unless symbol_types.count == 1
140
+ unless symbol_types.count == 1
141
+ raise ArgumentError, "Expected single kind of user_target for #{name}. Found #{symbol_types.join(', ')}."
142
+ end
138
143
  EMBED_FRAMEWORKS_IN_HOST_TARGET_TYPES.include?(symbol_types[0])
139
144
  end
140
145
 
@@ -194,7 +199,7 @@ module Pod
194
199
  #
195
200
  def specs_by_build_configuration
196
201
  result = {}
197
- user_build_configurations.keys.each do |build_configuration|
202
+ user_build_configurations.each_key do |build_configuration|
198
203
  result[build_configuration] = pod_targets_for_build_configuration(build_configuration).
199
204
  flat_map(&:specs)
200
205
  end
@@ -216,14 +221,14 @@ module Pod
216
221
  # @return [Boolean] Whether the target contains any resources
217
222
  #
218
223
  def includes_resources?
219
- !resource_paths_by_config.values.all?(&:empty?)
224
+ !resource_paths_by_config.each_value.all?(&:empty?)
220
225
  end
221
226
 
222
227
  # @return [Boolean] Whether the target contains framework to be embedded into
223
228
  # the user target
224
229
  #
225
230
  def includes_frameworks?
226
- !framework_paths_by_config.values.all?(&:empty?)
231
+ !framework_paths_by_config.each_value.all?(&:empty?)
227
232
  end
228
233
 
229
234
  # @return [Hash{String => Array<FrameworkPaths>}] The vendored dynamic artifacts and framework target
@@ -232,7 +237,7 @@ module Pod
232
237
  def framework_paths_by_config
233
238
  @framework_paths_by_config ||= begin
234
239
  framework_paths_by_config = {}
235
- user_build_configurations.keys.each do |config|
240
+ user_build_configurations.each_key do |config|
236
241
  relevant_pod_targets = pod_targets_for_build_configuration(config)
237
242
  framework_paths_by_config[config] = relevant_pod_targets.flat_map do |pod_target|
238
243
  library_specs = pod_target.library_specs.map(&:name)
@@ -250,7 +255,7 @@ module Pod
250
255
  relevant_pod_targets = pod_targets.reject do |pod_target|
251
256
  pod_target.should_build? && pod_target.build_as_dynamic_framework?
252
257
  end
253
- user_build_configurations.keys.each_with_object({}) do |config, resources_by_config|
258
+ user_build_configurations.each_key.each_with_object({}) do |config, resources_by_config|
254
259
  targets = relevant_pod_targets & pod_targets_for_build_configuration(config)
255
260
  resources_by_config[config] = targets.flat_map do |pod_target|
256
261
  library_specs = pod_target.library_specs.map(&:name)
@@ -402,8 +402,8 @@ module Pod
402
402
  #
403
403
  # @return [Hash<String, String>]
404
404
  #
405
- def merged_xcconfigs(xcconfig_values_by_consumer_by_key, attribute)
406
- xcconfig_values_by_consumer_by_key.each_with_object({}) do |(key, values_by_consumer), xcconfig|
405
+ def merged_xcconfigs(xcconfig_values_by_consumer_by_key, attribute, overriding: {})
406
+ xcconfig_values_by_consumer_by_key.each_with_object(overriding.dup) do |(key, values_by_consumer), xcconfig|
407
407
  uniq_values = values_by_consumer.values.uniq
408
408
  values_are_bools = uniq_values.all? { |v| v =~ /\A(yes|no)\z/i }
409
409
  if values_are_bools
@@ -417,7 +417,11 @@ module Pod
417
417
  end
418
418
  elsif PLURAL_SETTINGS.include? key
419
419
  # Plural build settings
420
- xcconfig[key] = uniq_values.join(' ')
420
+ if xcconfig.key?(key)
421
+ overridden = xcconfig[key]
422
+ uniq_values.prepend(overridden)
423
+ end
424
+ xcconfig[key] = uniq_values.uniq.join(' ')
421
425
  elsif uniq_values.count > 1
422
426
  # Singular build settings
423
427
  UI.warn "Can't merge #{attribute} for pod targets: " \
@@ -555,12 +559,11 @@ module Pod
555
559
 
556
560
  frameworks = []
557
561
  frameworks.concat consumer_frameworks
558
- if non_library_xcconfig? || (target.should_build? && target.build_as_dynamic?)
562
+ if library_xcconfig? && (target.should_build? && target.build_as_dynamic?)
559
563
  frameworks.concat vendored_static_frameworks.map { |l| File.basename(l, '.framework') }
560
564
  end
561
565
  if non_library_xcconfig?
562
- frameworks.concat vendored_dynamic_frameworks.map { |l| File.basename(l, '.framework') }
563
- frameworks.concat dependent_targets.flat_map { |pt| pt.build_settings.frameworks_to_import }
566
+ frameworks.concat dependent_targets_to_link.flat_map { |pt| pt.build_settings.frameworks_to_import }
564
567
  end
565
568
  frameworks
566
569
  end
@@ -665,7 +668,7 @@ module Pod
665
668
  end
666
669
  if non_library_xcconfig?
667
670
  libraries.concat dependent_targets.flat_map { |pt| pt.build_settings.dynamic_libraries_to_import }
668
- libraries.concat dependent_targets.flat_map { |pt| pt.build_settings.static_libraries_to_import }
671
+ libraries.concat dependent_targets_to_link.flat_map { |pt| pt.build_settings.static_libraries_to_import }
669
672
  end
670
673
  libraries
671
674
  end
@@ -865,6 +868,17 @@ module Pod
865
868
  )
866
869
  end
867
870
 
871
+ # @return [Array<PodTarget>]
872
+ define_build_settings_method :dependent_targets_to_link, :memoized => true do
873
+ if test_xcconfig?
874
+ # we're embedding into an app defined by an app spec
875
+ host_targets = target.app_host_dependent_targets_for_spec(non_library_spec)
876
+ dependent_targets - host_targets
877
+ else
878
+ dependent_targets
879
+ end
880
+ end
881
+
868
882
  # Returns the +pod_target_xcconfig+ for the pod target and its spec
869
883
  # consumers grouped by keys
870
884
  #
@@ -884,17 +898,26 @@ module Pod
884
898
  # @return [Hash{String, String}]
885
899
  #
886
900
  define_build_settings_method :merged_pod_target_xcconfigs, :memoized => true do
887
- merged_xcconfigs(pod_target_xcconfig_values_by_consumer_by_key, :pod_target_xcconfig)
901
+ merged_xcconfigs(pod_target_xcconfig_values_by_consumer_by_key, :pod_target_xcconfig,
902
+ :overriding => non_library_xcconfig? ? target.build_settings.merged_pod_target_xcconfigs : {})
888
903
  end
889
904
 
890
905
  # @return [Array<Sandbox::FileAccessor>]
891
906
  define_build_settings_method :file_accessors, :memoized => true do
892
- target.file_accessors.select { |fa| fa.spec.spec_type == @xcconfig_spec_type }
907
+ if non_library_xcconfig?
908
+ target.file_accessors.select { |fa| non_library_spec == fa.spec }
909
+ else
910
+ target.file_accessors.select { |fa| fa.spec.spec_type == @xcconfig_spec_type }
911
+ end
893
912
  end
894
913
 
895
914
  # @return [Array<Specification::Consumer>]
896
915
  define_build_settings_method :spec_consumers, :memoized => true do
897
- target.spec_consumers.select { |fa| fa.spec.spec_type == @xcconfig_spec_type }
916
+ if non_library_xcconfig?
917
+ target.spec_consumers.select { |sc| non_library_spec == sc.spec }
918
+ else
919
+ target.spec_consumers.select { |sc| sc.spec.spec_type == @xcconfig_spec_type }
920
+ end
898
921
  end
899
922
 
900
923
  #-------------------------------------------------------------------------#