cocoapods-generate 2.0.1 → 2.2.4

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.
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.