cocoapods 1.11.0 → 1.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +162 -2
  3. data/README.md +7 -8
  4. data/lib/cocoapods/command/lib/lint.rb +3 -0
  5. data/lib/cocoapods/command/repo/push.rb +3 -0
  6. data/lib/cocoapods/command/setup.rb +2 -2
  7. data/lib/cocoapods/command/spec/lint.rb +3 -0
  8. data/lib/cocoapods/config.rb +5 -5
  9. data/lib/cocoapods/executable.rb +1 -1
  10. data/lib/cocoapods/external_sources/abstract_external_source.rb +1 -1
  11. data/lib/cocoapods/external_sources/path_source.rb +1 -1
  12. data/lib/cocoapods/gem_version.rb +1 -1
  13. data/lib/cocoapods/generator/acknowledgements.rb +12 -0
  14. data/lib/cocoapods/generator/app_target_helper.rb +1 -1
  15. data/lib/cocoapods/generator/copy_resources_script.rb +1 -1
  16. data/lib/cocoapods/generator/copy_xcframework_script.rb +48 -22
  17. data/lib/cocoapods/generator/embed_frameworks_script.rb +1 -1
  18. data/lib/cocoapods/generator/info_plist_file.rb +1 -1
  19. data/lib/cocoapods/installer/analyzer/analysis_result.rb +3 -3
  20. data/lib/cocoapods/installer/analyzer/pod_variant.rb +1 -1
  21. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +8 -7
  22. data/lib/cocoapods/installer/analyzer.rb +9 -5
  23. data/lib/cocoapods/installer/base_install_hooks_context.rb +18 -3
  24. data/lib/cocoapods/installer/installation_options.rb +11 -0
  25. data/lib/cocoapods/installer/pod_source_downloader.rb +159 -0
  26. data/lib/cocoapods/installer/pod_source_installer.rb +10 -36
  27. data/lib/cocoapods/installer/project_cache/project_cache_analyzer.rb +2 -2
  28. data/lib/cocoapods/installer/project_cache/target_cache_key.rb +1 -1
  29. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +2 -1
  30. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +37 -3
  31. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +6 -0
  32. data/lib/cocoapods/installer/xcode/pods_project_generator/project_generator.rb +1 -1
  33. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +9 -3
  34. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +36 -1
  35. data/lib/cocoapods/installer/xcode/target_validator.rb +1 -1
  36. data/lib/cocoapods/installer.rb +102 -34
  37. data/lib/cocoapods/native_target_extension.rb +1 -1
  38. data/lib/cocoapods/open-uri.rb +1 -1
  39. data/lib/cocoapods/project.rb +8 -8
  40. data/lib/cocoapods/resolver/resolver_specification.rb +1 -1
  41. data/lib/cocoapods/resolver.rb +3 -3
  42. data/lib/cocoapods/sandbox/file_accessor.rb +11 -2
  43. data/lib/cocoapods/sandbox/path_list.rb +1 -1
  44. data/lib/cocoapods/sandbox.rb +48 -12
  45. data/lib/cocoapods/sources_manager.rb +7 -4
  46. data/lib/cocoapods/target/build_settings.rb +9 -2
  47. data/lib/cocoapods/target/pod_target.rb +2 -2
  48. data/lib/cocoapods/user_interface.rb +2 -2
  49. data/lib/cocoapods/validator.rb +31 -20
  50. data/lib/cocoapods/xcode/xcframework/xcframework_slice.rb +12 -6
  51. data/lib/cocoapods/xcode/xcframework.rb +1 -1
  52. metadata +14 -13
@@ -40,7 +40,7 @@ module Pod
40
40
  #
41
41
  attr_reader :specs
42
42
 
43
- # @return [Bool] Whether the installation is performed in update mode.
43
+ # @return [Boolean] Whether the installation is performed in update mode.
44
44
  #
45
45
  attr_reader :update_mode
46
46
 
@@ -51,7 +51,7 @@ module Pod
51
51
  # @param [Sandbox] sandbox @see sandbox
52
52
  # @param [Podfile] podfile @see podfile
53
53
  # @param [Array<Specifications>] specs @see specs
