cocoapods 1.9.3 → 1.10.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +167 -5
  3. data/README.md +2 -1
  4. data/lib/cocoapods.rb +3 -1
  5. data/lib/cocoapods/command.rb +12 -2
  6. data/lib/cocoapods/command/lib/lint.rb +12 -3
  7. data/lib/cocoapods/command/repo/push.rb +1 -1
  8. data/lib/cocoapods/command/repo/update.rb +11 -0
  9. data/lib/cocoapods/command/spec/lint.rb +12 -3
  10. data/lib/cocoapods/config.rb +17 -0
  11. data/lib/cocoapods/downloader/cache.rb +2 -2
  12. data/lib/cocoapods/gem_version.rb +1 -1
  13. data/lib/cocoapods/generator/app_target_helper.rb +10 -2
  14. data/lib/cocoapods/generator/copy_dsyms_script.rb +56 -0
  15. data/lib/cocoapods/generator/copy_resources_script.rb +2 -14
  16. data/lib/cocoapods/generator/copy_xcframework_script.rb +245 -0
  17. data/lib/cocoapods/generator/embed_frameworks_script.rb +125 -212
  18. data/lib/cocoapods/generator/script_phase_constants.rb +99 -0
  19. data/lib/cocoapods/installer.rb +70 -3
  20. data/lib/cocoapods/installer/analyzer.rb +17 -8
  21. data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +1 -1
  22. data/lib/cocoapods/installer/base_install_hooks_context.rb +135 -0
  23. data/lib/cocoapods/installer/installation_options.rb +5 -0
  24. data/lib/cocoapods/installer/pod_source_installer.rb +2 -1
  25. data/lib/cocoapods/installer/post_install_hooks_context.rb +1 -127
  26. data/lib/cocoapods/installer/post_integrate_hooks_context.rb +9 -0
  27. data/lib/cocoapods/installer/sandbox_dir_cleaner.rb +2 -1
  28. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +132 -111
  29. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +45 -6
  30. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +13 -27
  31. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +2 -1
  32. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +4 -4
  33. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +175 -58
  34. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +61 -30
  35. data/lib/cocoapods/installer/xcode/pods_project_generator/project_generator.rb +3 -2
  36. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +5 -7
  37. data/lib/cocoapods/installer/xcode/pods_project_generator_result.rb +19 -0
  38. data/lib/cocoapods/installer/xcode/target_validator.rb +1 -1
  39. data/lib/cocoapods/sources_manager.rb +2 -1
  40. data/lib/cocoapods/target.rb +44 -2
  41. data/lib/cocoapods/target/aggregate_target.rb +35 -0
  42. data/lib/cocoapods/target/build_settings.rb +84 -17
  43. data/lib/cocoapods/target/pod_target.rb +85 -11
  44. data/lib/cocoapods/user_interface/error_report.rb +1 -1
  45. data/lib/cocoapods/user_interface/inspector_reporter.rb +3 -10
  46. data/lib/cocoapods/validator.rb +32 -8
  47. data/lib/cocoapods/xcode/framework_paths.rb +1 -1
  48. data/lib/cocoapods/xcode/xcframework.rb +17 -4
  49. data/lib/cocoapods/xcode/xcframework/xcframework_slice.rb +81 -3
  50. metadata +30 -38
  51. data/lib/cocoapods/generator/prepare_artifacts_script.rb +0 -257
