cocoapods 0.37.2 → 0.38.0.beta.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +136 -1
- data/lib/cocoapods.rb +0 -5
- data/lib/cocoapods/command.rb +3 -0
- data/lib/cocoapods/command/cache.rb +28 -0
- data/lib/cocoapods/command/cache/clean.rb +90 -0
- data/lib/cocoapods/command/cache/list.rb +69 -0
- data/lib/cocoapods/command/lib.rb +11 -4
- data/lib/cocoapods/command/list.rb +4 -4
- data/lib/cocoapods/command/outdated.rb +1 -10
- data/lib/cocoapods/command/project.rb +3 -2
- data/lib/cocoapods/command/spec.rb +0 -17
- data/lib/cocoapods/command/spec/cat.rb +1 -1
- data/lib/cocoapods/command/spec/create.rb +1 -0
- data/lib/cocoapods/command/spec/edit.rb +1 -1
- data/lib/cocoapods/command/spec/lint.rb +10 -4
- data/lib/cocoapods/config.rb +6 -0
- data/lib/cocoapods/downloader/cache.rb +48 -1
- data/lib/cocoapods/executable.rb +27 -6
- data/lib/cocoapods/gem_version.rb +1 -1
- data/lib/cocoapods/generator/copy_resources_script.rb +1 -0
- data/lib/cocoapods/generator/embed_frameworks_script.rb +23 -28
- data/lib/cocoapods/generator/header.rb +5 -1
- data/lib/cocoapods/generator/umbrella_header.rb +1 -1
- data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +139 -33
- data/lib/cocoapods/generator/xcconfig/private_pod_xcconfig.rb +2 -2
- data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +3 -3
- data/lib/cocoapods/installer.rb +64 -109
- data/lib/cocoapods/installer/analyzer.rb +167 -336
- data/lib/cocoapods/installer/analyzer/analysis_result.rb +46 -0
- data/lib/cocoapods/installer/analyzer/specs_state.rb +76 -0
- data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +41 -0
- data/lib/cocoapods/installer/analyzer/target_inspector.rb +203 -0
- data/lib/cocoapods/installer/file_references_installer.rb +48 -13
- data/lib/cocoapods/installer/podfile_validator.rb +86 -0
- data/lib/cocoapods/installer/{hooks_context.rb → post_install_hooks_context.rb} +3 -3
- data/lib/cocoapods/installer/pre_install_hooks_context.rb +41 -0
- data/lib/cocoapods/installer/target_installer.rb +1 -7
- data/lib/cocoapods/installer/target_installer/aggregate_target_installer.rb +15 -17
- data/lib/cocoapods/installer/target_installer/pod_target_installer.rb +4 -4
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +16 -16
- data/lib/cocoapods/sandbox/file_accessor.rb +20 -2
- data/lib/cocoapods/sandbox/path_list.rb +15 -13
- data/lib/cocoapods/sandbox/podspec_finder.rb +1 -0
- data/lib/cocoapods/sources_manager.rb +2 -0
- data/lib/cocoapods/target.rb +7 -37
- data/lib/cocoapods/target/aggregate_target.rb +25 -1
- data/lib/cocoapods/target/pod_target.rb +106 -10
- data/lib/cocoapods/user_interface.rb +26 -0
- data/lib/cocoapods/user_interface/error_report.rb +6 -0
- data/lib/cocoapods/validator.rb +22 -0
- metadata +21 -16
- data/lib/cocoapods/generator/target_environment_header.rb +0 -171
- data/lib/cocoapods/hooks/installer_representation.rb +0 -133
- data/lib/cocoapods/hooks/library_representation.rb +0 -93
- data/lib/cocoapods/hooks/pod_representation.rb +0 -70
@@ -60,13 +60,13 @@ module Pod
|
|
60
60
|
# 'USE_HEADERMAP' => 'NO'
|
61
61
|
}
|
62
62
|
|
63
|
-
if target.requires_frameworks?
|
63
|
+
if target.requires_frameworks? && target.scoped?
|
64
64
|
# Only quote the FRAMEWORK_SEARCH_PATHS entry, because it’s a setting that takes multiple values.
|
65
65
|
# In addition, quoting CONFIGURATION_BUILD_DIR would make it be interpreted as a relative path.
|
66
66
|
build_settings = {
|
67
67
|
'PODS_FRAMEWORK_BUILD_PATH' => target.configuration_build_dir,
|
68
|
-
'CONFIGURATION_BUILD_DIR' => '$PODS_FRAMEWORK_BUILD_PATH',
|
69
68
|
'FRAMEWORK_SEARCH_PATHS' => '"$PODS_FRAMEWORK_BUILD_PATH"',
|
69
|
+
'CONFIGURATION_BUILD_DIR' => '$PODS_FRAMEWORK_BUILD_PATH',
|
70
70
|
}
|
71
71
|
config.merge!(build_settings)
|
72
72
|
end
|
@@ -33,7 +33,7 @@ module Pod
|
|
33
33
|
#
|
34
34
|
def self.default_ld_flags(target)
|
35
35
|
ld_flags = '-ObjC'
|
36
|
-
if target.
|
36
|
+
if target.podfile.set_arc_compatibility_flag? &&
|
37
37
|
target.spec_consumers.any?(&:requires_arc?)
|
38
38
|
ld_flags << ' -fobjc-arc'
|
39
39
|
end
|
@@ -70,7 +70,7 @@ module Pod
|
|
70
70
|
# The xcconfig to edit.
|
71
71
|
#
|
72
72
|
def self.add_spec_build_settings_to_xcconfig(consumer, xcconfig)
|
73
|
-
xcconfig.merge!(consumer.
|
73
|
+
xcconfig.merge!(consumer.pod_target_xcconfig)
|
74
74
|
xcconfig.libraries.merge(consumer.libraries)
|
75
75
|
xcconfig.frameworks.merge(consumer.frameworks)
|
76
76
|
xcconfig.weak_frameworks.merge(consumer.weak_frameworks)
|
@@ -189,7 +189,7 @@ module Pod
|
|
189
189
|
search_paths = xcconfig.attributes['FRAMEWORK_SEARCH_PATHS'] ||= ''
|
190
190
|
search_paths_to_add = []
|
191
191
|
search_paths_to_add << '$(inherited)'
|
192
|
-
if platform == :ios
|
192
|
+
if platform == :ios || platform == :watchos
|
193
193
|
search_paths_to_add << '"$(SDKROOT)/Developer/Library/Frameworks"'
|
194
194
|
else
|
195
195
|
search_paths_to_add << '"$(DEVELOPER_LIBRARY_DIR)/Frameworks"'
|
data/lib/cocoapods/installer.rb
CHANGED
@@ -31,8 +31,10 @@ module Pod
|
|
31
31
|
autoload :AggregateTargetInstaller, 'cocoapods/installer/target_installer/aggregate_target_installer'
|
32
32
|
autoload :Analyzer, 'cocoapods/installer/analyzer'
|
33
33
|
autoload :FileReferencesInstaller, 'cocoapods/installer/file_references_installer'
|
34
|
-
autoload :
|
34
|
+
autoload :PostInstallHooksContext, 'cocoapods/installer/post_install_hooks_context'
|
35
|
+
autoload :PreInstallHooksContext, 'cocoapods/installer/pre_install_hooks_context'
|
35
36
|
autoload :Migrator, 'cocoapods/installer/migrator'
|
37
|
+
autoload :PodfileValidator, 'cocoapods/installer/podfile_validator'
|
36
38
|
autoload :PodSourceInstaller, 'cocoapods/installer/pod_source_installer'
|
37
39
|
autoload :PodSourcePreparer, 'cocoapods/installer/pod_source_preparer'
|
38
40
|
autoload :PodTargetInstaller, 'cocoapods/installer/target_installer/pod_target_installer'
|
@@ -106,12 +108,19 @@ module Pod
|
|
106
108
|
sandbox.prepare
|
107
109
|
ensure_plugins_are_installed!
|
108
110
|
Migrator.migrate(sandbox)
|
111
|
+
run_plugins_pre_install_hooks
|
109
112
|
end
|
110
113
|
end
|
111
114
|
|
112
115
|
def resolve_dependencies
|
116
|
+
analyzer = create_analyzer
|
117
|
+
|
118
|
+
UI.section 'Updating local specs repositories' do
|
119
|
+
analyzer.update_repositories
|
120
|
+
end unless config.skip_repo_update?
|
121
|
+
|
113
122
|
UI.section 'Analyzing dependencies' do
|
114
|
-
analyze
|
123
|
+
analyze(analyzer)
|
115
124
|
validate_build_configurations
|
116
125
|
prepare_for_legacy_compatibility
|
117
126
|
clean_sandbox
|
@@ -122,7 +131,7 @@ module Pod
|
|
122
131
|
UI.section 'Downloading dependencies' do
|
123
132
|
create_file_accessors
|
124
133
|
install_pod_sources
|
125
|
-
|
134
|
+
run_podfile_pre_install_hooks
|
126
135
|
clean_pod_sources
|
127
136
|
lock_pod_sources
|
128
137
|
end
|
@@ -160,11 +169,19 @@ module Pod
|
|
160
169
|
#
|
161
170
|
attr_reader :names_of_pods_to_install
|
162
171
|
|
163
|
-
# @return [Array<AggregateTarget>] The
|
164
|
-
#
|
172
|
+
# @return [Array<AggregateTarget>] The model representations of an
|
173
|
+
# aggregation of pod targets generated for a target definition
|
174
|
+
# in the Podfile as result of the analyzer.
|
165
175
|
#
|
166
176
|
attr_reader :aggregate_targets
|
167
177
|
|
178
|
+
# @return [Array<PodTarget>] The model representations of pod targets
|
179
|
+
# generated as result of the analyzer.
|
180
|
+
#
|
181
|
+
def pod_targets
|
182
|
+
aggregate_targets.map(&:pod_targets).flatten.uniq
|
183
|
+
end
|
184
|
+
|
168
185
|
# @return [Array<Specification>] The specifications that where installed.
|
169
186
|
#
|
170
187
|
attr_accessor :installed_specs
|
@@ -179,33 +196,27 @@ module Pod
|
|
179
196
|
#
|
180
197
|
# @return [void]
|
181
198
|
#
|
182
|
-
|
183
|
-
# `UI.warn` method because it prints the output only at the end
|
184
|
-
# of the installation. At that time CocoaPods could have crashed.
|
185
|
-
#
|
186
|
-
def analyze
|
187
|
-
if lockfile && lockfile.cocoapods_version > Version.new(VERSION)
|
188
|
-
STDERR.puts '[!] The version of CocoaPods used to generate ' \
|
189
|
-
"the lockfile (#{lockfile.cocoapods_version}) is "\
|
190
|
-
"higher than the version of the current executable (#{VERSION}). " \
|
191
|
-
'Incompatibility issues may arise.'.yellow
|
192
|
-
end
|
193
|
-
|
194
|
-
analyzer = Analyzer.new(sandbox, podfile, lockfile)
|
199
|
+
def analyze(analyzer = create_analyzer)
|
195
200
|
analyzer.update = update
|
196
201
|
@analysis_result = analyzer.analyze
|
197
202
|
@aggregate_targets = analyzer.result.targets
|
198
203
|
end
|
199
204
|
|
205
|
+
def create_analyzer
|
206
|
+
Analyzer.new(sandbox, podfile, lockfile)
|
207
|
+
end
|
208
|
+
|
200
209
|
# Ensures that the white-listed build configurations are known to prevent
|
201
210
|
# silent typos.
|
202
211
|
#
|
203
212
|
# @raise If an unknown user configuration is found.
|
204
213
|
#
|
205
214
|
def validate_build_configurations
|
206
|
-
whitelisted_configs = pod_targets.
|
207
|
-
|
208
|
-
|
215
|
+
whitelisted_configs = pod_targets.
|
216
|
+
flat_map(&:target_definitions).
|
217
|
+
flat_map(&:all_whitelisted_configurations).
|
218
|
+
map(&:downcase).
|
219
|
+
uniq
|
209
220
|
all_user_configurations = analysis_result.all_user_build_configurations.keys.map(&:downcase)
|
210
221
|
|
211
222
|
remainder = whitelisted_configs - all_user_configurations
|
@@ -251,16 +262,14 @@ module Pod
|
|
251
262
|
# created by the Pod source installer as well.
|
252
263
|
#
|
253
264
|
def create_file_accessors
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
Sandbox::FileAccessor.new(path_list, spec.consumer(pod_target.platform))
|
260
|
-
end
|
261
|
-
pod_target.file_accessors ||= []
|
262
|
-
pod_target.file_accessors.concat(file_accessors)
|
265
|
+
pod_targets.each do |pod_target|
|
266
|
+
pod_root = sandbox.pod_dir(pod_target.root_spec.name)
|
267
|
+
path_list = Sandbox::PathList.new(pod_root)
|
268
|
+
file_accessors = pod_target.specs.map do |spec|
|
269
|
+
Sandbox::FileAccessor.new(path_list, spec.consumer(pod_target.platform))
|
263
270
|
end
|
271
|
+
pod_target.file_accessors ||= []
|
272
|
+
pod_target.file_accessors.concat(file_accessors)
|
264
273
|
end
|
265
274
|
end
|
266
275
|
|
@@ -342,7 +351,7 @@ module Pod
|
|
342
351
|
def determine_dependency_product_types
|
343
352
|
aggregate_targets.each do |aggregate_target|
|
344
353
|
aggregate_target.pod_targets.each do |pod_target|
|
345
|
-
pod_target.host_requires_frameworks
|
354
|
+
pod_target.host_requires_frameworks ||= aggregate_target.requires_frameworks?
|
346
355
|
end
|
347
356
|
end
|
348
357
|
end
|
@@ -371,7 +380,7 @@ module Pod
|
|
371
380
|
aggregate_target.user_build_configurations.keys.each do |config|
|
372
381
|
pod_targets = aggregate_target.pod_targets_for_build_configuration(config)
|
373
382
|
|
374
|
-
dependencies = pod_targets.flat_map(&:dependencies)
|
383
|
+
dependencies = pod_targets.select(&:should_build?).flat_map(&:dependencies)
|
375
384
|
dependended_upon_targets = pod_targets.select { |t| dependencies.include?(t.pod_name) && !t.should_build? }
|
376
385
|
|
377
386
|
static_libs = dependended_upon_targets.flat_map(&:file_accessors).flat_map do |fa|
|
@@ -403,6 +412,15 @@ module Pod
|
|
403
412
|
end
|
404
413
|
end
|
405
414
|
|
415
|
+
# Runs the registered callbacks for the plugins pre install hooks.
|
416
|
+
#
|
417
|
+
# @return [void]
|
418
|
+
#
|
419
|
+
def run_plugins_pre_install_hooks
|
420
|
+
context = PreInstallHooksContext.generate(sandbox, podfile, lockfile)
|
421
|
+
HooksManager.run(:pre_install, context, podfile.plugins)
|
422
|
+
end
|
423
|
+
|
406
424
|
# Performs any post-installation actions
|
407
425
|
#
|
408
426
|
# @return [void]
|
@@ -415,7 +433,7 @@ module Pod
|
|
415
433
|
# Runs the registered callbacks for the plugins post install hooks.
|
416
434
|
#
|
417
435
|
def run_plugins_post_install_hooks
|
418
|
-
context =
|
436
|
+
context = PostInstallHooksContext.generate(sandbox, aggregate_targets)
|
419
437
|
HooksManager.run(:post_install, context, podfile.plugins)
|
420
438
|
end
|
421
439
|
|
@@ -491,9 +509,11 @@ module Pod
|
|
491
509
|
platforms = aggregate_targets.map(&:platform)
|
492
510
|
osx_deployment_target = platforms.select { |p| p.name == :osx }.map(&:deployment_target).min
|
493
511
|
ios_deployment_target = platforms.select { |p| p.name == :ios }.map(&:deployment_target).min
|
512
|
+
watchos_deployment_target = platforms.select { |p| p.name == :watchos }.map(&:deployment_target).min
|
494
513
|
@pods_project.build_configurations.each do |build_configuration|
|
495
514
|
build_configuration.build_settings['MACOSX_DEPLOYMENT_TARGET'] = osx_deployment_target.to_s if osx_deployment_target
|
496
515
|
build_configuration.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = ios_deployment_target.to_s if ios_deployment_target
|
516
|
+
build_configuration.build_settings['WATCHOS_DEPLOYMENT_TARGET'] = watchos_deployment_target.to_s if watchos_deployment_target
|
497
517
|
build_configuration.build_settings['STRIP_INSTALLED_PRODUCT'] = 'NO'
|
498
518
|
build_configuration.build_settings['CLANG_ENABLE_OBJC_ARC'] = 'YES'
|
499
519
|
end
|
@@ -519,7 +539,7 @@ module Pod
|
|
519
539
|
def install_libraries
|
520
540
|
UI.message '- Installing targets' do
|
521
541
|
pod_targets.sort_by(&:name).each do |pod_target|
|
522
|
-
next if pod_target.
|
542
|
+
next if pod_target.target_definitions.flat_map(&:dependencies).empty?
|
523
543
|
target_installer = PodTargetInstaller.new(sandbox, pod_target)
|
524
544
|
target_installer.install!
|
525
545
|
end
|
@@ -610,12 +630,8 @@ module Pod
|
|
610
630
|
# @return [void]
|
611
631
|
#
|
612
632
|
def share_development_pod_schemes
|
613
|
-
development_pod_targets
|
614
|
-
pods_project.
|
615
|
-
end.flatten
|
616
|
-
|
617
|
-
development_pod_targets.each do |pod_target|
|
618
|
-
Xcodeproj::XCScheme.share_scheme(pods_project.path, pod_target.name)
|
633
|
+
development_pod_targets.select(&:should_build?).each do |pod_target|
|
634
|
+
Xcodeproj::XCScheme.share_scheme(pods_project.path, pod_target.label)
|
619
635
|
end
|
620
636
|
end
|
621
637
|
|
@@ -671,7 +687,7 @@ module Pod
|
|
671
687
|
#
|
672
688
|
# @return [void]
|
673
689
|
#
|
674
|
-
def
|
690
|
+
def run_podfile_pre_install_hooks
|
675
691
|
UI.message '- Running pre install hooks' do
|
676
692
|
executed = run_podfile_pre_install_hook
|
677
693
|
UI.message '- Podfile' if executed
|
@@ -685,7 +701,7 @@ module Pod
|
|
685
701
|
# @return [Bool] Whether the hook was run.
|
686
702
|
#
|
687
703
|
def run_podfile_pre_install_hook
|
688
|
-
podfile.pre_install!(
|
704
|
+
podfile.pre_install!(self)
|
689
705
|
rescue => e
|
690
706
|
raise Informative, 'An error occurred while processing the pre-install ' \
|
691
707
|
'hook of the Podfile.' \
|
@@ -713,7 +729,7 @@ module Pod
|
|
713
729
|
# @return [Bool] Whether the hook was run.
|
714
730
|
#
|
715
731
|
def run_podfile_post_install_hook
|
716
|
-
podfile.post_install!(
|
732
|
+
podfile.post_install!(self)
|
717
733
|
rescue => e
|
718
734
|
raise Informative, 'An error occurred while processing the post-install ' \
|
719
735
|
'hook of the Podfile.' \
|
@@ -724,76 +740,15 @@ module Pod
|
|
724
740
|
|
725
741
|
public
|
726
742
|
|
727
|
-
#
|
728
|
-
|
729
|
-
# Creates a hook representation for this installer.
|
730
|
-
#
|
731
|
-
# @return [InstallerRepresentation]
|
732
|
-
#
|
733
|
-
def installer_rep
|
734
|
-
Hooks::InstallerRepresentation.new(self)
|
735
|
-
end
|
736
|
-
|
737
|
-
# Creates a hook representation for a Pod.
|
743
|
+
# @return [Array<Library>] The targets of the development pods generated by
|
744
|
+
# the installation process.
|
738
745
|
#
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
# @return [PodRepresentation]
|
743
|
-
#
|
744
|
-
def pod_rep(pod)
|
745
|
-
all_file_accessors = pod_targets.map(&:file_accessors).flatten.compact
|
746
|
-
file_accessors = all_file_accessors.select { |fa| fa.spec.root.name == pod }
|
747
|
-
Hooks::PodRepresentation.new(pod, file_accessors)
|
748
|
-
end
|
749
|
-
|
750
|
-
# Creates a hook representation for a given aggregate target.
|
751
|
-
#
|
752
|
-
# @param [AggregateTarget] aggregate_target
|
753
|
-
# the aggregate target
|
754
|
-
#
|
755
|
-
# @return [LibraryRepresentation]
|
756
|
-
#
|
757
|
-
def library_rep(aggregate_target)
|
758
|
-
Hooks::LibraryRepresentation.new(sandbox, aggregate_target)
|
759
|
-
end
|
760
|
-
|
761
|
-
# Creates hook representations for all aggregate targets.
|
762
|
-
#
|
763
|
-
# @return [Array<LibraryRepresentation>]
|
764
|
-
#
|
765
|
-
def library_reps
|
766
|
-
@library_reps ||= aggregate_targets.map { |lib| library_rep(lib) }
|
767
|
-
end
|
768
|
-
|
769
|
-
# Creates hook representations for all #root_specs.
|
770
|
-
#
|
771
|
-
# @return [Array<PodRepresentation>]
|
772
|
-
#
|
773
|
-
def pod_reps
|
774
|
-
root_specs.sort_by(&:name).map { |spec| pod_rep(spec.name) }
|
775
|
-
end
|
776
|
-
|
777
|
-
# Returns the libraries which use the given specification.
|
778
|
-
#
|
779
|
-
# @param [Specification] spec
|
780
|
-
# The specification for which the client libraries are needed.
|
781
|
-
#
|
782
|
-
# @return [Array<Library>] The library.
|
783
|
-
#
|
784
|
-
def libraries_using_spec(spec)
|
785
|
-
aggregate_targets.select do |aggregate_target|
|
786
|
-
aggregate_target.pod_targets.any? { |pod_target| pod_target.specs.include?(spec) }
|
746
|
+
def development_pod_targets
|
747
|
+
pod_targets.select do |pod_target|
|
748
|
+
sandbox.development_pods.keys.include?(pod_target.pod_name)
|
787
749
|
end
|
788
750
|
end
|
789
751
|
|
790
|
-
# @return [Array<Library>] The libraries generated by the installation
|
791
|
-
# process.
|
792
|
-
#
|
793
|
-
def pod_targets
|
794
|
-
aggregate_targets.map(&:pod_targets).flatten
|
795
|
-
end
|
796
|
-
|
797
752
|
#-------------------------------------------------------------------------#
|
798
753
|
|
799
754
|
private
|
@@ -6,9 +6,12 @@ module Pod
|
|
6
6
|
class Analyzer
|
7
7
|
include Config::Mixin
|
8
8
|
|
9
|
-
autoload :
|
10
|
-
|
9
|
+
autoload :AnalysisResult, 'cocoapods/installer/analyzer/analysis_result'
|
10
|
+
autoload :SandboxAnalyzer, 'cocoapods/installer/analyzer/sandbox_analyzer'
|
11
|
+
autoload :SpecsState, 'cocoapods/installer/analyzer/specs_state'
|
11
12
|
autoload :LockingDependencyAnalyzer, 'cocoapods/installer/analyzer/locking_dependency_analyzer'
|
13
|
+
autoload :TargetInspectionResult, 'cocoapods/installer/analyzer/target_inspection_result'
|
14
|
+
autoload :TargetInspector, 'cocoapods/installer/analyzer/target_inspector'
|
12
15
|
|
13
16
|
# @return [Sandbox] The sandbox where the Pods should be installed.
|
14
17
|
#
|
@@ -37,7 +40,6 @@ module Pod
|
|
37
40
|
|
38
41
|
@update = false
|
39
42
|
@allow_pre_downloads = true
|
40
|
-
@archs_by_target_def = {}
|
41
43
|
end
|
42
44
|
|
43
45
|
# Performs the analysis.
|
@@ -52,9 +54,14 @@ module Pod
|
|
52
54
|
# @return [AnalysisResult]
|
53
55
|
#
|
54
56
|
def analyze(allow_fetches = true)
|
55
|
-
|
57
|
+
validate_podfile!
|
58
|
+
validate_lockfile_version!
|
56
59
|
@result = AnalysisResult.new
|
57
|
-
|
60
|
+
if config.integrate_targets?
|
61
|
+
@result.target_inspections = inspect_targets_to_integrate
|
62
|
+
else
|
63
|
+
verify_platforms_specified!
|
64
|
+
end
|
58
65
|
@result.podfile_state = generate_podfile_state
|
59
66
|
@locked_dependencies = generate_version_locking_dependencies
|
60
67
|
|
@@ -143,8 +150,30 @@ module Pod
|
|
143
150
|
|
144
151
|
private
|
145
152
|
|
153
|
+
def validate_podfile!
|
154
|
+
validator = Installer::PodfileValidator.new(podfile)
|
155
|
+
validator.validate
|
156
|
+
|
157
|
+
unless validator.valid?
|
158
|
+
raise Informative, validator.message
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
146
162
|
# @!group Analysis steps
|
147
163
|
|
164
|
+
# @note The warning about the version of the Lockfile doesn't use the
|
165
|
+
# `UI.warn` method because it prints the output only at the end
|
166
|
+
# of the installation. At that time CocoaPods could have crashed.
|
167
|
+
#
|
168
|
+
def validate_lockfile_version!
|
169
|
+
if lockfile && lockfile.cocoapods_version > Version.new(VERSION)
|
170
|
+
STDERR.puts '[!] The version of CocoaPods used to generate ' \
|
171
|
+
"the lockfile (#{lockfile.cocoapods_version}) is "\
|
172
|
+
"higher than the version of the current executable (#{VERSION}). " \
|
173
|
+
'Incompatibility issues may arise.'.yellow
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
148
177
|
# Compares the {Podfile} with the {Lockfile} in order to detect which
|
149
178
|
# dependencies should be locked.
|
150
179
|
#
|
@@ -174,32 +203,31 @@ module Pod
|
|
174
203
|
end
|
175
204
|
end
|
176
205
|
|
206
|
+
public
|
207
|
+
|
177
208
|
# Updates the git source repositories unless the config indicates to skip it.
|
178
209
|
#
|
179
|
-
def
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
else
|
186
|
-
UI.message "Skipping `#{source.name}` update because the repository is not a git source repository."
|
187
|
-
end
|
188
|
-
end
|
210
|
+
def update_repositories
|
211
|
+
sources.each do |source|
|
212
|
+
if SourcesManager.git_repo?(source.repo)
|
213
|
+
SourcesManager.update(source.name)
|
214
|
+
else
|
215
|
+
UI.message "Skipping `#{source.name}` update because the repository is not a git source repository."
|
189
216
|
end
|
190
217
|
end
|
191
218
|
end
|
192
219
|
|
193
|
-
|
220
|
+
private
|
221
|
+
|
222
|
+
# Creates the models that represent the targets generated by CocoaPods.
|
194
223
|
#
|
195
|
-
# @return [Array<
|
224
|
+
# @return [Array<AggregateTarget>]
|
196
225
|
#
|
197
226
|
def generate_targets
|
198
|
-
|
199
|
-
result.specs_by_target.
|
200
|
-
|
227
|
+
pod_targets = generate_pod_targets(result.specs_by_target)
|
228
|
+
result.specs_by_target.map do |target_definition, _|
|
229
|
+
generate_target(target_definition, pod_targets)
|
201
230
|
end
|
202
|
-
targets
|
203
231
|
end
|
204
232
|
|
205
233
|
# Setup the aggregate target for a single user target
|
@@ -207,26 +235,22 @@ module Pod
|
|
207
235
|
# @param [TargetDefinition] target_definition
|
208
236
|
# the target definition for the user target.
|
209
237
|
#
|
210
|
-
# @param [Array<
|
211
|
-
# the
|
212
|
-
# given target definition.
|
238
|
+
# @param [Array<PodTarget>] pod_targets
|
239
|
+
# the pod targets, which were generated.
|
213
240
|
#
|
214
241
|
# @return [AggregateTarget]
|
215
242
|
#
|
216
|
-
def generate_target(target_definition,
|
243
|
+
def generate_target(target_definition, pod_targets)
|
217
244
|
target = AggregateTarget.new(target_definition, sandbox)
|
218
245
|
target.host_requires_frameworks |= target_definition.uses_frameworks?
|
219
246
|
|
220
247
|
if config.integrate_targets?
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
target.
|
226
|
-
target.
|
227
|
-
target.user_target_uuids = native_targets.map(&:uuid)
|
228
|
-
target.user_build_configurations = compute_user_build_configurations(target_definition, native_targets)
|
229
|
-
target.archs = @archs_by_target_def[target_definition]
|
248
|
+
target_inspection = result.target_inspections[target_definition]
|
249
|
+
target.user_project_path = target_inspection.project_path
|
250
|
+
target.client_root = target.user_project_path.dirname
|
251
|
+
target.user_target_uuids = target_inspection.project_target_uuids
|
252
|
+
target.user_build_configurations = target_inspection.build_configurations
|
253
|
+
target.archs = target_inspection.archs
|
230
254
|
else
|
231
255
|
target.client_root = config.installation_root
|
232
256
|
target.user_target_uuids = []
|
@@ -236,48 +260,119 @@ module Pod
|
|
236
260
|
end
|
237
261
|
end
|
238
262
|
|
239
|
-
target.pod_targets =
|
240
|
-
|
263
|
+
target.pod_targets = pod_targets.select do |pod_target|
|
264
|
+
pod_target.target_definitions.include?(target_definition)
|
265
|
+
end
|
241
266
|
target
|
242
267
|
end
|
243
268
|
|
244
|
-
# Setup the pod targets for an aggregate target.
|
245
|
-
# by
|
269
|
+
# Setup the pod targets for an aggregate target. Deduplicates resulting
|
270
|
+
# targets by grouping by grouping by platform and subspec by their root
|
271
|
+
# to create a {PodTarget} for each spec.
|
246
272
|
#
|
247
|
-
# @param [
|
248
|
-
# the
|
273
|
+
# @param [Hash{Podfile::TargetDefinition => Array<Specification>}] specs_by_target
|
274
|
+
# the resolved specifications grouped by target.
|
249
275
|
#
|
250
|
-
# @
|
251
|
-
#
|
276
|
+
# @return [Array<PodTarget>]
|
277
|
+
#
|
278
|
+
def generate_pod_targets(specs_by_target)
|
279
|
+
if config.deduplicate_targets?
|
280
|
+
all_specs = specs_by_target.flat_map do |target_definition, dependent_specs|
|
281
|
+
dependent_specs.group_by(&:root).map do |root_spec, specs|
|
282
|
+
[root_spec, specs, target_definition]
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
distinct_targets = all_specs.each_with_object({}) do |dependency, hash|
|
287
|
+
root_spec, specs, target_definition = *dependency
|
288
|
+
hash[root_spec] ||= {}
|
289
|
+
(hash[root_spec][[specs, target_definition.platform]] ||= []) << target_definition
|
290
|
+
end
|
291
|
+
|
292
|
+
pod_targets = distinct_targets.flat_map do |_, targets_by_distinctors|
|
293
|
+
if targets_by_distinctors.count > 1
|
294
|
+
# There are different sets of subspecs or the spec is used across different platforms
|
295
|
+
targets_by_distinctors.map do |distinctor, target_definitions|
|
296
|
+
specs, _ = *distinctor
|
297
|
+
generate_pod_target(target_definitions, specs, :scoped => true)
|
298
|
+
end
|
299
|
+
else
|
300
|
+
(specs, _), target_definitions = targets_by_distinctors.first
|
301
|
+
generate_pod_target(target_definitions, specs)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
# A `PodTarget` can't be deduplicated if any of its
|
306
|
+
# transitive dependencies can't be deduplicated.
|
307
|
+
pod_targets.flat_map do |target|
|
308
|
+
dependent_targets = transitive_dependencies_for_pod_target(target, pod_targets)
|
309
|
+
if dependent_targets.any?(&:scoped?)
|
310
|
+
target.scoped
|
311
|
+
else
|
312
|
+
target
|
313
|
+
end
|
314
|
+
end
|
315
|
+
else
|
316
|
+
specs_by_target.flat_map do |target_definition, specs|
|
317
|
+
grouped_specs = specs.group_by.group_by(&:root).values.uniq
|
318
|
+
grouped_specs.flat_map do |pod_specs|
|
319
|
+
generate_pod_target([target_definition], pod_specs, :scoped => true)
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
# Finds the names of the Pods upon which the given target _transitively_
|
326
|
+
# depends.
|
327
|
+
#
|
328
|
+
# @note: This is implemented in the analyzer, because we don't have to
|
329
|
+
# care about the requirements after dependency resolution.
|
330
|
+
#
|
331
|
+
# @param [PodTarget] pod_target
|
332
|
+
# The pod target, whose dependencies should be returned.
|
333
|
+
#
|
334
|
+
# @param [Array<PodTarget>] targets
|
335
|
+
# All pod targets, which are integrated alongside.
|
252
336
|
#
|
253
337
|
# @return [Array<PodTarget>]
|
254
338
|
#
|
255
|
-
def
|
256
|
-
|
257
|
-
|
258
|
-
|
339
|
+
def transitive_dependencies_for_pod_target(pod_target, targets)
|
340
|
+
if targets.any?
|
341
|
+
dependent_targets = pod_target.dependencies.flat_map do |dep|
|
342
|
+
targets.select { |t| t.pod_name == dep }
|
343
|
+
end
|
344
|
+
remaining_targets = targets - dependent_targets
|
345
|
+
dependent_targets + dependent_targets.flat_map do |target|
|
346
|
+
transitive_dependencies_for_pod_target(target, remaining_targets)
|
347
|
+
end
|
348
|
+
else
|
349
|
+
[]
|
259
350
|
end
|
260
351
|
end
|
261
352
|
|
262
|
-
# Create a target for each spec group
|
353
|
+
# Create a target for each spec group
|
263
354
|
#
|
264
|
-
# @param [
|
355
|
+
# @param [TargetDefinitions] target_definitions
|
265
356
|
# the aggregate target
|
266
357
|
#
|
267
358
|
# @param [Array<Specification>] specs
|
268
359
|
# the specifications of an equal root.
|
269
360
|
#
|
361
|
+
# @param [Bool] scoped
|
362
|
+
# whether the pod target should be scoped
|
363
|
+
#
|
270
364
|
# @return [PodTarget]
|
271
365
|
#
|
272
|
-
def generate_pod_target(
|
273
|
-
pod_target = PodTarget.new(pod_specs,
|
366
|
+
def generate_pod_target(target_definitions, pod_specs, scoped: false)
|
367
|
+
pod_target = PodTarget.new(pod_specs, target_definitions, sandbox, scoped)
|
274
368
|
|
275
369
|
if config.integrate_targets?
|
276
|
-
|
277
|
-
pod_target.
|
370
|
+
target_inspections = result.target_inspections.select { |t, _| target_definitions.include?(t) }.values
|
371
|
+
pod_target.user_build_configurations = target_inspections.map(&:build_configurations).reduce({}, &:merge)
|
372
|
+
pod_target.archs = target_inspections.flat_map(&:archs).compact.uniq.sort
|
278
373
|
else
|
279
374
|
pod_target.user_build_configurations = {}
|
280
|
-
if
|
375
|
+
if target_definitions.first.platform.name == :osx
|
281
376
|
pod_target.archs = '$(ARCHS_STANDARD_64_BIT)'
|
282
377
|
end
|
283
378
|
end
|
@@ -438,6 +533,7 @@ module Pod
|
|
438
533
|
UI.section "Resolving dependencies of #{UI.path podfile.defined_in_file}" do
|
439
534
|
resolver = Resolver.new(sandbox, podfile, locked_dependencies, sources)
|
440
535
|
specs_by_target = resolver.resolve
|
536
|
+
specs_by_target.values.flatten(1).each(&:validate_cocoapods_version)
|
441
537
|
end
|
442
538
|
specs_by_target
|
443
539
|
end
|
@@ -529,305 +625,40 @@ module Pod
|
|
529
625
|
|
530
626
|
# @!group Analysis sub-steps
|
531
627
|
|
532
|
-
#
|
533
|
-
# should integrate.
|
534
|
-
#
|
535
|
-
# @raise If the project is implicit and there are multiple projects.
|
536
|
-
#
|
537
|
-
# @raise If the path doesn't exits.
|
538
|
-
#
|
539
|
-
# @return [Pathname] the path of the user project.
|
540
|
-
#
|
541
|
-
def compute_user_project_path(target_definition)
|
542
|
-
if target_definition.user_project_path
|
543
|
-
path = config.installation_root + target_definition.user_project_path
|
544
|
-
path = "#{path}.xcodeproj" unless File.extname(path) == '.xcodeproj'
|
545
|
-
path = Pathname.new(path)
|
546
|
-
unless path.exist?
|
547
|
-
raise Informative, 'Unable to find the Xcode project ' \
|
548
|
-
"`#{path}` for the target `#{target_definition.label}`."
|
549
|
-
end
|
550
|
-
else
|
551
|
-
xcodeprojs = config.installation_root.children.select { |e| e.fnmatch('*.xcodeproj') }
|
552
|
-
if xcodeprojs.size == 1
|
553
|
-
path = xcodeprojs.first
|
554
|
-
else
|
555
|
-
raise Informative, 'Could not automatically select an Xcode project. ' \
|
556
|
-
"Specify one in your Podfile like so:\n\n" \
|
557
|
-
" xcodeproj 'path/to/Project.xcodeproj'\n"
|
558
|
-
end
|
559
|
-
end
|
560
|
-
path
|
561
|
-
end
|
562
|
-
|
563
|
-
# Returns a list of the targets from the project of {TargetDefinition}
|
564
|
-
# that needs to be integrated.
|
628
|
+
# Checks whether the platform is specified if not integrating
|
565
629
|
#
|
566
|
-
# @
|
567
|
-
# the `link_with` option of the {TargetDefinition}. Otherwise
|
568
|
-
# it looks for the target that has the same name of the target
|
569
|
-
# definition. Finally if no target was found the first
|
570
|
-
# encountered target is returned (it is assumed to be the one
|
571
|
-
# to integrate in simple projects).
|
572
|
-
#
|
573
|
-
# @note This will only return targets that do **not** already have
|
574
|
-
# the Pods library in their frameworks build phase.
|
575
|
-
#
|
576
|
-
#
|
577
|
-
def compute_user_project_targets(target_definition, user_project)
|
578
|
-
if link_with = target_definition.link_with
|
579
|
-
targets = native_targets(user_project).select { |t| link_with.include?(t.name) }
|
580
|
-
raise Informative, "Unable to find the targets named `#{link_with.to_sentence}` to link with target definition `#{target_definition.name}`" if targets.empty?
|
581
|
-
elsif target_definition.link_with_first_target?
|
582
|
-
targets = [native_targets(user_project).first].compact
|
583
|
-
raise Informative, 'Unable to find a target' if targets.empty?
|
584
|
-
else
|
585
|
-
target = native_targets(user_project).find { |t| t.name == target_definition.name.to_s }
|
586
|
-
targets = [target].compact
|
587
|
-
raise Informative, "Unable to find a target named `#{target_definition.name}`" if targets.empty?
|
588
|
-
end
|
589
|
-
targets
|
590
|
-
end
|
591
|
-
|
592
|
-
# @return [Array<PBXNativeTarget>] Returns the user’s targets, excluding
|
593
|
-
# aggregate targets.
|
594
|
-
#
|
595
|
-
def native_targets(user_project)
|
596
|
-
user_project.targets.reject do |target|
|
597
|
-
target.is_a? Xcodeproj::Project::Object::PBXAggregateTarget
|
598
|
-
end
|
599
|
-
end
|
600
|
-
|
601
|
-
# Checks if any of the targets for the {TargetDefinition} computed before
|
602
|
-
# by #compute_user_project_targets require to be build as a framework due
|
603
|
-
# the presence of Swift source code in any of the source build phases.
|
604
|
-
#
|
605
|
-
# @param [TargetDefinition] target_definition
|
606
|
-
# the target definition
|
607
|
-
#
|
608
|
-
# @param [Array<PBXNativeTarget>] native_targets
|
609
|
-
# the targets which are checked for presence of Swift source code
|
610
|
-
#
|
611
|
-
# @return [Boolean] Whether the user project targets to integrate into
|
612
|
-
# uses Swift
|
613
|
-
#
|
614
|
-
def compute_user_project_targets_require_framework(target_definition, native_targets)
|
615
|
-
file_predicate = nil
|
616
|
-
file_predicate = proc do |file_ref|
|
617
|
-
if file_ref.respond_to?(:last_known_file_type)
|
618
|
-
file_ref.last_known_file_type == 'sourcecode.swift'
|
619
|
-
elsif file_ref.respond_to?(:files)
|
620
|
-
file_ref.files.any?(&file_predicate)
|
621
|
-
else
|
622
|
-
false
|
623
|
-
end
|
624
|
-
end
|
625
|
-
target_definition.platform.supports_dynamic_frameworks? || native_targets.any? do |target|
|
626
|
-
target.source_build_phase.files.any? do |build_file|
|
627
|
-
file_predicate.call(build_file.file_ref)
|
628
|
-
end
|
629
|
-
end
|
630
|
-
end
|
631
|
-
|
632
|
-
# @return [Hash{String=>Symbol}] A hash representing the user build
|
633
|
-
# configurations where each key corresponds to the name of a
|
634
|
-
# configuration and its value to its type (`:debug` or `:release`).
|
635
|
-
#
|
636
|
-
def compute_user_build_configurations(target_definition, user_targets)
|
637
|
-
if user_targets
|
638
|
-
user_targets.map { |t| t.build_configurations.map(&:name) }.flatten.reduce({}) do |hash, name|
|
639
|
-
hash[name] = name == 'Debug' ? :debug : :release
|
640
|
-
hash
|
641
|
-
end.merge(target_definition.build_configurations || {})
|
642
|
-
else
|
643
|
-
target_definition.build_configurations || {}
|
644
|
-
end
|
645
|
-
end
|
646
|
-
|
647
|
-
# @return [Platform] The platform for the library.
|
648
|
-
#
|
649
|
-
# @note This resolves to the lowest deployment target across the user
|
650
|
-
# targets.
|
651
|
-
#
|
652
|
-
# @todo Is assigning the platform to the target definition the best way
|
653
|
-
# to go?
|
630
|
+
# @return [void]
|
654
631
|
#
|
655
|
-
def
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
name ||= target.platform_name
|
662
|
-
raise Informative, 'Targets with different platforms' unless name == target.platform_name
|
663
|
-
if !deployment_target || deployment_target > Version.new(target.deployment_target)
|
664
|
-
deployment_target = Version.new(target.deployment_target)
|
632
|
+
def verify_platforms_specified!
|
633
|
+
unless config.integrate_targets?
|
634
|
+
podfile.target_definition_list.each do |target_definition|
|
635
|
+
unless target_definition.platform
|
636
|
+
raise Informative, 'It is necessary to specify the platform in the Podfile if not integrating.'
|
637
|
+
end
|
665
638
|
end
|
666
639
|
end
|
667
|
-
|
668
|
-
target_definition.set_platform(name, deployment_target)
|
669
|
-
Platform.new(name, deployment_target)
|
670
|
-
end
|
671
|
-
|
672
|
-
# @return [Platform] The platform for the library.
|
673
|
-
#
|
674
|
-
# @note This resolves to the lowest deployment target across the user
|
675
|
-
# targets.
|
676
|
-
#
|
677
|
-
# @todo Is assigning the platform to the target definition the best way
|
678
|
-
# to go?
|
679
|
-
#
|
680
|
-
def compute_archs_for_target_definition(target_definition, user_targets)
|
681
|
-
archs = []
|
682
|
-
user_targets.each do |target|
|
683
|
-
target_archs = target.common_resolved_build_setting('ARCHS')
|
684
|
-
archs.concat(Array(target_archs))
|
685
|
-
end
|
686
|
-
|
687
|
-
archs = archs.compact.uniq.sort
|
688
|
-
UI.message('Using `ARCHS` setting to build architectures of ' \
|
689
|
-
"target `#{target_definition.label}`: " \
|
690
|
-
"(`#{archs.join('`, `')}`)")
|
691
|
-
archs.length > 1 ? archs : archs.first
|
692
640
|
end
|
693
641
|
|
694
|
-
# Precompute
|
642
|
+
# Precompute information for each target_definition in the Podfile
|
695
643
|
#
|
696
644
|
# @note The platforms are computed and added to each target_definition
|
697
645
|
# because it might be necessary to infer the platform from the
|
698
646
|
# user targets.
|
699
647
|
#
|
700
|
-
# @return [
|
648
|
+
# @return [Hash{TargetDefinition => TargetInspectionResult}]
|
701
649
|
#
|
702
|
-
def
|
650
|
+
def inspect_targets_to_integrate
|
651
|
+
inspection_result = {}
|
703
652
|
UI.section 'Inspecting targets to integrate' do
|
704
653
|
podfile.target_definition_list.each do |target_definition|
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
archs = compute_archs_for_target_definition(target_definition, targets)
|
711
|
-
@archs_by_target_def[target_definition] = archs
|
712
|
-
else
|
713
|
-
unless target_definition.platform
|
714
|
-
raise Informative, 'It is necessary to specify the platform in the Podfile if not integrating.'
|
715
|
-
end
|
716
|
-
end
|
654
|
+
inspector = TargetInspector.new(target_definition, config.installation_root)
|
655
|
+
results = inspector.compute_results
|
656
|
+
inspection_result[target_definition] = results
|
657
|
+
UI.message('Using `ARCHS` setting to build architectures of ' \
|
658
|
+
"target `#{target_definition.label}`: (`#{results.archs.join('`, `')}`)")
|
717
659
|
end
|
718
660
|
end
|
719
|
-
|
720
|
-
|
721
|
-
#-----------------------------------------------------------------------#
|
722
|
-
|
723
|
-
class AnalysisResult
|
724
|
-
# @return [SpecsState] the states of the Podfile specs.
|
725
|
-
#
|
726
|
-
attr_accessor :podfile_state
|
727
|
-
|
728
|
-
# @return [Hash{TargetDefinition => Array<Spec>}] the specifications
|
729
|
-
# grouped by target.
|
730
|
-
#
|
731
|
-
attr_accessor :specs_by_target
|
732
|
-
|
733
|
-
# @return [Array<Specification>] the specifications of the resolved
|
734
|
-
# version of Pods that should be installed.
|
735
|
-
#
|
736
|
-
attr_accessor :specifications
|
737
|
-
|
738
|
-
# @return [SpecsState] the states of the {Sandbox} respect the resolved
|
739
|
-
# specifications.
|
740
|
-
#
|
741
|
-
attr_accessor :sandbox_state
|
742
|
-
|
743
|
-
# @return [Array<Target>] The Podfile targets containing library
|
744
|
-
# dependencies.
|
745
|
-
#
|
746
|
-
attr_accessor :targets
|
747
|
-
|
748
|
-
# @return [Hash{String=>Symbol}] A hash representing all the user build
|
749
|
-
# configurations across all integration targets. Each key
|
750
|
-
# corresponds to the name of a configuration and its value to
|
751
|
-
# its type (`:debug` or `:release`).
|
752
|
-
#
|
753
|
-
def all_user_build_configurations
|
754
|
-
targets.reduce({}) do |result, target|
|
755
|
-
result.merge(target.user_build_configurations)
|
756
|
-
end
|
757
|
-
end
|
758
|
-
end
|
759
|
-
|
760
|
-
#-----------------------------------------------------------------------#
|
761
|
-
|
762
|
-
# This class represents the state of a collection of Pods.
|
763
|
-
#
|
764
|
-
# @note The names of the pods stored by this class are always the **root**
|
765
|
-
# name of the specification.
|
766
|
-
#
|
767
|
-
# @note The motivation for this class is to ensure that the names of the
|
768
|
-
# subspecs are added instead of the name of the Pods.
|
769
|
-
#
|
770
|
-
class SpecsState
|
771
|
-
# Initialize a new instance
|
772
|
-
#
|
773
|
-
# @param [Hash{Symbol=>String}] pods_by_state
|
774
|
-
# The name of the pods grouped by their state
|
775
|
-
# (`:added`, `:removed`, `:changed` or `:unchanged`).
|
776
|
-
#
|
777
|
-
def initialize(pods_by_state = nil)
|
778
|
-
@added = []
|
779
|
-
@deleted = []
|
780
|
-
@changed = []
|
781
|
-
@unchanged = []
|
782
|
-
|
783
|
-
if pods_by_state
|
784
|
-
@added = pods_by_state[:added] || []
|
785
|
-
@deleted = pods_by_state[:removed] || []
|
786
|
-
@changed = pods_by_state[:changed] || []
|
787
|
-
@unchanged = pods_by_state[:unchanged] || []
|
788
|
-
end
|
789
|
-
end
|
790
|
-
|
791
|
-
# @return [Array<String>] the names of the pods that were added.
|
792
|
-
#
|
793
|
-
attr_accessor :added
|
794
|
-
|
795
|
-
# @return [Array<String>] the names of the pods that were changed.
|
796
|
-
#
|
797
|
-
attr_accessor :changed
|
798
|
-
|
799
|
-
# @return [Array<String>] the names of the pods that were deleted.
|
800
|
-
#
|
801
|
-
attr_accessor :deleted
|
802
|
-
|
803
|
-
# @return [Array<String>] the names of the pods that were unchanged.
|
804
|
-
#
|
805
|
-
attr_accessor :unchanged
|
806
|
-
|
807
|
-
# Displays the state of each pod.
|
808
|
-
#
|
809
|
-
# @return [void]
|
810
|
-
#
|
811
|
-
def print
|
812
|
-
added .sort.each { |pod| UI.message('A'.green + " #{pod}", '', 2) }
|
813
|
-
deleted .sort.each { |pod| UI.message('R'.red + " #{pod}", '', 2) }
|
814
|
-
changed .sort.each { |pod| UI.message('M'.yellow + " #{pod}", '', 2) }
|
815
|
-
unchanged.sort.each { |pod| UI.message('-' + " #{pod}", '', 2) }
|
816
|
-
end
|
817
|
-
|
818
|
-
# Adds the name of a Pod to the give state.
|
819
|
-
#
|
820
|
-
# @param [String] name
|
821
|
-
# the name of the Pod.
|
822
|
-
#
|
823
|
-
# @param [Symbol] state
|
824
|
-
# the state of the Pod.
|
825
|
-
#
|
826
|
-
# @return [void]
|
827
|
-
#
|
828
|
-
def add_name(name, state)
|
829
|
-
send(state) << name
|
830
|
-
end
|
661
|
+
inspection_result
|
831
662
|
end
|
832
663
|
end
|
833
664
|
end
|