cocoapods-generate 2.0.1 → 2.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1ff4789b445c0e00d7e00d2808dd4ed69e0d02f5e43547ef710d83bcc0dbce62
4
- data.tar.gz: cc8ab4c9925c136e06706ced54b25b419327a4d9b4625bfac7e17ed02b5f58a2
3
+ metadata.gz: e678737eede01f12fa09ac0d4d64a23737ec7d659147d67a9e489bb64044709e
4
+ data.tar.gz: 82c0cf87922bed22879443ad965b8dd9795c6d0704fab11cbf2329570d4ce6ca
5
5
  SHA512:
6
- metadata.gz: 3bf5669db86616bdc81af45c12d51a7a4fc10b1f7168173394290632522a5e1e4a65c2c9f100573018022fd3feaac3599ec80f853f62b24384d0f6a5f77d0c3b
7
- data.tar.gz: 003a8045475b4fc18dbf57e2c4bc12e2ade7b07da9d62b129870c52984f2ba2a27ce5eec00b6e7fa4f66e1cec43b149f433265422a3c194227ace7429c0b427f
6
+ metadata.gz: 458d65f261c92ff4fae69b24feab9693bc2f7a63503585b8dbdfc06aafd4e006a0a25556b6dd1d70a7213cb29a9a2d4668e4da8688dc1b628008f56fd23a0110
7
+ data.tar.gz: 90730f6a121011ee794f4c910135b47eee34ba177e1a1af620a6a96755d5d60f3a941b41179e25fbf9b17dc99cedabf5e3a11c5a0c618411fec2586eb8832478
data/README.md CHANGED
@@ -89,6 +89,9 @@ Options:
89
89
  default plugins
90
90
  --deterministic-uuids Whether installation should use
91
91
  deterministic UUIDs for pods projects
92
+ --disable-input-output-paths Whether to disable the input & output paths
93
+ of the CocoaPods script phases (Copy
94
+ Frameworks & Copy Resources)
92
95
  --share-schemes-for-development-pods Whether installation should share schemes
93
96
  for development pods
94
97
  --warn-for-multiple-pod-sources Whether installation should warn when a pod
@@ -98,6 +101,10 @@ Options:
98
101
  modules, as if `use_modular_headers!` were
99
102
  specified. Will error if both this option
100
103
  and a podfile are specified