@@ -0,0 +1,99 @@
1
+ module Pod
2
+ module Generator
3
+ module ScriptPhaseConstants
4
+ DEFAULT_SCRIPT_PHASE_HEADER = <<-SH.strip_heredoc.freeze
5
+ #!/bin/sh
6
+ set -e
7
+ set -u
8
+ set -o pipefail
9
+
10
+ function on_error {
11
+ echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
12
+ }
13
+ trap 'on_error $LINENO' ERR
14
+ SH
15
+
16
+ RSYNC_PROTECT_TMP_FILES = <<-SH.strip_heredoc.freeze
17
+ # This protects against multiple targets copying the same framework dependency at the same time. The solution
18
+ # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
19
+ RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
20
+ SH
21
+
22
+ STRIP_INVALID_ARCHITECTURES_METHOD = <<-SH.strip_heredoc.freeze
23
+ # Used as a return value for each invocation of `strip_invalid_archs` function.
24
+ STRIP_BINARY_RETVAL=0
25
+
26
+ # Strip invalid architectures
27
+ strip_invalid_archs() {
28
+ binary="$1"
29
+ warn_missing_arch=${2:-true}
30
+ # Get architectures for current target binary
31
+ binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
32
+ # Intersect them with the architectures we are building for
33
+ intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\\n' | sort | uniq -d)"
34
+ # If there are no archs supported by this binary then warn the user
35
+ if [[ -z "$intersected_archs" ]]; then
36
+ if [[ "$warn_missing_arch" == "true" ]]; then
37
+ echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
38
+ fi
39
+ STRIP_BINARY_RETVAL=1
40
+ return
41
+ fi
42
+ stripped=""
43
+ for arch in $binary_archs; do
44
+ if ! [[ "${ARCHS}" == *"$arch"* ]]; then
45
+ # Strip non-valid architectures in-place
46
+ lipo -remove "$arch" -output "$binary" "$binary"
47
+ stripped="$stripped $arch"
48
+ fi
49
+ done
50
+ if [[ "$stripped" ]]; then
51
+ echo "Stripped $binary of architectures:$stripped"
52
+ fi
53
+ STRIP_BINARY_RETVAL=0
54
+ }
55
+ SH
56
+
57
+ INSTALL_DSYM_METHOD = <<-SH.strip_heredoc.freeze
58
+ # Copies and strips a vendored dSYM
59
+ install_dsym() {
60
+ local source="$1"
61
+ warn_missing_arch=${2:-true}
62
+ if [ -r "$source" ]; then
63
+ # Copy the dSYM into the targets temp dir.
64
+ echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \\"- CVS/\\" --filter \\"- .svn/\\" --filter \\"- .git/\\" --filter \\"- .hg/\\" --filter \\"- Headers\\" --filter \\"- PrivateHeaders\\" --filter \\"- Modules\\" \\"${source}\\" \\"${DERIVED_FILES_DIR}\\""
65
+ rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
66
+
67
+ local basename
68
+ basename="$(basename -s .dSYM "$source")"
69
+ binary_name="$(ls "$source/Contents/Resources/DWARF")"
70
+ binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
71
+
72
+ # Strip invalid architectures from the dSYM.
73
+ if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
74
+ strip_invalid_archs "$binary" "$warn_missing_arch"
75
+ fi
76
+ if [[ $STRIP_BINARY_RETVAL == 0 ]]; then
77
+ # Move the stripped file into its final destination.
78
+ echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \\"- CVS/\\" --filter \\"- .svn/\\" --filter \\"- .git/\\" --filter \\"- .hg/\\" --filter \\"- Headers\\" --filter \\"- PrivateHeaders\\" --filter \\"- Modules\\" \\"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\\" \\"${DWARF_DSYM_FOLDER_PATH}\\""
79
+ rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
80
+ else
81
+ # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
82
+ touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
83
+ fi
84
+ fi
85
+ }
86
+ SH
87
+
88
+ INSTALL_BCSYMBOLMAP_METHOD = <<-SH.strip_heredoc.freeze
89
+ # Copies the bcsymbolmap files of a vendored framework
90
+ install_bcsymbolmap() {
91
+ local bcsymbolmap_path="$1"
92
+ local destination="${BUILT_PRODUCTS_DIR}"
93
+ echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${bcsymbolmap_path}\" \"${destination}\""
94
+ rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
95
+ }
96
+ SH
97
+ end
98
+ end
99
+ end
@@ -34,6 +34,8 @@ module Pod
34
34
  autoload :InstallationOptions, 'cocoapods/installer/installation_options'
35
35
  autoload :PostInstallHooksContext, 'cocoapods/installer/post_install_hooks_context'
36
36
  autoload :PreInstallHooksContext, 'cocoapods/installer/pre_install_hooks_context'
37
+ autoload :BaseInstallHooksContext, 'cocoapods/installer/base_install_hooks_context'
38
+ autoload :PostIntegrateHooksContext, 'cocoapods/installer/post_integrate_hooks_context'
37
39
  autoload :SourceProviderHooksContext, 'cocoapods/installer/source_provider_hooks_context'