54
- # @param [Bool] update_mode @see update_mode
54
+ # @param [Boolean] update_mode @see update_mode
55
55
  #
56
56
  def initialize(sandbox, podfile, specs, update_mode)
57
57
  @sandbox = sandbox
@@ -92,8 +92,8 @@ module Pod
92
92
  # @return [Symbol] The state
93
93
  #
94
94
  def pod_state(pod)
95
- return :added if pod_added?(pod)
96
95
  return :deleted if pod_deleted?(pod)
96
+ return :added if pod_added?(pod)
97
97
  return :changed if pod_changed?(pod)
98
98
  :unchanged
99
99
  end
@@ -105,7 +105,7 @@ module Pod
105
105
  # @param [String] pod
106
106
  # the name of the Pod.
107
107
  #
108
- # @return [Bool] Whether the Pod is added.
108
+ # @return [Boolean] Whether the Pod is added.
109
109
  #
110
110
  def pod_added?(pod)
111
111
  return true if resolved_pods.include?(pod) && !sandbox_pods.include?(pod)
@@ -119,7 +119,7 @@ module Pod
119
119
  # @param [String] pod
120
120
  # the name of the Pod.
121
121
  #
122
- # @return [Bool] Whether the Pod is deleted.
122
+ # @return [Boolean] Whether the Pod is deleted.
123
123
  #
124
124
  def pod_deleted?(pod)
125
125
  return true if !resolved_pods.include?(pod) && sandbox_pods.include?(pod)
@@ -138,14 +138,15 @@ module Pod
138
138
  # @param [String] pod
139
139
  # the name of the Pod.
140
140
  #
141
- # @return [Bool] Whether the Pod is changed.
141
+ # @return [Boolean] Whether the Pod is changed.
142
142
  #
143
143
  def pod_changed?(pod)
144
144
  spec = root_spec(pod)
145
145
  return true if spec.version != sandbox_version(pod)
146
146
  return true if spec.checksum != sandbox_checksum(pod)
147
147
  return true if resolved_spec_names(pod) != sandbox_spec_names(pod)
148
- return true if podfile_dependency(pod) != sandbox_dependency(pod)
148
+ podfile_dep = podfile_dependency(pod)&.tap { |dep| dep.podspec_repo = nil }
149
+ return true if podfile_dep != sandbox_dependency(pod)
149
150
  return true if sandbox.predownloaded?(pod)
150
151
  return true if folder_empty?(pod)
151
152
  false
@@ -43,7 +43,7 @@ module Pod
43
43
  #
44
44
  attr_reader :plugin_sources
45
45
 
46
- # @return [Bool] Whether the analysis has dependencies and thus sources must be configured.
46
+ # @return [Boolean] Whether the analysis has dependencies and thus sources must be configured.
47
47
  #
48
48
  # @note This is used by the `pod lib lint` command to prevent update of specs when not needed.
49
49
  #
@@ -84,6 +84,7 @@ module Pod
84
84
  @installation_options = podfile.installation_options
85
85
  @podfile_dependency_cache = PodfileDependencyCache.from_podfile(podfile)
86
86
  @sources_manager = sources_manager
87
+ @path_lists = {}
87
88
  @result = nil
88
89
  end
89
90
 
@@ -93,7 +94,7 @@ module Pod
93
94
  # compute which specification should be installed. The manifest of the
94
95
  # sandbox returns which specifications are installed.
95
96
  #
96
- # @param [Bool] allow_fetches
97
+ # @param [Boolean] allow_fetches
97
98
  # whether external sources may be fetched
98
99
  #
99
100
  # @return [AnalysisResult]
@@ -125,7 +126,7 @@ module Pod
125
126
  validate_platforms(resolver_specs_by_target)
126
127
  specifications = generate_specifications(resolver_specs_by_target)
127
128
  aggregate_targets, pod_targets = generate_targets(resolver_specs_by_target, target_inspections)
128
- sandbox_state = generate_sandbox_state(specifications)
129
+ sandbox_state = generate_sandbox_state(specifications)
129
130
  specs_by_target = resolver_specs_by_target.each_with_object({}) do |rspecs_by_target, hash|