104
+ --single-workspace Whether to produce a single workspace for
105
+ all podspecs specified.
106
+ --xcode-version=xcode_version The Xcode version to use for producing the
107
+ consumer sample project
101
108
  ```
102
109
  <!-- end cli usage -->
103
110
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.1
1
+ 2.2.4
@@ -64,8 +64,8 @@ module Pod
64
64
  # even if there are multiple podspecs
65
65
  update_sources if configuration.repo_update?
66
66
 
67
- Generate::PodfileGenerator.new(configuration).podfiles_by_spec.each do |spec, podfile|
68
- Generate::Installer.new(configuration, spec, podfile).install!
67
+ Generate::PodfileGenerator.new(configuration).podfiles_by_specs.each do |specs, podfile|
68
+ Generate::Installer.new(configuration, specs, podfile).install!
69
69
  end
70
70
 
71
71
  remove_warnings(UI.warnings)
@@ -123,6 +123,10 @@ module Pod
123
123
  value
124
124
  end
125
125
 
126
+ coerce_to_version = lambda do |value|
127
+ Pod::Version.new(value)
128
+ end
129
+
126
130
  coerce_to_pathname = lambda do |path|
127
131
  path && Pathname(path).expand_path
128
132
  end
@@ -169,7 +173,7 @@ module Pod
169
173
  ->(paths) { ('paths do not exist' unless paths.all? { |p| p.is_a?(URI) || p.exist? }) },
170
174
  ->(paths) { paths && paths.map { |path| path.to_s =~ %r{https?://} ? URI(path) : Pathname(path).expand_path } }
171
175
  option :podspecs, ArrayOf.new(Pod::Specification),
172
- 'self.class.podspecs_from_paths(podspec_paths)',
176
+ 'self.class.podspecs_from_paths(podspec_paths, gen_directory)',
173
177
  nil,
174
178
  nil,
175
179
  ->(specs) { 'no podspecs found' if specs.empty? },
@@ -199,10 +203,19 @@ module Pod
199
203
  ->(platforms) { Array(platforms).flat_map { |s| s.split(',') } }
200
204
  option :repo_update, BOOLEAN, 'false', 'Force running `pod repo update` before install', nil, nil, coerce_to_bool
201
205
  option :use_default_plugins, BOOLEAN, 'false', 'Whether installation should activate default plugins', nil, nil, coerce_to_bool
202
- option :deterministic_uuids, BOOLEAN, 'false', 'Whether installation should use deterministic UUIDs for pods projects', nil, nil, coerce_to_bool
203
- option :share_schemes_for_development_pods, BOOLEAN, 'true', 'Whether installation should share schemes for development pods', nil, nil, coerce_to_bool
204
- option :warn_for_multiple_pod_sources, BOOLEAN, 'false', 'Whether installation should warn when a pod is found in multiple sources', nil, nil, coerce_to_bool
206
+ option :deterministic_uuids, BOOLEAN, '(use_podfile && podfile) ? podfile.installation_options.deterministic_uuids : false', 'Whether installation should use deterministic UUIDs for pods projects', nil, nil, coerce_to_bool
207
+ option :disable_input_output_paths, BOOLEAN, '(use_podfile && podfile) ? podfile.installation_options.disable_input_output_paths : false', 'Whether to disable the input & output paths of the CocoaPods script phases (Copy Frameworks & Copy Resources)', nil, nil, coerce_to_bool
208
+ option :share_schemes_for_development_pods, [TrueClass, FalseClass, Array], '(use_podfile && podfile) ? podfile.installation_options.share_schemes_for_development_pods : true', 'Whether installation should share schemes for development pods', nil, nil
209
+ option :warn_for_multiple_pod_sources, BOOLEAN, '(use_podfile && podfile) ? podfile.installation_options.warn_for_multiple_pod_sources : false', 'Whether installation should warn when a pod is found in multiple sources', nil, nil, coerce_to_bool
205
210
  option :use_modular_headers, BOOLEAN, 'false', 'Whether the target should be generated as a clang module, treating dependencies as modules, as if `use_modular_headers!` were specified. Will error if both this option and a podfile are specified', nil, nil, coerce_to_bool
211
+ option :single_workspace, BOOLEAN, 'false', 'Whether to produce a single workspace for all podspecs specified.', nil, nil, coerce_to_bool
212
+ option :xcode_version, Pod::Version, 'Pod::Version.new(\'9.3\')', 'The Xcode version to use for producing the consumer sample project', 'xcode_version', nil, coerce_to_version
213
+ option :external_source_pods, ArrayOf.new(HashOf.new(keys: [String], values: [ArrayOf.new(HashOf.new(keys: [String], values: [String]))])),
214
+ [],
215
+ nil,
216
+ nil,
217
+ nil,
218
+ ->(external_sources) { Array(external_sources) }
206
219
 
207
220
  options.freeze
208
221
  options.each do |o|
@@ -302,12 +315,13 @@ module Pod
302
315
  end << ' }'
303
316
  end
304
317
 
305
- # @return [Pathname] the directory for installation of the generated workspace
318
+ # @return [Pathname] the directory for installation of the generated workspace.
306
319
  #
307
- # @param [String] name the name of the pod
320
+ # @param [Array<Specification>] specs The specs to get a directory name for.
308
321
  #
309
- def gen_dir_for_pod(name)
310
- gen_directory.join(name)
322
+ def gen_dir_for_specs(specs)
323
+ basename = specs.count == 1 ? specs.first.name : 'Workspace'
324
+ gen_directory.join(basename)
311
325
  end
312
326
 
313
327
  # @return [Boolean] whether gen should install with dynamic frameworks
@@ -318,14 +332,14 @@ module Pod
318
332
 
319
333
  # @return [String] The project name to use for generating this workspace.
320
334
  #
321
- # @param [Specification] spec
322
- # the specification to generate project name for.
335
+ # @param [Array<Specification>] specs
336
+ # the specifications to generate project name for.
323
337
  #
324
- def project_name_for_spec(spec)
325
- project_name = spec.name.dup
338
+ def project_name_for_specs(specs)
339
+ project_name = specs.count == 1 ? +specs.first.name.dup : +'Workspace'
326
340
  # When using multiple Xcode project the project name will collide with the actual .xcodeproj meant for the pod
327
341
  # that we are generating the workspace for.
328
- project_name << 'Sample' if generate_multiple_pod_projects?
342
+ project_name << 'Sample' if generate_multiple_pod_projects? && specs.count == 1
329
343
  project_name
330
344
  end
331
345
 
@@ -335,7 +349,10 @@ module Pod
335
349
  # @param [Array<Pathname,URI>] paths
336
350
  # the paths to search for podspecs
337
351
  #
338
- def self.podspecs_from_paths(paths)
352
+ # @param [Pathname] gen_directory
353
+ # the directory that the gen installation would occur into.
354
+ #
355
+ def self.podspecs_from_paths(paths, gen_directory)
339
356
  paths = [Pathname('.')] if paths.empty?
340
357
  paths.flat_map do |path|
341
358
  if path.is_a?(URI)
@@ -351,9 +368,16 @@ module Pod
351
368
  $ERROR_INFO
352
369
  end
353
370
  elsif path.directory?
354
- glob = Pathname.glob(path + '*.podspec{.json,}')
371
+ glob = Pathname.glob(path.expand_path + '**/*.podspec{.json,}').select { |f| f.relative_path_from(gen_directory).to_s.start_with?('..') }
372
+ glob.reject! { |f| File.basename(f.dirname) == 'Local Podspecs' && f.parent.parent.join('Manifest.lock').file? }
355
373
  next StandardError.new "no specs found in #{UI.path path}" if glob.empty?
356
- glob.map { |f| Pod::Specification.from_file(f) }.sort_by(&:name)
374
+ podspecs = glob.map { |f| Pod::Specification.from_file(f) }
375
+ podspecs.group_by(&:name).sort_by(&:first).flat_map do |name, specs|
376
+ if specs.size != 1
377
+ Pod::UI.warn("Multiple podspecs found for pod #{name}, which one will be used is undefined:#{specs.map { |s| "\n - #{s.defined_in_file}" }.join}")
378
+ end
379
+ specs
380
+ end
357
381
  else
358
382
  Pod::Specification.from_file(path)
359
383
  end
@@ -4,24 +4,40 @@ module Pod
4
4
  # given a configuration and a generated podfile.
5
5
  #
6
6
  class Installer
7
+ DEFAULT_XCODE_VERSION = '9.3'.freeze
8
+
9
+ XCODE_VERSION_TO_OBJECT_VERSION = {
10
+ '14.0' => 56,
11
+ '13.0' => 55,
12
+ '12.0' => 54,
13
+ '11.4' => 53,
14
+ '11.0' => 52,
15
+ '10.0' => 51,
16
+ '9.3' => 50,
17
+ '8.0' => 48,
18
+ '6.3' => 47,
19
+ '3.2' => 46,
20
+ '3.1' => 45
21
+ }.freeze
22
+
7
23
  # @return [Configuration]
8
24
  # the configuration to use when installing
9
25
  #
10
26
  attr_reader :configuration
11
27
 
12
- # @return [Specification]
28
+ # @return [Array<Specification>]
13
29
  # the spec whose workspace is being created
14
30
  #
15
- attr_reader :spec
31
+ attr_reader :specs
16
32
 
17
33
  # @return [Podfile]
18
34
  # the podfile to install
19
35
  #
20
36
  attr_reader :podfile
21
37
 
22
- def initialize(configuration, spec, podfile)
38
+ def initialize(configuration, specs, podfile)
23
39
  @configuration = configuration
24
- @spec = spec
40
+ @specs = specs
25
41
  @podfile = podfile
26
42
  end
27
43
 
@@ -37,7 +53,7 @@ module Pod
37
53
  # @return [void]
38
54
  #
39
55
  def install!
40
- UI.title "Generating #{spec.name} in #{UI.path install_directory}" do
56
+ UI.title "Generating workspace in #{UI.path install_directory}" do
41
57
  clean! if configuration.clean?
42
58
  install_directory.mkpath
43
59
 
@@ -89,11 +105,15 @@ module Pod
89
105
  end
90
106
 
91
107
  def open_app_project(recreate: false)
92
- app_project_path = install_directory.join("#{configuration.project_name_for_spec(spec)}.xcodeproj")
108
+ app_project_path = install_directory.join("#{configuration.project_name_for_specs(specs)}.xcodeproj")
93
109
  if !recreate && app_project_path.exist?
94
110
  Xcodeproj::Project.open(app_project_path)
95
111
  else
96
- Xcodeproj::Project.new(app_project_path)
112
+ version_key = XCODE_VERSION_TO_OBJECT_VERSION.keys.find do |k|
113
+ configuration.xcode_version >= Pod::Version.new(k)
114
+ end || DEFAULT_XCODE_VERSION
115
+ object_version = XCODE_VERSION_TO_OBJECT_VERSION[version_key]
116
+ Xcodeproj::Project.new(app_project_path, false, object_version)
97
117
  end
98
118
  end
99
119
 
@@ -104,27 +124,32 @@ module Pod
104
124
  def create_app_project
105
125
  app_project = open_app_project(recreate: !configuration.incremental_installation?)
106
126
 
107
- spec_platforms = spec.available_platforms.flatten.reject do |platform|
108
- !configuration.platforms.nil? && !configuration.platforms.include?(platform.string_name.downcase)
109
- end
127
+ platforms_by_spec = Hash[specs.map do |spec|
128
+ platforms = spec.available_platforms.flatten.reject do |platform|
129
+ !configuration.platforms.nil? && !configuration.platforms.include?(platform.string_name.downcase)
130
+ end
131
+ [spec, platforms]
132
+ end]
110
133
 
111
- if spec_platforms.empty?
112
- Pod::Command::Gen.help! Pod::StandardError.new "No available platforms in #{spec.name}.podspec match requested platforms: #{configuration.platforms}"
134
+ if platforms_by_spec.values.all?(&:empty?)
135
+ Pod::Command::Gen.help! Pod::StandardError.new "No available platforms for podspecs #{specs.map(&:name).to_sentence} match requested platforms: #{configuration.platforms}"
113
136
  end
114
137
 
115
- spec_platforms
116
- .map do |platform|
117
- consumer = spec.consumer(platform)
118
- target_name = "App-#{Platform.string_name(consumer.platform_name)}"
119
- next if app_project.targets.map(&:name).include? target_name
120
- native_app_target = Pod::Generator::AppTargetHelper.add_app_target(app_project, consumer.platform_name,
121
- deployment_target(consumer), target_name)
122
- # Temporarily set Swift version to pass validator checks for pods which do not specify Swift version.
123
- # It will then be re-set again within #perform_post_install_steps.
124
- Pod::Generator::AppTargetHelper.add_swift_version(native_app_target, Pod::Validator::DEFAULT_SWIFT_VERSION)
125
- native_app_target
138
+ platforms_by_spec
139
+ .flat_map do |spec, platforms|
140
+ platforms.map do |platform|
141
+ consumer = spec.consumer(platform)
142
+ target_name = "App-#{Platform.string_name(consumer.platform_name)}"
143
+ next if app_project.targets.map(&:name).include? target_name
144
+ native_app_target = Pod::Generator::AppTargetHelper.add_app_target(app_project, consumer.platform_name,
145
+ deployment_target(consumer), target_name)
146
+ # Temporarily set Swift version to pass validator checks for pods which do not specify Swift version.
147
+ # It will then be re-set again within #perform_post_install_steps.
148
+ Pod::Generator::AppTargetHelper.add_swift_version(native_app_target, Pod::Validator::DEFAULT_SWIFT_VERSION)
149
+ native_app_target
150
+ end
126
151
  end
127
- .compact.tap do
152
+ .compact.uniq.tap do
128
153
  app_project.recreate_user_schemes do |scheme, target|
129
154
  installation_result = installation_result_from_target(target)
130
155
  next unless installation_result
@@ -134,9 +159,10 @@ module Pod
134
159
  end
135
160
  end
136
161
  .each do |target|
137
- Xcodeproj::XCScheme.share_scheme(app_project.path, target.name) if target
162
+ Xcodeproj::XCScheme.share_scheme(app_project.path.to_s, target.name) if target
138
163
  end
139
164
  app_project.save
165
+ app_project
140
166
  end
141
167
 
142
168
  def deployment_target(consumer)
@@ -152,14 +178,16 @@ module Pod
152
178
  app_project.native_targets.each do |native_app_target|
153
179
  remove_script_phase_from_target(native_app_target, 'Check Pods Manifest.lock')
154
180
 
155
- pod_target = installer.pod_targets.find { |pt| pt.platform.name == native_app_target.platform_name && pt.pod_name == spec.name }
156
- raise "Unable to find a pod target for #{native_app_target} / #{spec}" unless pod_target
181
+ spec_names = specs.map(&:name)
182
+ pod_targets = installer.pod_targets.select do |pt|
183
+ pt.platform.name == native_app_target.platform_name && spec_names.include?(pt.pod_name)
184
+ end
157
185
 
158
186
  native_app_target.source_build_phase.clear
159
187
  native_app_target.resources_build_phase.clear
160
188
 
161
189
  if (app_host_source_dir = configuration.app_host_source_dir)
162
- relative_app_host_source_dir = app_host_source_dir.relative_path_from(installer.sandbox.root)
190
+ relative_app_host_source_dir = app_host_source_dir.relative_path_from(install_directory)
163
191
  groups = {}
164
192
 
165
193
  app_host_source_dir.find do |file|
@@ -189,22 +217,18 @@ module Pod
189
217
  source_file_ref = group.new_file(file.basename)
190
218
  native_app_target.add_file_references([source_file_ref])
191
219
  end
192
- elsif Pod::Generator::AppTargetHelper.method(:add_app_project_import).arity == -5 # CocoaPods >= 1.6
193
- # If we are doing incremental installation then the file might already be there.
220
+ else
194
221
  platform_name = Platform.string_name(native_app_target.platform_name)
195
222
  group = group_for_platform_name(app_project, platform_name)
196
223
  main_file_ref = group.files.find { |f| f.display_name == 'main.m' }
197
224
  if main_file_ref.nil?
198
- Pod::Generator::AppTargetHelper.add_app_project_import(app_project, native_app_target, pod_target,
199
- pod_target.platform.name, native_app_target.name)
225
+ source_file = create_main_source_file(app_project, pod_targets, native_app_target.name)
226
+ group = app_project[group.name] || app_project.new_group(group.name, group.name)
227
+ source_file_ref = group.new_file(source_file)
228
+ native_app_target.add_file_references([source_file_ref])
200
229
  else
201
230
  native_app_target.add_file_references([main_file_ref])
202
231
  end
203
- else
204
- Pod::Generator::AppTargetHelper.add_app_project_import(app_project, native_app_target, pod_target,
205
- pod_target.platform.name,
206
- pod_target.requires_frameworks?,
207
- native_app_target.name)
208
232
  end
209
233
 
210
234
  # Set `PRODUCT_BUNDLE_IDENTIFIER`
@@ -212,23 +236,32 @@ module Pod
212
236
  bc.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = 'org.cocoapods-generate.${PRODUCT_NAME:rfc1034identifier}'
213
237
  end
214
238
 
215
- case native_app_target.platform_name
239
+ case native_app_target.platform_name.to_sym
216
240
  when :ios
217
241
  make_ios_app_launchable(app_project, native_app_target)
242
+ when :osx
243
+ generate_infoplist_file(app_project, native_app_target)
244
+ when :tvos
245
+ generate_infoplist_file(app_project, native_app_target)
218
246
  end
219
247
 
220
- Pod::Generator::AppTargetHelper.add_swift_version(native_app_target, pod_target.swift_version) unless pod_target.swift_version.blank?
248
+ swift_version = pod_targets.map { |pt| Pod::Version.new(pt.swift_version) }.max.to_s
249
+
250
+ Pod::Generator::AppTargetHelper.add_swift_version(native_app_target, swift_version) unless swift_version.blank?
221
251
  if installer.pod_targets.any? { |pt| pt.spec_consumers.any? { |c| c.frameworks.include?('XCTest') } }
222
252
  Pod::Generator::AppTargetHelper.add_xctest_search_paths(native_app_target)
223
253
  end
224
254
 
225
- # Share the pods xcscheme only if it exists. For pre-built vendored pods there is no xcscheme generated.
226
- if installer.respond_to?(:generated_projects) # CocoaPods 1.7.0
227
- installer.generated_projects.each do |project|
228
- Xcodeproj::XCScheme.share_scheme(project.path, pod_target.label) if File.exist?(project.path + pod_target.label)
255
+ pod_targets.each do |pod_target|
256
+ result = installer.target_installation_results.pod_target_installation_results[pod_target.name]
257
+ next unless result
258
+ share_scheme(result.native_target.project, pod_target.label)
259
+ pod_target.test_specs.each do |test_spec|
260
+ share_scheme(result.native_target.project, pod_target.test_target_label(test_spec))
261
+ end
262
+ pod_target.app_specs.each do |app_spec|
263
+ share_scheme(result.native_target.project, pod_target.app_target_label(app_spec))
229
264
  end
230
- elsif File.exist?(installer.pods_project.path + pod_target.label)
231
- Xcodeproj::XCScheme.share_scheme(installer.pods_project.path, pod_target.label)
232
265
  end
233
266
 
234
267
  add_test_spec_schemes_to_app_scheme(installer, app_project)
@@ -252,23 +285,19 @@ module Pod
252
285
  end
253
286
 
254
287
  def add_test_spec_schemes_to_app_scheme(installer, app_project)
288
+ spec_root_names = Set.new(specs.map { |s| s.root.name })
289
+
255
290
  test_native_targets =
256
- if installer.respond_to?(:target_installation_results) # CocoaPods >= 1.6
257
- installer
258
- .target_installation_results
259
- .pod_target_installation_results
260
- .values
261
- .flatten(1)
262
- .select { |installation_result| installation_result.target.pod_name == spec.root.name }
263
- else
264
- installer
265
- .pod_targets
266
- .select { |pod_target| pod_target.pod_name == spec.root.name }
267
- end
291
+ installer
292
+ .target_installation_results
293
+ .pod_target_installation_results
294
+ .values
295
+ .flatten(1)
296
+ .select { |installation_result| spec_root_names.include?(installation_result.target.pod_name) }
268
297
  .flat_map(&:test_native_targets)
269
298
  .group_by(&:platform_name)
270
299
 
271
- workspace_path = install_directory + "#{spec.name}.xcworkspace"
300
+ workspace_path = install_directory + (configuration.project_name_for_specs(specs) + '.xcworkspace')
272
301
  Xcodeproj::Plist.write_to_path(
273
302
  { 'IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded' => false },
274
303
  workspace_path.join('xcshareddata').tap(&:mkpath).join('WorkspaceSettings.xcsettings')
@@ -287,7 +316,7 @@ module Pod
287
316
 
288
317
  testable = Xcodeproj::XCScheme::TestAction::TestableReference.new(target)
289
318
  testable.buildable_references.each do |buildable|
290
- buildable.xml_element.attributes['ReferencedContainer'] = 'container:Pods.xcodeproj'
319
+ buildable.xml_element.attributes['ReferencedContainer'] = "container:Pods/#{File.basename(target.project.path)}"
291
320
  end
292
321
  test_action.add_testable(testable)
293
322
  end
@@ -368,6 +397,15 @@ module Pod
368
397
  native_app_target.resources_build_phase.add_file_reference(launch_storyboard_file_ref)
369
398
  end
370
399
 
400
+ def generate_infoplist_file(_app_project, native_app_target)
401
+ # Starting in Xcode 14, there is an error when you build the macOS or
402
+ # tvOS app that is generated from cocoapods-generate. This implements
403
+ # the suggested change.
404
+ native_app_target.build_configurations.each do |bc|
405
+ bc.build_settings['GENERATE_INFOPLIST_FILE'] = 'YES'
406
+ end
407
+ end
408
+
371
409
  def group_for_platform_name(project, platform_name, should_create = true)
372
410
  project.main_group.find_subpath("App-#{platform_name}", should_create)
373
411
  end
@@ -380,9 +418,37 @@ module Pod
380
418
  Executable.execute_command 'open', [workspace_path]
381
419
  end
382
420
  else
383
- UI.info "Open #{UI.path workspace_path} to work on #{spec.name}"
421
+ UI.info "Open #{UI.path workspace_path} to work on it!"
384
422
  end
385
423
  end
424
+
425
+ def share_scheme(project, scheme_name)
426
+ scheme = Xcodeproj::XCScheme.user_data_dir(project.path) + "#{scheme_name}.xcscheme"
427
+ return unless File.exist?(scheme)
428
+ Xcodeproj::XCScheme.share_scheme(project.path, scheme_name)
429
+ end
430
+
431
+ def create_main_source_file(project, pod_targets, name)
432
+ source_file = project.path.dirname.+("#{name}/main.m")
433
+ source_file.parent.mkpath
434
+
435
+ import_statements = pod_targets.map do |pod_target|
436
+ if pod_target.should_build? && pod_target.defines_module?
437
+ "@import #{pod_target.product_module_name};"
438
+ else
439
+ header_name = "#{pod_target.product_module_name}/#{pod_target.product_module_name}.h"
440
+ "#import <#{header_name}>" if pod_target.sandbox.public_headers.root.+(header_name).file?
441
+ end
442
+ end.compact
443
+
444
+ source_file.open('w') do |f|
445
+ f << import_statements.join("\n")
446
+ f << "\n" unless import_statements.empty?
447
+ f << "int main() { return 0; }\n"
448
+ end
449
+
450
+ source_file
451
+ end
386
452
  end
387
453
  end
388
454
  end
@@ -14,27 +14,28 @@ module Pod
14
14
  @configuration = configuration
15
15
  end
16
16
 
17
- # @return [Hash<Specification, Podfile>]
18
- # a hash of specifications to generated podfiles
17
+ # @return [Hash<Array<Specification>, Podfile>] the podfiles keyed by the specs that are part of each.
19
18
  #
20
- def podfiles_by_spec
19
+ def podfiles_by_specs
20
+ return { configuration.podspecs => podfile_for_specs(configuration.podspecs) } if configuration.single_workspace?
21
21
  Hash[configuration.podspecs.map do |spec|
22
- [spec, podfile_for_spec(spec)]
22
+ [[spec], podfile_for_specs([spec])]
23
23
  end]
24
24
  end
25
25
 
26
26
  # @return [Podfile] a podfile suitable for installing the given spec
27
27
  #
28
- # @param [Specification] spec
28
+ # @param [Array<Specification>] specs
29
29
  #
30
- def podfile_for_spec(spec)
30
+ def podfile_for_specs(specs)
31
31
  generator = self
32
- dir = configuration.gen_dir_for_pod(spec.name)
33
- project_name = configuration.project_name_for_spec(spec)
32
+ dir = configuration.gen_dir_for_specs(specs)
33
+ project_name = configuration.project_name_for_specs(specs)
34
+ external_source_pods = configuration.external_source_pods
34
35
 
35
36
  Pod::Podfile.new do
36
37
  project "#{project_name}.xcodeproj"
37
- workspace "#{spec.name}.xcworkspace"
38
+ workspace "#{project_name}.xcworkspace"
38
39
 
39
40
  plugin 'cocoapods-generate'
40
41
 
@@ -57,24 +58,32 @@ module Pod
57
58
 
58
59
  self.defined_in_file = dir.join('CocoaPods.podfile.yaml')
59
60
 
60
- test_specs = spec.recursive_subspecs.select(&:test_specification?)
61
- app_specs = if spec.respond_to?(:app_specification?)
62
- spec.recursive_subspecs.select(&:app_specification?)
63
- else
64
- []
65
- end
61
+ test_specs_by_spec = Hash[specs.map do |spec|
62
+ [spec, spec.recursive_subspecs.select(&:test_specification?)]
63
+ end]
64
+ app_specs_by_spec = Hash[specs.map do |spec|
65
+ app_specs = if spec.respond_to?(:app_specification?)
66
+ spec.recursive_subspecs.select(&:app_specification?)
67
+ else
68
+ []
69
+ end
70
+ [spec, app_specs]
71
+ end]
66
72
 
67
73
  # Stick all of the transitive dependencies in an abstract target.
68
74
  # This allows us to force CocoaPods to use the versions / sources / external sources
69
75
  # that we want.
70
- # By using an abstract target,
71
76
  abstract_target 'Transitive Dependencies' do
72
- pods_for_transitive_dependencies = [spec.name]
73
- .concat(test_specs.map(&:name))
74
- .concat(test_specs.flat_map { |ts| ts.dependencies.flat_map(&:name) })
75
- .concat(app_specs.map(&:name))
76
- .concat(app_specs.flat_map { |as| as.dependencies.flat_map(&:name) })
77
+ pods_for_transitive_dependencies = specs.flat_map do |spec|
78
+ [spec.name]
79
+ .concat(test_specs_by_spec.keys.map(&:name))
80
+ .concat(test_specs_by_spec.values.flatten.flat_map { |ts| ts.dependencies.flat_map(&:name) })
81
+ .concat(app_specs_by_spec.keys.map(&:name))
82
+ .concat(app_specs_by_spec.values.flatten.flat_map { |as| as.dependencies.flat_map(&:name) })
83
+ end
84
+ pods_for_transitive_dependencies.uniq!
77
85
 
86
+ spec_names = specs.map { |s| s.root.name }.to_set
78
87
  dependencies = generator
79
88
  .transitive_dependencies_by_pod
80
89
  .values_at(*pods_for_transitive_dependencies)
@@ -82,17 +91,26 @@ module Pod
82
91
  .flatten(1)
83
92
  .uniq
84
93
  .sort_by(&:name)
85
- .reject { |d| d.root_name == spec.root.name }
94
+ .reject { |d| spec_names.include?(d.root_name) }
86
95
 
87
96
  dependencies.each do |dependency|
88
- pod_args = generator.pod_args_for_dependency(self, dependency)
97
+ pod_args = generator.pod_args_for_podfile_dependency(self, dependency)
89
98
  pod(*pod_args)
90
99
  end
100
+
101
+ external_source_pods.each do |hash|
102
+ hash.each do |name, attrs|
103
+ next if spec_names.include?(name)
104
+
105
+ dependency = Dependency.new(name, attrs.first.deep_symbolize_keys)
106
+ pod_args = generator.pod_args_for_dependency(nil, dependency)
107
+ pod(*pod_args)
108
+ end
109
+ end
91
110
  end
92
111
 
93
- # Add platform-specific concrete targets that inherit the
94
- # `pod` declaration for the local pod.
95
- spec_platform_names = spec.available_platforms.map(&:string_name).flatten.each.reject do |platform_name|
112
+ # Add platform-specific concrete targets that inherit the `pod` declaration for the local pod.
113
+ spec_platform_names = specs.flat_map { |s| s.available_platforms.map(&:string_name) }.uniq.each.reject do |platform_name|
96
114
  !generator.configuration.platforms.nil? && !generator.configuration.platforms.include?(platform_name.downcase)
97
115
  end
98
116
 
@@ -117,26 +135,31 @@ module Pod
117
135
  inhibit_all_warnings! if generator.inhibit_all_warnings?
118
136
  use_modular_headers! if generator.use_modular_headers?
119
137
 
120
- # This is the pod declaration for the local pod,
121
- # it will be inherited by the concrete target definitions below
122
- pod_options = generator.dependency_compilation_kwargs(spec.name)
123
- pod_options[:path] = spec.defined_in_file.relative_path_from(dir).to_s
124
- { testspecs: test_specs, appspecs: app_specs }.each do |key, specs|
125
- pod_options[key] = specs.map { |s| s.name.sub(%r{^#{Regexp.escape spec.root.name}/}, '') }.sort unless specs.empty?
126
- end
138
+ specs.each do |spec|
139
+ # This is the pod declaration for the local pod,
140
+ # it will be inherited by the concrete target definitions below
141
+ pod_options = generator.dependency_compilation_kwargs(spec.name)
127
142
 
128
- pod spec.name, **pod_options
143
+ path = spec.defined_in_file.relative_path_from(dir).to_s
144
+ pod_options[:path] = path
145
+ { testspecs: test_specs_by_spec[spec], appspecs: app_specs_by_spec[spec] }.each do |key, subspecs|
146
+ pod_options[key] = subspecs.map { |s| s.name.sub(%r{^#{Regexp.escape spec.root.name}/}, '') }.sort unless subspecs.blank?
147
+ end
148
+ pod spec.name, **pod_options
149
+ end
129
150
 
130
151
  # Implement local-sources option to set up dependencies to podspecs in the local filesystem.
131
152
  next if generator.configuration.local_sources.empty?
132
- generator.transitive_local_dependencies(spec, generator.configuration.local_sources).sort_by(&:first).each do |dependency, podspec_file|
133
- pod_options = generator.dependency_compilation_kwargs(dependency.name)
134
- pod_options[:path] = if podspec_file[0] == '/' # absolute path
135
- podspec_file
136
- else
137
- '../../' + podspec_file
138
- end
139
- pod dependency.name, **pod_options
153
+ specs.each do |spec|
154
+ generator.transitive_local_dependencies(spec, generator.configuration.local_sources).sort_by(&:first).each do |dependency, podspec_file|
155
+ pod_options = generator.dependency_compilation_kwargs(dependency.name)
156
+ pod_options[:path] = if podspec_file[0] == '/' # absolute path
157
+ podspec_file
158
+ else
159
+ '../../' + podspec_file
160
+ end
161
+ pod dependency.name, **pod_options
162
+ end
140
163
  end
141
164
  end
142
165
  end
@@ -279,12 +302,23 @@ module Pod
279
302
  #
280
303
  # @param [Dependency] dependency
281
304
  #
282
- def pod_args_for_dependency(podfile, dependency)
305
+ def pod_args_for_podfile_dependency(podfile, dependency)
283
306
  dependency = podfile_dependencies[dependency.root_name]
284
307
  .map { |dep| dep.dup.tap { |d| d.name = dependency.name } }
285
308
  .push(dependency)
286
309
  .reduce(&:merge)
310
+ pod_args_for_dependency(podfile, dependency)
311
+ end
287
312
 
313
+ # @return [Hash<String,Array<Dependency>>]
314
+ # returns the arguments that should be passed to the Podfile DSL's
315
+ # `pod` method.
316
+ #
317
+ # @param [Podfile] podfile
318
+ #
319
+ # @param [Dependency] dependency
320
+ #
321
+ def pod_args_for_dependency(podfile, dependency)
288
322
  options = dependency_compilation_kwargs(dependency.name)
289
323
  options[:source] = dependency.podspec_repo if dependency.podspec_repo
290
324
  options.update(dependency.external_source) if dependency.external_source
@@ -325,7 +359,7 @@ module Pod
325
359
  def installation_options
326
360
  installation_options = {
327
361
  deterministic_uuids: configuration.deterministic_uuids?,
328
- share_schemes_for_development_pods: configuration.share_schemes_for_development_pods?,
362
+ share_schemes_for_development_pods: configuration.share_schemes_for_development_pods,
329
363
  warn_for_multiple_pod_sources: configuration.warn_for_multiple_pod_sources?
330
364
  }
331
365
 
@@ -337,6 +371,10 @@ module Pod
337
371
  installation_options[:incremental_installation] = configuration.incremental_installation?
338
372
  end
339
373
 
374
+ if Pod::Installer::InstallationOptions.all_options.include?('disable_input_output_paths')
375
+ installation_options[:disable_input_output_paths] = configuration.disable_input_output_paths
376
+ end
377
+
340
378
  installation_options
341
379
  end
342
380
 
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocoapods-generate
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Giddins
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-03 00:00:00.000000000 Z
11
+ date: 2023-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cocoapods-disable-podfile-validations
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.1.1
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 0.3.0
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: 0.1.1
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 0.3.0
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: bundler
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -101,7 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
107
  - !ruby/object:Gem::Version
102
108
  version: '0'
103
109
  requirements: []
104
- rubygems_version: 3.0.1
110
+ rubygems_version: 3.3.7
105
111
  signing_key:
106
112
  specification_version: 4
107
113
  summary: Generates Xcode workspaces from a podspec.