38
40
  autoload :PodfileValidator, 'cocoapods/installer/podfile_validator'
39
41
  autoload :PodSourceInstaller, 'cocoapods/installer/pod_source_installer'
@@ -47,6 +49,8 @@ module Pod
47
49
 
48
50
  include Config::Mixin
49
51
 
52
+ MASTER_SPECS_REPO_GIT_URL = 'https://github.com/CocoaPods/Specs.git'.freeze
53
+
50
54
  # @return [Sandbox] The sandbox where the Pods should be installed.
51
55
  #
52
56
  attr_reader :sandbox
@@ -331,7 +335,7 @@ module Pod
331
335
  all_projects_by_pod_targets.merge!(pods_project_by_targets) if pods_project_by_targets
332
336
  all_projects_by_pod_targets.merge!(projects_by_pod_targets) if projects_by_pod_targets
333
337
  all_projects_by_pod_targets.each do |project, pod_targets|
334
- generator.configure_schemes(project, pod_targets)
338
+ generator.configure_schemes(project, pod_targets, pod_project_generation_result)
335
339
  end
336
340
  end
337
341
  end
@@ -494,7 +498,7 @@ module Pod
494
498
  previous_version = sandbox.manifest.version(spec.name)
495
499
  has_changed_version = current_version != previous_version
496
500
  current_repo = analysis_result.specs_by_source.detect { |key, values| break key if values.map(&:name).include?(spec.name) }
497
- current_repo &&= current_repo.url || current_repo.name
501
+ current_repo &&= (Pod::TrunkSource::TRUNK_REPO_NAME if current_repo.name == Pod::TrunkSource::TRUNK_REPO_NAME) || current_repo.url || current_repo.name
498
502
  previous_spec_repo = sandbox.manifest.spec_repo(spec.name)
499
503
  has_changed_repo = !previous_spec_repo.nil? && current_repo && !current_repo.casecmp(previous_spec_repo).zero?
500
504
  title = "Installing #{spec.name} #{spec.version}"
@@ -563,6 +567,7 @@ module Pod
563
567
  #
564
568
  def clean_pod_sources
565
569
  return unless installation_options.clean?
570
+ return if installed_specs.empty?
566
571
  pod_installers.each(&:clean!)
567
572
  end
568
573
 
@@ -607,6 +612,7 @@ module Pod
607
612
  run_plugins_post_install_hooks
608
613
  warn_for_deprecations
609
614
  warn_for_installed_script_phases
615
+ warn_for_removing_git_master_specs_repo
610
616
  print_post_install_message
611
617
  end
612
618
 
@@ -635,12 +641,27 @@ module Pod
635
641
  lock_pod_sources
636
642
  end
637
643
 
644
+ # Runs the registered callbacks for the plugins post integrate hooks.
645
+ #
646
+ def run_plugins_post_integrate_hooks
647
+ if any_plugin_post_integrate_hooks?
648
+ context = PostIntegrateHooksContext.generate(sandbox, pods_project, aggregate_targets)
649
+ HooksManager.run(:post_integrate, context, plugins)
650
+ end
651
+ end
652
+
638
653
  # @return [Boolean] whether there are any plugin post-install hooks to run
639
654
  #
640
655
  def any_plugin_post_install_hooks?
641
656
  HooksManager.hooks_to_run(:post_install, plugins).any?
642
657
  end
643
658
 
659
+ # @return [Boolean] whether there are any plugin post-integrate hooks to run
660
+ #
661
+ def any_plugin_post_integrate_hooks?
662
+ HooksManager.hooks_to_run(:post_integrate, plugins).any?
663
+ end
664
+
644
665
  # Runs the registered callbacks for the source provider plugin hooks.
645
666
  #
646
667
  # @return [Array<Pod::Source>] the plugin sources
@@ -686,7 +707,7 @@ module Pod
686
707
  end
687
708
  end
688
709
 
689
- DEFAULT_PLUGINS = { 'cocoapods-stats' => {} }
710
+ DEFAULT_PLUGINS = {}
690
711
 
691
712
  # Returns the plugins that should be run, as indicated by the default
692
713
  # plugins and the podfile's plugins