130
131
  hash[rspecs_by_target[0]] = rspecs_by_target[1].map(&:spec)
131
132
  end
@@ -193,7 +194,7 @@ module Pod
193
194
 
194
195
  # @!group Configuration
195
196
 
196
- # @return [Bool] Whether the version of the dependencies which did not
197
+ # @return [Boolean] Whether the version of the dependencies which did not
197
198
  # change in the Podfile should be locked.
198
199
  #
199
200
  def update_mode?
@@ -830,7 +831,10 @@ module Pod
830
831
  def create_file_accessors(specs, platform)
831
832
  name = specs.first.name
832
833
  pod_root = sandbox.pod_dir(name)
833
- path_list = Sandbox::PathList.new(pod_root)
834
+ path_list = @path_lists.fetch(pod_root) do |root|
835
+ path_list = Sandbox::PathList.new(root)
836
+ @path_lists[root] = path_list
837
+ end
834
838
  specs.map do |spec|
835
839
  Sandbox::FileAccessor.new(path_list, spec.consumer(platform))
836
840
  end
@@ -16,6 +16,10 @@ module Pod
16
16
  #
17
17
  attr_reader :pods_project
18
18
 
19
+ # @return [Array<Pod::Project>] the subprojects nested under pods_project.
20
+ #
21
+ attr_reader :pod_target_subprojects
22
+
19
23
  # @return [Array<UmbrellaTargetDescription>] The list of
20
24
  # the CocoaPods umbrella targets generated by the installer.
21
25
  #
@@ -26,12 +30,14 @@ module Pod
26
30
  # @param [Sandbox] sandbox see #sandbox
27
31
  # @param [String] sandbox_root see #sandbox_root
28
32
  # @param [Xcodeproj::Project] pods_project see #pods_project
33
+ # @param [Array<Xcodeproj::Project>] pod_target_subprojects see #pod_target_subprojects
29
34
  # @param [Array<UmbrellaTargetDescription>] umbrella_targets see #umbrella_targets
30
35
  #
31
- def initialize(sandbox, sandbox_root, pods_project, umbrella_targets)
36
+ def initialize(sandbox, sandbox_root, pods_project, pod_target_subprojects, umbrella_targets)
32
37
  @sandbox = sandbox
33
38
  @sandbox_root = sandbox_root
34
39
  @pods_project = pods_project
40
+ @pod_target_subprojects = pod_target_subprojects
35
41
  @umbrella_targets = umbrella_targets
36
42
  end
37
43
 
@@ -43,6 +49,9 @@ module Pod
43
49
  # @param [Project] pods_project
44
50
  # The pods project.
45
51
  #
52
+ # @param [Project] pod_target_subprojects
53
+ # The subprojects nested under pods_project.
54
+ #
46
55
  # @param [Array<AggregateTarget>] aggregate_targets
47
56
  # The aggregate targets, which will been presented by an adequate
48
57
  # {UmbrellaTargetDescription} in the generated context.
@@ -50,7 +59,7 @@ module Pod
50
59
  # @return [HooksContext] Convenience class method to generate the
51
60
  # static context.
52
61
  #
53
- def self.generate(sandbox, pods_project, aggregate_targets)
62
+ def self.generate(sandbox, pods_project, pod_target_subprojects, aggregate_targets)
54
63
  umbrella_targets_descriptions = aggregate_targets.map do |umbrella|
55
64
  user_project = umbrella.user_project
56
65
  user_targets = umbrella.user_targets
@@ -61,7 +70,13 @@ module Pod
61
70
  UmbrellaTargetDescription.new(user_project, user_targets, specs, platform_name, platform_deployment_target, cocoapods_target_label)
62
71
  end
63
72
 
64
- new(sandbox, sandbox.root.to_s, pods_project, umbrella_targets_descriptions)
73
+ new(sandbox, sandbox.root.to_s, pods_project, pod_target_subprojects, umbrella_targets_descriptions)
74
+ end
75
+
76
+ # @return [Array<Pod::Project>] all projects generated during installation
77
+ #
78
+ def generated_projects
79
+ [pods_project] + pod_target_subprojects
65
80
  end
