cocoapods 1.9.0 → 1.10.0.beta.2

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +226 -3
  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 +85 -18
  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 +31 -53
  51. data/lib/cocoapods/generator/prepare_artifacts_script.rb +0 -253
@@ -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.