@@ -736,6 +757,24 @@ module Pod
736
757
  end
737
758
  end
738
759
 
760
+ # Prints a warning if the project is not explicitly using the git based master specs repo.
761
+ #
762
+ # Helps users to delete the git based master specs repo from the repos directory which reduces `--repo-update`
763
+ # speed and hopefully reduces Github workload.
764
+ #
765
+ # @return [void]
766
+ #
767
+ def warn_for_removing_git_master_specs_repo
768
+ return unless installation_options.warn_for_unused_master_specs_repo?
769
+ podfile_master_source = podfile.sources.find { |source| source == MASTER_SPECS_REPO_GIT_URL }
770
+ master_repo = config.sources_manager.all.find { |s| s.url == MASTER_SPECS_REPO_GIT_URL }
771
+ if podfile_master_source.nil? && !master_repo.nil?
772
+ UI.warn 'Your project does not explicitly specify the CocoaPods master specs repo. Since CDN is now used as the' \
773
+ ' default, you may safely remove it from your repos directory via `pod repo remove master`. To suppress this warning' \
774
+ ' please add `warn_for_unused_master_specs_repo => false` to your Podfile.'
775
+ end
776
+ end
777
+
739
778
  # @return [Lockfile] The lockfile to write to disk.
740
779
  #
741
780
  def generate_lockfile
@@ -799,6 +838,7 @@ module Pod
799
838
  integrator = UserProjectIntegrator.new(podfile, sandbox, installation_root, aggregate_targets, generated_aggregate_targets,
800
839
  :use_input_output_paths => !installation_options.disable_input_output_paths?)
801
840
  integrator.integrate!
841
+ run_podfile_post_integrate_hooks
802
842
  end
803
843
  end
804
844
 
@@ -861,6 +901,33 @@ module Pod
861
901
  "\n\n#{e.message}\n\n#{e.backtrace * "\n"}"
862
902
  end
863
903
 
904
+ # Runs the post integrate hooks of the installed specs and of the Podfile.
905
+ #
906
+ # @note Post integrate hooks run _after_ saving of project, so that they
907
+ # can alter it after it is written to the disk.
908
+ #
909
+ # @return [void]
910
+ #
911
+ def run_podfile_post_integrate_hooks
912
+ UI.message '- Running post integrate hooks' do
913
+ executed = run_podfile_post_integrate_hook
914
+ UI.message '- Podfile' if executed
915
+ end
916
+ end
917
+
918
+ # Runs the post integrate hook of the Podfile.
919
+ #
920
+ # @raise Raises an informative if the hooks raises.
921
+ #
922
+ # @return [Boolean] Whether the hook was run.
923
+ #
924
+ def run_podfile_post_integrate_hook
925
+ podfile.post_integrate!(self)
926
+ rescue => e
927
+ raise Informative, 'An error occurred while processing the post-integrate ' \
928
+ 'hook of the Podfile.' \
929
+ "\n\n#{e.message}\n\n#{e.backtrace * "\n"}"
930
+ end
864
931
  #-------------------------------------------------------------------------#
865
932
 
866
933
  public
@@ -446,11 +446,18 @@ module Pod
446
446
  is_app_extension ||= aggregate_target.user_targets.any? do |user_target|
447
447
  user_target.common_resolved_build_setting('APPLICATION_EXTENSION_API_ONLY', :resolve_against_xcconfig => true) == 'YES'
448
448
  end
449
+ if is_app_extension
450
+ aggregate_target.mark_application_extension_api_only
451
+ aggregate_target.pod_targets.each(&:mark_application_extension_api_only)
452
+ end
449
453
 
450
- next unless is_app_extension
451
-
452
- aggregate_target.mark_application_extension_api_only
453
- aggregate_target.pod_targets.each(&:mark_application_extension_api_only)
454
+ build_library_for_distribution = aggregate_target.user_targets.any? do |user_target|
455
+ user_target.common_resolved_build_setting('BUILD_LIBRARY_FOR_DISTRIBUTION', :resolve_against_xcconfig => true) == 'YES'
456
+ end
457
+ if build_library_for_distribution
458
+ aggregate_target.mark_build_library_for_distribution
459
+ aggregate_target.pod_targets.each(&:mark_build_library_for_distribution)
460
+ end
454
461
  end