66
81
 
67
82
  # Pure data class which describes an umbrella target.
@@ -190,6 +190,17 @@ module Pod
190
190
  # Whether to skip generating the `Pods.xcodeproj` and perform only dependency resolution and downloading.
191
191
  #
192
192
  option :skip_pods_project_generation, false
193
+
194
+ # Whether to download pods in parallel before beginning the installation process
195
+ #
196
+ option :parallel_pod_downloads, false
197
+
198
+ # The size of the thread pool to use when downloading pods in parallel. Only takes effect when
199
+ # `parallel_pod_downloads` is `true`.
200
+ #
201
+ # Default: 40
202
+ #
203
+ option(:parallel_pod_download_thread_pool_size, 40, :boolean => false)
193
204
  end
194
205
  end
195
206
  end
@@ -0,0 +1,159 @@
1
+
2
+ module Pod
3
+ class Installer
4
+ # Controller class responsible for downloading the activated specifications
5
+ # of a single Pod.
6
+ #
7
+ # @note This class needs to consider all the activated specs of a Pod.
8
+ #
9
+ class PodSourceDownloader
10
+ UNENCRYPTED_PROTOCOLS = %w(http git).freeze
11
+
12
+ # @return [Sandbox] The installation target.
13
+ #
14
+ attr_reader :sandbox
15
+
16
+ # @return [Podfile] the podfile that should be integrated with the user
17
+ # projects.
18
+ #
19
+ attr_reader :podfile
20
+
21
+ # @return [Hash{Symbol=>Array}] The specifications that need to be
22
+ # installed grouped by platform.
23
+ #
24
+ attr_reader :specs_by_platform
25
+
26
+ # @return [Boolean] Whether the installer is allowed to touch the cache.
27
+ #
28
+ attr_reader :can_cache
29
+ alias can_cache? can_cache
30
+
31
+ # Initialize a new instance
32
+ #
33
+ # @param [Sandbox] sandbox @see #sandbox
34
+ # @param [Podfile] podfile @see #podfile
35
+ # @param [Hash{Symbol=>Array}] specs_by_platform @see #specs_by_platform
36
+ # @param [Boolean] can_cache @see #can_cache
37
+ #
38
+ def initialize(sandbox, podfile, specs_by_platform, can_cache: true)
39
+ @sandbox = sandbox
40
+ @podfile = podfile
41
+ @specs_by_platform = specs_by_platform
42
+ @can_cache = can_cache
43
+ end
44
+
45
+ # @return [String] A string suitable for debugging.
46
+ #
47
+ def inspect
48
+ "<#{self.class} sandbox=#{sandbox.root} pod=#{root_spec.name}"
49
+ end
50
+
51
+ # @return [String] The name of the pod this downloader is downloading.
52
+ #
53
+ def name
54
+ root_spec.name
55
+ end
56
+
57
+ #-----------------------------------------------------------------------#
58
+
59
+ public
60
+
61
+ # @!group Downloading
62
+
63
+ # Creates the target in the Pods project and the relative support files.
64
+ #
65
+ # @return [void]
66
+ #
67
+ def download!
68
+ verify_source_is_secure(root_spec)
69
+ download_result = Downloader.download(download_request, root, :can_cache => can_cache?)
70
+
71
+ if (specific_source = download_result.checkout_options) && specific_source != root_spec.source
72
+ sandbox.store_checkout_source(root_spec.name, specific_source)
73
+ end
74
+
75
+ sandbox.store_downloaded_pod(root_spec.name)
76
+ end
77
+
78
+ #-----------------------------------------------------------------------#
79
+
80
+ private
81
+
82
+ # @!group Download Steps
83
+
84
+ # Verify the source of the spec is secure, which is used to show a warning to the user if that isn't the case
85
+ # This method doesn't verify all protocols, but currently only prohibits unencrypted 'http://' and 'git://''
86
+ # connections.
87
+ #
88
+ # @return [void]
89
+ #
90
+ def verify_source_is_secure(root_spec)
91
+ return if root_spec.source.nil? || (root_spec.source[:http].nil? && root_spec.source[:git].nil?)
92
+ source = if !root_spec.source[:http].nil?
93
+ URI(root_spec.source[:http].to_s)
94
+ elsif !root_spec.source[:git].nil?
95
+ git_source = root_spec.source[:git].to_s
96
+ return unless git_source =~ /^#{URI::DEFAULT_PARSER.make_regexp}$/
97
+ URI(git_source)
98
+ end
99
+ if UNENCRYPTED_PROTOCOLS.include?(source.scheme) && source.host != 'localhost'
100
+ UI.warn "'#{root_spec.name}' uses the unencrypted '#{source.scheme}' protocol to transfer the Pod. " \
101
+ 'Please be sure you\'re in a safe network with only trusted hosts. ' \
102
+ 'Otherwise, please reach out to the library author to notify them of this security issue.'
103
+ end
104
+ end
105
+
106
+ def download_request
107
+ Downloader::Request.new(
108
+ :spec => root_spec,
109
+ :released => released?,
110
+ )
111
+ end
112
+
113
+ #-----------------------------------------------------------------------#
114
+
115
+ private
116
+
117
+ # @!group Convenience methods.
118
+
119
+ # @return [Array<Specifications>] the specification of the Pod used in
120
+ # this installation.
121
+ #
122
+ def specs
123
+ specs_by_platform.values.flatten
124
+ end
125
+
126
+ # @return [Specification] the root specification of the Pod.
127
+ #
128
+ def root_spec
129
+ specs.first.root
130
+ end
131
+
132
+ # @return [Pathname] the folder where the source of the Pod is located.
133
+ #
134
+ def root
135
+ sandbox.pod_dir(root_spec.name)
136
+ end
137
+
138
+ # @return [Boolean] whether the source has been pre downloaded in the
139
+ # resolution process to retrieve its podspec.
140
+ #
141
+ def predownloaded?
142
+ sandbox.predownloaded_pods.include?(root_spec.name)
143
+ end
144
+
145
+ # @return [Boolean] whether the pod uses the local option and thus
146
+ # CocoaPods should not interfere with the files of the user.
147
+ #
148
+ def local?
149
+ sandbox.local?(root_spec.name)
150
+ end
151
+
152
+ def released?
153
+ sandbox.specification(root_spec.name) != root_spec
154
+ end
155
+
156
+ #-----------------------------------------------------------------------#
157
+ end
158
+ end
159
+ end
@@ -8,8 +8,6 @@ module Pod
8
8
  # @note This class needs to consider all the activated specs of a Pod.
