cocoapods 1.11.0 → 1.12.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.
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|