455
462
 
456
463
  if installation_options.integrate_targets?
@@ -648,8 +655,10 @@ module Pod
648
655
  resolver_specs_by_target.flat_map do |target_definition, specs|
649
656
  grouped_specs = specs.group_by(&:root).values.uniq
650
657
  pod_targets = grouped_specs.flat_map do |pod_specs|
651
- build_type = determine_build_type(pod_specs.first, target_definition.build_type)
652
- generate_pod_target([target_definition], build_type, target_inspections, pod_specs.map(&:spec)).scoped(dedupe_cache)
658
+ build_type = determine_build_type(pod_specs.first.spec, target_definition.build_type)
659
+ swift_version = determine_swift_version(pod_specs.first.spec, [target_definition])
660
+ generate_pod_target([target_definition], build_type, target_inspections, pod_specs.map(&:spec),
661
+ :swift_version => swift_version).scoped(dedupe_cache)
653
662
  end
654
663
 
655
664
  compute_pod_target_dependencies(pod_targets, specs.map(&:spec).group_by(&:name))
@@ -690,13 +699,13 @@ module Pod
690
699
  hash[app_spec.name] = Hash[app_dependencies_by_config.map { |k, v| [k, filter_dependencies(v, pod_targets_by_name, target)] }]
691
700
  end
692
701
 
693
- target.test_app_hosts_by_spec_name = target.test_specs.each_with_object({}) do |test_spec, hash|
702
+ target.test_app_hosts_by_spec = target.test_specs.each_with_object({}) do |test_spec, hash|
694
703
  next unless app_host_name = test_spec.consumer(target.platform).app_host_name
695
704
  app_host_spec = pod_targets_by_name[Specification.root_name(app_host_name)].flat_map(&:app_specs).find do |pt|
696
705
  pt.name == app_host_name
697
706
  end
698
707
  app_host_dependencies = { app_host_spec.root => [app_host_spec] }
699
- hash[test_spec.name] = [app_host_spec, filter_dependencies(app_host_dependencies, pod_targets_by_name, target).first]
708
+ hash[test_spec] = [app_host_spec, filter_dependencies(app_host_dependencies, pod_targets_by_name, target).first]
700
709
  end
701
710
  end
702
711
  end
@@ -50,7 +50,7 @@ module Pod
50
50
  @build_configurations = build_configurations
51
51
  @platform = platform
52
52
  @archs = archs
53
- @client_root = project.project_dir.realpath
53
+ @client_root = Pathname.new(project.project_dir + project.root_object.project_dir_path).realpath
54
54
  end
55
55
  end
56
56
  end