9
9
  #
10
10
  class PodSourceInstaller
11
- UNENCRYPTED_PROTOCOLS = %w(http git).freeze
12
-
13
11
  # @return [Sandbox] The installation target.
14
12
  #
15
13
  attr_reader :sandbox
@@ -114,43 +112,12 @@ module Pod
114
112
  # @return [void]
115
113
  #
116
114
  def download_source
117
- verify_source_is_secure(root_spec)
118
- download_result = Downloader.download(download_request, root, :can_cache => can_cache?)
119
-
120
- if (specific_source = download_result.checkout_options) && specific_source != root_spec.source
121
- sandbox.store_checkout_source(root_spec.name, specific_source)
115
+ unless downloaded?
116
+ downloader = PodSourceDownloader.new(sandbox, podfile, specs_by_platform, :can_cache => can_cache?)
117
+ downloader.download!
122
118
  end
123
119
  end
124
120
 
125
- # Verify the source of the spec is secure, which is used to show a warning to the user if that isn't the case
126
- # This method doesn't verify all protocols, but currently only prohibits unencrypted 'http://' and 'git://''
127
- # connections.
128
- #
129
- # @return [void]
130
- #
131
- def verify_source_is_secure(root_spec)
132
- return if root_spec.source.nil? || (root_spec.source[:http].nil? && root_spec.source[:git].nil?)
133
- source = if !root_spec.source[:http].nil?
134
- URI(root_spec.source[:http].to_s)
135
- elsif !root_spec.source[:git].nil?
136
- git_source = root_spec.source[:git].to_s
137
- return unless git_source =~ /^#{URI.regexp}$/
138
- URI(git_source)
139
- end
140
- if UNENCRYPTED_PROTOCOLS.include?(source.scheme) && source.host != 'localhost'
141
- UI.warn "'#{root_spec.name}' uses the unencrypted '#{source.scheme}' protocol to transfer the Pod. " \
142
- 'Please be sure you\'re in a safe network with only trusted hosts. ' \
143
- 'Otherwise, please reach out to the library author to notify them of this security issue.'
144
- end
145
- end
146
-
147
- def download_request
148
- Downloader::Request.new(
149
- :spec => root_spec,
150
- :released => released?,
151
- )
152
- end
153
-
154
121
  #-----------------------------------------------------------------------#