@@ -0,0 +1,135 @@
1
+ module Pod
2
+ class Installer
3
+ # Context object designed to be used with the HooksManager which describes
4
+ # the context of the installer.
5
+ #
6
+ class BaseInstallHooksContext
7
+ # @return [Sandbox] The Sandbox for the project.
8
+ #
9
+ attr_reader :sandbox
10
+
11
+ # @return [String] The path to the sandbox root (`Pods` directory).
12
+ #
13
+ attr_reader :sandbox_root
14
+
15
+ # @return [Xcodeproj::Project] The Pods Xcode project.
16
+ #
17
+ attr_reader :pods_project
18
+
19
+ # @return [Array<UmbrellaTargetDescription>] The list of
20
+ # the CocoaPods umbrella targets generated by the installer.
21
+ #
22
+ attr_reader :umbrella_targets
23
+
24
+ # Initialize a new instance
25
+ #
26
+ # @param [Sandbox] sandbox see #sandbox
27
+ # @param [String] sandbox_root see #sandbox_root
28
+ # @param [Xcodeproj::Project] pods_project see #pods_project
29
+ # @param [Array<UmbrellaTargetDescription>] umbrella_targets see #umbrella_targets
30
+ #
31
+ def initialize(sandbox, sandbox_root, pods_project, umbrella_targets)
32
+ @sandbox = sandbox
33
+ @sandbox_root = sandbox_root
34
+ @pods_project = pods_project
35
+ @umbrella_targets = umbrella_targets
36
+ end
37
+
38
+ # @return [PostInstallHooksContext] Convenience class generator method
39
+ #
40
+ # @param [Sandbox] sandbox
41
+ # The sandbox
42
+ #
43
+ # @param [Project] pods_project
44
+ # The pods project.
45
+ #
46
+ # @param [Array<AggregateTarget>] aggregate_targets
47
+ # The aggregate targets, which will been presented by an adequate
48
+ # {UmbrellaTargetDescription} in the generated context.
49
+ #
50
+ # @return [HooksContext] Convenience class method to generate the
51
+ # static context.
52
+ #
53
+ def self.generate(sandbox, pods_project, aggregate_targets)
54
+ umbrella_targets_descriptions = aggregate_targets.map do |umbrella|
55
+ user_project = umbrella.user_project
56
+ user_targets = umbrella.user_targets
57
+ specs = umbrella.specs
58
+ platform_name = umbrella.platform.name
59
+ platform_deployment_target = umbrella.platform.deployment_target.to_s
60
+ cocoapods_target_label = umbrella.label
61
+ UmbrellaTargetDescription.new(user_project, user_targets, specs, platform_name, platform_deployment_target, cocoapods_target_label)
62
+ end
63
+
64
+ new(sandbox, sandbox.root.to_s, pods_project, umbrella_targets_descriptions)
65
+ end
66
+
67
+ # Pure data class which describes an umbrella target.
68
+ #
69
+ class UmbrellaTargetDescription
70
+ # @return [Xcodeproj::Project] The user project into which this target
71
+ # is integrated.
72
+ #
73
+ attr_reader :user_project
74
+
75
+ # @return [Array<PBXNativeTarget>]
76
+ # The list of user targets integrated by this umbrella target.
77
+ #
78
+ attr_reader :user_targets
79
+
80
+ # @return [Array<Specification>] The list of the
81
+ # specifications of the target.
82
+ #
83
+ attr_reader :specs
84
+
85
+ # @return [Symbol] The platform (either `:ios`, `:watchos`, `:tvos`, or `:osx`).
86
+ #
87
+ attr_reader :platform_name
88
+
89
+ # @return [String] The deployment target.
90
+ #
91
+ attr_reader :platform_deployment_target
92
+
93
+ # @return [String] The label for the target.
94
+ #
95
+ attr_reader :cocoapods_target_label
96
+
97
+ # Initialize a new instance
98
+ #
99
+ # @param [Xcodeproj::Project] user_project see #user_project
100
+ # @param [Array<PBXNativeTarget>] user_targets see #user_targets
101
+ # @param [Array<Specification>] specs see #specs
102
+ # @param [Symbol] platform_name see #platform_name
103
+ # @param [String] platform_deployment_target see #platform_deployment_target
104
+ # @param [String] cocoapods_target_label see #cocoapods_target_label
105
+ #
106
+ def initialize(user_project, user_targets, specs, platform_name, platform_deployment_target, cocoapods_target_label)
107
+ @user_project = user_project
108
+ @user_targets = user_targets
109
+ @specs = specs
110
+ @platform_name = platform_name
111
+ @platform_deployment_target = platform_deployment_target
112
+ @cocoapods_target_label = cocoapods_target_label
113
+ end
114
+
115
+ # @return [String] The path of the user project
116
+ # integrated by this target.
117
+ #
118
+ def user_project_path
119
+ user_project.path if user_project
120
+ end
121
+
122
+ # @return [Array<String>] The list of the UUIDs of the
123
+ # user targets integrated by this umbrella
124
+ # target. They can be used to find the
125
+ # targets opening the project They can be used
126
+ # to find the targets opening the project with
127
+ # Xcodeproj.
128
+ #
129
+ def user_target_uuids
130
+ user_targets.map(&:uuid)
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
@@ -153,6 +153,11 @@ module Pod
153
153
  #
154
154
  option :warn_for_multiple_pod_sources, true
155
155
 
156
+ # Whether to emit a warning if a project is not explicitly specifying the git based master specs repo and can
157
+ # instead use CDN which is the default.
158
+ #
159
+ option :warn_for_unused_master_specs_repo, true
160
+
156
161
  # Whether to share Xcode schemes for development pods.
157
162
  #
158
163
  # Schemes for development pods are created automatically but are not shared by default.