155
122
 
156
123
  private
@@ -186,6 +153,13 @@ module Pod
186
153
  sandbox.pod_dir(root_spec.name)
187
154
  end
188
155
 
156
+ # @return [Boolean] whether the source has already been downloaded prior
157
+ # to the installation process.
158
+ #
159
+ def downloaded?
160
+ sandbox.downloaded_pods.include?(root_spec.name)
161
+ end
162
+
189
163
  # @return [Boolean] whether the source has been pre downloaded in the
190
164
  # resolution process to retrieve its podspec.
191
165
  #
@@ -38,7 +38,7 @@ module Pod
38
38
  #
39
39
  attr_reader :installation_options
40
40
 
41
- # @return [Bool] Flag indicating if we want to ignore the cache and force a clean installation.
41
+ # @return [Boolean] Flag indicating if we want to ignore the cache and force a clean installation.
42
42
  #
43
43
  attr_reader :clean_install
44
44
 
@@ -52,7 +52,7 @@ module Pod
52
52
  # @param [Array<PodTarget>] pod_targets @see #pod_targets
53
53
  # @param [Array<AggregateTarget>] aggregate_targets @see #aggregate_targets
54
54
  # @param [Hash<Symbol, Object>] installation_options @see #installation_options
55
- # @param [Bool] clean_install @see #clean_install
55
+ # @param [Boolean] clean_install @see #clean_install
56
56
  #
57
57
  def initialize(sandbox, cache, build_configurations, project_object_version, podfile_plugins, pod_targets, aggregate_targets, installation_options,
58
58
  clean_install: false)
@@ -109,7 +109,7 @@ module Pod
109
109
  # @param [PodTarget] pod_target
110
110
  # The pod target used to construct a TargetCacheKey object.
111
111
  #
112
- # @param [Bool] is_local_pod
112
+ # @param [Boolean] is_local_pod
113
113
  # Used to also include its local files in the cache key.
114
114
  #
115
115
  # @param [Hash] checkout_options
@@ -62,7 +62,8 @@ module Pod
62
62
  # @param [Hash] info_plist_entries see #info_plist_entries
63
63
  # @param [String] product_basename see #product_basename
64
64
  #
65
- def initialize(sandbox, project, platform, subgroup_name, group_name, app_target_label, add_main: true, add_launchscreen_storyboard: platform == :ios, info_plist_entries: {}, product_basename: nil)
65
+ def initialize(sandbox, project, platform, subgroup_name, group_name, app_target_label, add_main: true,
66
+ add_launchscreen_storyboard: platform == :ios, info_plist_entries: {}, product_basename: nil)
66
67
  @sandbox = sandbox
67
68
  @project = project
68
69
  @platform = platform
@@ -21,7 +21,7 @@ module Pod
21
21
  #
22
22
  attr_reader :pods_project
23
23
 
24
- # @return [Bool] add support for preserving the file structure of externally sourced pods, in addition to local pods.
24
+ # @return [Boolean] add support for preserving the file structure of externally sourced pods, in addition to local pods.
25
25
  #
26
26
  attr_reader :preserve_pod_file_structure
27
27
 
@@ -30,7 +30,7 @@ module Pod
30
30
  # @param [Sandbox] sandbox @see #sandbox
31
31
  # @param [Array<PodTarget>] pod_targets @see #pod_targets
32
32
  # @param [Project] pods_project @see #pods_project
33
- # @param [Bool] preserve_pod_file_structure @see #preserve_pod_file_structure
33
+ # @param [Boolean] preserve_pod_file_structure @see #preserve_pod_file_structure
34
34
  #
35
35
  def initialize(sandbox, pod_targets, pods_project, preserve_pod_file_structure = false)
36
36
  @sandbox = sandbox
@@ -207,7 +207,7 @@ module Pod
207
207
  # @param [Symbol] group_key
208
208
  # The key of the group of the Pods project.
209
209
  #
210
- # @param [Bool] reflect_file_system_structure
210
+ # @param [Boolean] reflect_file_system_structure
211
211
  # Whether organizing a local pod's files in subgroups inside
212
212
  # the pod's group is allowed.
213
213
  #
@@ -243,6 +243,10 @@ module Pod
243
243
  def allowable_project_paths(paths)
244
244
  lproj_paths = Set.new
245
245
  lproj_paths_with_files = Set.new
246
+
247
+ # Remove all file ref under .docc folder, but preserve the .docc folder
248
+ paths = merge_to_docc_folder(paths)
249
+
246
250
  allowable_paths = paths.select do |path|
247
251
  path_str = path.to_s
248
252
 
@@ -327,3 +331,33 @@ module Pod
327
331
  end
328
332
  end
329
333
  end
334
+
335
+ # If we have an non-empty .docc folder, remove all paths under the folder
336
+ # but keep the folder itself
337
+ #
338
+ # @param [Array<Pathname>] paths the paths to inspect
339
+ #
340
+ # @return [Array<Pathname>] The resulted list of paths.
341
+ #
342
+ def merge_to_docc_folder(paths)
343
+ docc_paths_with_files = Set.new
344
+ allowable_paths = paths.select do |path|
345
+ path_str = path.to_s
346
+
347
+ if path_str =~ /\.docc(\/|$)/i
348
+
349
+ # we want folder with files
350
+ next if path.directory?
351
+
352
+ # remove everything after ".docc", but keep ".docc"
353
+ folder_path = path_str.split("\.docc")[0] + "\.docc"
354
+
355
+ docc_paths_with_files << Pathname(folder_path)
356
+ next
357
+
358
+ end
359
+ true
360
+ end
361
+
362
+ allowable_paths + docc_paths_with_files.to_a
363
+ end
@@ -600,6 +600,9 @@ module Pod
600
600
  # classes from the parent module.
601
601
  configuration.build_settings['IBSC_MODULE'] = target.product_module_name
602
602
 
603
+ # Xcode 14.x throws an error about code signing on resource bundles, turn it off for now.
604
+ configuration.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
605
+
603
606
  # Set the `SWIFT_VERSION` build setting for resource bundles that could have resources that get
604
607
  # compiled such as an `xcdatamodeld` file which has 'Swift' as its code generation language.
605
608
  if contains_compile_phase_refs && file_accessors.any? { |fa| target.uses_swift_for_spec?(fa.spec) }
@@ -1010,6 +1013,9 @@ module Pod
1010
1013
  error_message_for_missing_reference = lambda do |sf, target|
1011
1014
  "Unable to find #{file_type} ref for `#{sf.basename}` for target `#{target.name}`."
1012
1015
  end
1016
+
1017
+ # Remove all file ref under .docc folder, but preserve the .docc folder
1018
+ files = merge_to_docc_folder(files)
1013
1019
  files.map do |sf|
1014
1020
  begin
1015
1021
  project.reference_for_path(sf).tap do |ref|
@@ -38,7 +38,7 @@ module Pod
38
38
  #
39
39
  attr_reader :podfile_path
40
40
 
41
- # @return [Bool] Bool indicating if this project is a pod target subproject.
41
+ # @return [Boolean] Bool indicating if this project is a pod target subproject.
42
42
  # Used by `generate_multiple_pod_projects` installation option.
43
43
  #
44
44
  attr_reader :pod_target_subproject
@@ -48,17 +48,23 @@ module Pod
48
48
  # @param [Hash] additional_entries
49
49
  # any additional entries to include in this Info.plist file.
50
50
  #
51
+ # @param [String] build_setting_value
52
+ # an optional value to set for the `INFOPLIST_FILE` build setting on the
53
+ # native target. If none is specified then the value is calculated from the
54
+ # Info.plist path relative to the sandbox root.
55
+ #
51
56
  # @return [void]
52
57
  #
53
58
  def create_info_plist_file_with_sandbox(sandbox, path, native_target, version, platform,
54
- bundle_package_type = :fmwk, additional_entries: {})
59
+ bundle_package_type = :fmwk, additional_entries: {},
60
+ build_setting_value: nil)
55
61
  UI.message "- Generating Info.plist file at #{UI.path(path)}" do
56
62
  generator = Generator::InfoPlistFile.new(version, platform, bundle_package_type, additional_entries)
57
63
  update_changed_file(generator, path)
58
64
 
59
- relative_path_string = path.relative_path_from(sandbox.root).to_s
65
+ build_setting_value ||= path.relative_path_from(sandbox.root).to_s
60
66
  native_target.build_configurations.each do |c|
61
- c.build_settings['INFOPLIST_FILE'] = relative_path_string
67
+ c.build_settings['INFOPLIST_FILE'] = build_setting_value
62
68
  end
63
69
  end
64
70
  end
@@ -195,7 +195,7 @@ module Pod
195
195
 
196
196
  # @param [String] pod The root name of the development pod.
197
197
  #
198
- # @return [Bool] whether the scheme for the given development pod should be
198
+ # @return [Boolean] whether the scheme for the given development pod should be
199
199
  # shared.
200
200
  #
201
201
  def share_scheme_for_development_pod?(pod)
@@ -265,6 +265,10 @@ module Pod
265
265
  if scheme_configuration.key?(:code_coverage)
266
266
  scheme.test_action.code_coverage_enabled = scheme_configuration[:code_coverage]
267
267
  end
268
+ if scheme_configuration.key?(:parallelizable)
269
+ scheme.test_action.testables.each { |testable| testable.parallelizable = scheme_configuration[:parallelizable] }
270
+ end
271
+ set_scheme_build_configurations(scheme, scheme_configuration.fetch(:build_configurations, {}))
268
272
 
269
273
  hosted_test_specs_by_host[spec].each do |hosted_spec|
270
274
  # We are an app spec which hosts this test spec.
@@ -285,6 +289,37 @@ module Pod
285
289
  Xcodeproj::XCScheme.share_scheme(project.path, scheme_name) if share_scheme
286
290
  end
287
291
  end
292
+
293
+ # @param [Xcodeproj::XCSheme] scheme
294
+ # scheme to apply configuration to
295
+ #
296
+ # @param [Hash{String => String}] configuration
297
+ # action => build configuration to use for the action
298
+ #
299
+ # @return [void]
300
+ #
301
+ def set_scheme_build_configurations(scheme, configuration)
302
+ configuration.each do |k, v|
303
+ unless @build_configurations.include?(v)
304
+ raise Informative, "Unable to set `#{v}` as a build configuration as " \
305
+ "it doesn't match with any of your projects build configurations."
306
+ end
307
+
308
+ case k
309
+ when 'Run'
310
+ scheme.launch_action.build_configuration = v
311
+ when 'Test'
312
+ scheme.test_action.build_configuration = v
313
+ when 'Analyze'
314
+ scheme.analyze_action.build_configuration = v
315
+ when 'Archive'
316
+ scheme.archive_action.build_configuration = v
317
+ else
318
+ raise Informative, "#{k} is not a valid scheme action " \
319
+ "only one of ['run', 'test', 'analyze', 'archive'] is available"
320
+ end
321
+ end
322
+ end
288
323
  end
289
324
  end
290
325
  end
@@ -129,7 +129,7 @@ module Pod
129
129
  def verify_swift_pods_have_module_dependencies
130
130
  error_messages = []
131
131
  pod_targets.each do |pod_target|
132
- next unless pod_target.uses_swift?
132
+ next unless pod_target.uses_swift? && pod_target.should_build?
133
133
 
134
134
  non_module_dependencies = []
135
135
  pod_target.dependent_targets.each do |dependent_target|