cocoapods-generate 1.6.0 → 2.2.0

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: 444c04f0d19618e1220c68828b385d2a5360b63f359f6d5c97840c92ec4c82f5
4
- data.tar.gz: 953c104741ea87c0629466cd2db8e6b27f2a9d3b395b7a18b76b714fec8d926c
3
+ metadata.gz: 2145be6fd1f163f41cdd8bcba9ea779ae778d1fe23f01f73fd21bc6303c289a6
4
+ data.tar.gz: 46d4ba1d2f392403d8e24d82f0c1ff305df62ea42cdde91ea0587400d6a3e484
5
5
  SHA512:
6
- metadata.gz: fdf382c8e04699dfb9c206fdc97fb892d39fd7b3d5403fa2118127c2caf92330bd7445b49bc38542ce67aae075002c412633ba09600a3682e20a797ae6d2bae5
7
- data.tar.gz: 237a7ab95303b502f3f0e8b525a3c6f4f640031d55b5ceab88a963806b762f51b15c7197a23c779cae4fd39e54aecb5c47e9daa0a2e0f93b03f84fbaa26c05c7
6
+ metadata.gz: 0d62df5b33c54a60348728eb036c47aa22ce1c52a120dc6de294ab4577a08b014cd748b29738a5ab498c7df4cf1f131252153cfa4575f4e6a6c1a564d37a3360
7
+ data.tar.gz: 733dfed2775abdb8d93f6c33e9d1ee14a1089d4d0719e0decac5d82bf8c08a3a6f250dee4d7ff8f69c5eb252f9cb2ee6391ff8d6730896a2872a13f6b06f6a8a
data/README.md CHANGED
@@ -47,6 +47,7 @@ Usage:
47
47
 
48
48
  Options:
49
49
 
50
+ --allow-root Allows CocoaPods to run as root
50
51
  --silent Show nothing
51
52
  --verbose Show more debugging information
52
53
  --no-ansi Show output without ANSI codes
@@ -88,6 +89,9 @@ Options:
88
89
  default plugins
89
90
  --deterministic-uuids Whether installation should use
90
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)
91
95
  --share-schemes-for-development-pods Whether installation should share schemes
92
96
  for development pods
93
97
  --warn-for-multiple-pod-sources Whether installation should warn when a pod
@@ -97,6 +101,10 @@ Options:
97
101
  modules, as if `use_modular_headers!` were
98
102
  specified. Will error if both this option
99
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
100
108
  ```
101
109
  <!-- end cli usage -->
102
110
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.6.0
1
+ 2.2.0
@@ -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)
@@ -86,10 +86,12 @@ module Pod
86
86
  path = dir + '.gen_config.yml'
87
87
  next unless path.file?
88
88
  Pod::Generate::Configuration.from_file(path)
89
- end
89
+ end.compact
90
+
91
+ options.delete(:podspec_paths) if options[:podspec_paths].empty? && config_hashes.any? { |h| h.include?(:podspec_paths) }
90
92
 
91
93
  env = Generate::Configuration.from_env(ENV)
92
- config_hashes.insert(-2, env)
94
+ config_hashes = [env] + config_hashes
93
95
  config_hashes << options
94
96
 
95
97
  configuration = config_hashes.compact.each_with_object({}) { |e, h| h.merge!(e) }
@@ -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,13 @@ 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
206
213
 
207
214
  options.freeze
208
215
  options.each do |o|
@@ -302,12 +309,13 @@ module Pod
302
309
  end << ' }'
303
310
  end
304
311
 
305
- # @return [Pathname] the directory for installation of the generated workspace
312
+ # @return [Pathname] the directory for installation of the generated workspace.
306
313
  #
307
- # @param [String] name the name of the pod
314
+ # @param [Array<Specification>] specs The specs to get a directory name for.
308
315
  #
309
- def gen_dir_for_pod(name)
310
- gen_directory.join(name)
316
+ def gen_dir_for_specs(specs)
317
+ basename = specs.count == 1 ? specs.first.name : 'Workspace'
318
+ gen_directory.join(basename)
311
319
  end
312
320
 
313
321
  # @return [Boolean] whether gen should install with dynamic frameworks
@@ -316,13 +324,29 @@ module Pod
316
324
  !use_libraries?
317
325
  end
318
326
 
327
+ # @return [String] The project name to use for generating this workspace.
328
+ #
329
+ # @param [Array<Specification>] specs
330
+ # the specifications to generate project name for.
331
+ #
332
+ def project_name_for_specs(specs)
333
+ project_name = specs.count == 1 ? +specs.first.name.dup : +'Workspace'
334
+ # When using multiple Xcode project the project name will collide with the actual .xcodeproj meant for the pod
335
+ # that we are generating the workspace for.
336
+ project_name << 'Sample' if generate_multiple_pod_projects? && specs.count == 1
337
+ project_name
338
+ end
339
+
319
340
  # @return [Array<Specification>] the podspecs found at the given paths.
320
341
  # This method will download specs from URLs and traverse a directory's children.
321
342
  #
322
343
  # @param [Array<Pathname,URI>] paths
323
344
  # the paths to search for podspecs
324
345
  #
325
- def self.podspecs_from_paths(paths)
346
+ # @param [Pathname] gen_directory
347
+ # the directory that the gen installation would occur into.
348
+ #
349
+ def self.podspecs_from_paths(paths, gen_directory)
326
350
  paths = [Pathname('.')] if paths.empty?
327
351
  paths.flat_map do |path|
328
352
  if path.is_a?(URI)
@@ -338,9 +362,9 @@ module Pod
338
362
  $ERROR_INFO
339
363
  end
340
364
  elsif path.directory?
341
- glob = Pathname.glob(path + '*.podspec{.json,}')
365
+ glob = Pathname.glob(path.expand_path + '**/*.podspec{.json,}').select { |f| f.relative_path_from(gen_directory).to_s.start_with?('..') }
342
366
  next StandardError.new "no specs found in #{UI.path path}" if glob.empty?
343
- glob.map { |f| Pod::Specification.from_file(f) }
367
+ glob.map { |f| Pod::Specification.from_file(f) }.sort_by(&:name)
344
368
  else
345
369
  Pod::Specification.from_file(path)
346
370
  end
@@ -4,24 +4,38 @@ 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
+ '12.0' => 54,
11
+ '11.4' => 53,
12
+ '11.0' => 52,
13
+ '10.0' => 51,
14
+ '9.3' => 50,
15
+ '8.0' => 48,
16
+ '6.3' => 47,
17
+ '3.2' => 46,
18
+ '3.1' => 45
19
+ }.freeze
20
+
7
21
  # @return [Configuration]
8
22
  # the configuration to use when installing
9
23
  #
10
24
  attr_reader :configuration
11
25
 
12
- # @return [Specification]
26
+ # @return [Array<Specification>]
13
27
  # the spec whose workspace is being created
14
28
  #
15
- attr_reader :spec
29
+ attr_reader :specs
16
30
 
17
31
  # @return [Podfile]
18
32
  # the podfile to install
19
33
  #
20
34
  attr_reader :podfile
21
35
 
22
- def initialize(configuration, spec, podfile)
36
+ def initialize(configuration, specs, podfile)
23
37
  @configuration = configuration
24
- @spec = spec
38
+ @specs = specs
25
39
  @podfile = podfile
26
40
  end
27
41
 
@@ -37,7 +51,7 @@ module Pod
37
51
  # @return [void]
38
52
  #
39
53
  def install!
40
- UI.title "Generating #{spec.name} in #{UI.path install_directory}" do
54
+ UI.title "Generating workspace in #{UI.path install_directory}" do
41
55
  clean! if configuration.clean?
42
56
  install_directory.mkpath
43
57
 
@@ -51,7 +65,12 @@ module Pod
51
65
 
52
66
  installer = nil
53
67
  UI.section 'Installing...' do
54
- configuration.pod_config.with_changes(installation_root: install_directory, podfile: podfile, lockfile: configuration.lockfile, sandbox: nil, sandbox_root: install_directory, podfile_path: podfile.defined_in_file, silent: !configuration.pod_config.verbose?, verbose: false, lockfile_path: nil) do
68
+ configuration.pod_config.with_changes(installation_root: install_directory, podfile: podfile,
69
+ lockfile: configuration.lockfile, sandbox: nil,
70
+ sandbox_root: install_directory + 'Pods',
71
+ podfile_path: podfile.defined_in_file,
72
+ silent: !configuration.pod_config.verbose?, verbose: false,
73
+ lockfile_path: nil) do
55
74
  installer = ::Pod::Installer.new(configuration.pod_config.sandbox, podfile, configuration.lockfile)
56
75
  installer.use_default_plugins = configuration.use_default_plugins
57
76
  installer.install!
@@ -59,7 +78,12 @@ module Pod
59
78
  end
60
79
 
61
80
  UI.section 'Performing post-installation steps' do
62
- perform_post_install_steps(open_app_project, installer)
81
+ should_perform_post_install = if installer.respond_to?(:generated_aggregate_targets) # CocoaPods 1.7.0
82
+ !installer.generated_aggregate_targets.empty?
83
+ else
84
+ true
85
+ end
86
+ perform_post_install_steps(open_app_project, installer) if should_perform_post_install
63
87
  end
64
88
 
65
89
  print_post_install_message
@@ -79,11 +103,15 @@ module Pod
79
103
  end
80
104
 
81
105
  def open_app_project(recreate: false)
82
- app_project_path = install_directory.join("#{spec.name}.xcodeproj")
106
+ app_project_path = install_directory.join("#{configuration.project_name_for_specs(specs)}.xcodeproj")
83
107
  if !recreate && app_project_path.exist?
84
108
  Xcodeproj::Project.open(app_project_path)
85
109
  else
86
- Xcodeproj::Project.new(app_project_path)
110
+ version_key = XCODE_VERSION_TO_OBJECT_VERSION.keys.find do |k|
111
+ configuration.xcode_version >= Pod::Version.new(k)
112
+ end || DEFAULT_XCODE_VERSION
113
+ object_version = XCODE_VERSION_TO_OBJECT_VERSION[version_key]
114
+ Xcodeproj::Project.new(app_project_path, false, object_version)
87
115
  end
88
116
  end
89
117
 
@@ -92,25 +120,34 @@ module Pod
92
120
  # @return [Xcodeproj::Project]
93
121
  #
94
122
  def create_app_project
95
- app_project = open_app_project(recreate: true)
123
+ app_project = open_app_project(recreate: !configuration.incremental_installation?)
124
+
125
+ platforms_by_spec = Hash[specs.map do |spec|
126
+ platforms = spec.available_platforms.flatten.reject do |platform|
127
+ !configuration.platforms.nil? && !configuration.platforms.include?(platform.string_name.downcase)
128
+ end
129
+ [spec, platforms]
130
+ end]
96
131
 
97
- spec_platforms = spec.available_platforms.flatten.reject do |platform|
98
- !configuration.platforms.nil? && !configuration.platforms.include?(platform.string_name.downcase)
132
+ if platforms_by_spec.values.all?(&:empty?)
133
+ Pod::Command::Gen.help! Pod::StandardError.new "No available platforms for podspecs #{specs.map(&:name).to_sentence} match requested platforms: #{configuration.platforms}"
99
134
  end
100
135
 
101
- Pod::Command::Gen.help! Pod::StandardError.new "No available platforms in #{spec.name}.podspec match requested platforms: #{configuration.platforms}" if spec_platforms.empty?
102
-
103
- spec_platforms
104
- .map do |platform|
105
- consumer = spec.consumer(platform)
106
- target_name = "App-#{Platform.string_name(consumer.platform_name)}"
107
- native_app_target = Pod::Generator::AppTargetHelper.add_app_target(app_project, consumer.platform_name, deployment_target(consumer), target_name)
108
- # Temporarily set Swift version to pass validator checks for pods which do not specify Swift version.
109
- # It will then be re-set again within #perform_post_install_steps.
110
- Pod::Generator::AppTargetHelper.add_swift_version(native_app_target, Pod::Validator::DEFAULT_SWIFT_VERSION)
111
- native_app_target
136
+ platforms_by_spec
137
+ .flat_map do |spec, platforms|
138
+ platforms.map do |platform|
139
+ consumer = spec.consumer(platform)
140
+ target_name = "App-#{Platform.string_name(consumer.platform_name)}"
141
+ next if app_project.targets.map(&:name).include? target_name
142
+ native_app_target = Pod::Generator::AppTargetHelper.add_app_target(app_project, consumer.platform_name,
143
+ deployment_target(consumer), target_name)
144
+ # Temporarily set Swift version to pass validator checks for pods which do not specify Swift version.
145
+ # It will then be re-set again within #perform_post_install_steps.
146
+ Pod::Generator::AppTargetHelper.add_swift_version(native_app_target, Pod::Validator::DEFAULT_SWIFT_VERSION)
147
+ native_app_target
148
+ end
112
149
  end
113
- .tap do
150
+ .compact.uniq.tap do
114
151
  app_project.recreate_user_schemes do |scheme, target|
115
152
  installation_result = installation_result_from_target(target)
116
153
  next unless installation_result
@@ -120,9 +157,10 @@ module Pod
120
157
  end
121
158
  end
122
159
  .each do |target|
123
- Xcodeproj::XCScheme.share_scheme(app_project.path, target.name) if target
160
+ Xcodeproj::XCScheme.share_scheme(app_project.path.to_s, target.name) if target
124
161
  end
125
162
  app_project.save
163
+ app_project
126
164
  end
127
165
 
128
166
  def deployment_target(consumer)
@@ -138,8 +176,13 @@ module Pod
138
176
  app_project.native_targets.each do |native_app_target|
139
177
  remove_script_phase_from_target(native_app_target, 'Check Pods Manifest.lock')
140
178
 
141
- pod_target = installer.pod_targets.find { |pt| pt.platform.name == native_app_target.platform_name && pt.pod_name == spec.name }
142
- raise "unable to find a pod target for #{native_app_target} / #{spec}" unless pod_target
179
+ spec_names = specs.map(&:name)
180
+ pod_targets = installer.pod_targets.select do |pt|
181
+ pt.platform.name == native_app_target.platform_name && spec_names.include?(pt.pod_name)
182
+ end
183
+
184
+ native_app_target.source_build_phase.clear
185
+ native_app_target.resources_build_phase.clear
143
186
 
144
187
  if (app_host_source_dir = configuration.app_host_source_dir)
145
188
  relative_app_host_source_dir = app_host_source_dir.relative_path_from(installer.sandbox.root)
@@ -172,10 +215,18 @@ module Pod
172
215
  source_file_ref = group.new_file(file.basename)
173
216
  native_app_target.add_file_references([source_file_ref])
174
217
  end
175
- elsif Pod::Generator::AppTargetHelper.method(:add_app_project_import).arity == -5 # CocoaPods >= 1.6
176
- Pod::Generator::AppTargetHelper.add_app_project_import(app_project, native_app_target, pod_target, pod_target.platform.name, native_app_target.name)
177
218
  else
178
- Pod::Generator::AppTargetHelper.add_app_project_import(app_project, native_app_target, pod_target, pod_target.platform.name, pod_target.requires_frameworks?, native_app_target.name)
219
+ platform_name = Platform.string_name(native_app_target.platform_name)
220
+ group = group_for_platform_name(app_project, platform_name)
221
+ main_file_ref = group.files.find { |f| f.display_name == 'main.m' }
222
+ if main_file_ref.nil?
223
+ source_file = create_main_source_file(app_project, pod_targets, native_app_target.name)
224
+ group = app_project[group.name] || app_project.new_group(group.name, group.name)
225
+ source_file_ref = group.new_file(source_file)
226
+ native_app_target.add_file_references([source_file_ref])
227
+ else
228
+ native_app_target.add_file_references([main_file_ref])
229
+ end
179
230
  end
180
231
 
181
232
  # Set `PRODUCT_BUNDLE_IDENTIFIER`
@@ -185,21 +236,25 @@ module Pod
185
236
 
186
237
  case native_app_target.platform_name
187
238
  when :ios
188
- make_ios_app_launchable(installer, app_project, native_app_target)
239
+ make_ios_app_launchable(app_project, native_app_target)
189
240
  end
190
241
 
191
- Pod::Generator::AppTargetHelper.add_swift_version(native_app_target, pod_target.swift_version) unless pod_target.swift_version.blank?
242
+ swift_version = pod_targets.map { |pt| Pod::Version.new(pt.swift_version) }.max.to_s
243
+
244
+ Pod::Generator::AppTargetHelper.add_swift_version(native_app_target, swift_version) unless swift_version.blank?
192
245
  if installer.pod_targets.any? { |pt| pt.spec_consumers.any? { |c| c.frameworks.include?('XCTest') } }
193
246
  Pod::Generator::AppTargetHelper.add_xctest_search_paths(native_app_target)
194
247
  end
195
248
 
196
- # Share the pods xcscheme only if it exists. For pre-built vendored pods there is no xcscheme generated.
197
- if installer.respond_to?(:generated_projects) # CocoaPods 1.7.0
198
- installer.generated_projects.each do |project|
199
- Xcodeproj::XCScheme.share_scheme(project.path, pod_target.label) if File.exist?(project.path + pod_target.label)
249
+ pod_targets.each do |pod_target|
250
+ result = installer.target_installation_results.pod_target_installation_results[pod_target.name]
251
+ share_scheme(result.native_target.project, pod_target.label)
252
+ pod_target.test_specs.each do |test_spec|
253
+ share_scheme(result.native_target.project, pod_target.test_target_label(test_spec))
254
+ end
255
+ pod_target.app_specs.each do |app_spec|
256
+ share_scheme(result.native_target.project, pod_target.app_target_label(app_spec))
200
257
  end
201
- elsif File.exist?(installer.pods_project.path + pod_target.label)
202
- Xcodeproj::XCScheme.share_scheme(installer.pods_project.path, pod_target.label)
203
258
  end
204
259
 
205
260
  add_test_spec_schemes_to_app_scheme(installer, app_project)
@@ -223,25 +278,22 @@ module Pod
223
278
  end
224
279
 
225
280
  def add_test_spec_schemes_to_app_scheme(installer, app_project)
281
+ spec_root_names = Set.new(specs.map { |s| s.root.name })
282
+
226
283
  test_native_targets =
227
- if installer.respond_to?(:target_installation_results) # CocoaPods >= 1.6
228
- installer
229
- .target_installation_results
230
- .pod_target_installation_results
231
- .values
232
- .flatten(1)
233
- .select { |installation_result| installation_result.target.pod_name == spec.root.name }
234
- else
235
- installer
236
- .pod_targets
237
- .select { |pod_target| pod_target.pod_name == spec.root.name }
238
- end
284
+ installer
285
+ .target_installation_results
286
+ .pod_target_installation_results
287
+ .values
288
+ .flatten(1)
289
+ .select { |installation_result| spec_root_names.include?(installation_result.target.pod_name) }
239
290
  .flat_map(&:test_native_targets)
240
291
  .group_by(&:platform_name)
241
292
 
293
+ workspace_path = install_directory + (configuration.project_name_for_specs(specs) + '.xcworkspace')
242
294
  Xcodeproj::Plist.write_to_path(
243
295
  { 'IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded' => false },
244
- app_project.path.sub_ext('.xcworkspace').join('xcshareddata').tap(&:mkpath).join('WorkspaceSettings.xcsettings')
296
+ workspace_path.join('xcshareddata').tap(&:mkpath).join('WorkspaceSettings.xcsettings')
245
297
  )
246
298
 
247
299
  test_native_targets.each do |platform_name, test_targets|
@@ -257,7 +309,7 @@ module Pod
257
309
 
258
310
  testable = Xcodeproj::XCScheme::TestAction::TestableReference.new(target)
259
311
  testable.buildable_references.each do |buildable|
260
- buildable.xml_element.attributes['ReferencedContainer'] = 'container:Pods.xcodeproj'
312
+ buildable.xml_element.attributes['ReferencedContainer'] = "container:Pods/#{File.basename(target.project.path)}"
261
313
  end
262
314
  test_action.add_testable(testable)
263
315
  end
@@ -266,9 +318,9 @@ module Pod
266
318
  end
267
319
  end
268
320
 
269
- def make_ios_app_launchable(installer, app_project, native_app_target)
321
+ def make_ios_app_launchable(app_project, native_app_target)
270
322
  platform_name = Platform.string_name(native_app_target.platform_name)
271
- generated_source_dir = installer.sandbox.root.join('App', platform_name).tap(&:mkpath)
323
+ generated_source_dir = install_directory.join("App-#{platform_name}").tap(&:mkpath)
272
324
 
273
325
  # Add `LaunchScreen.storyboard`
274
326
  launch_storyboard = generated_source_dir.join('LaunchScreen.storyboard')
@@ -329,12 +381,17 @@ module Pod
329
381
  Xcodeproj::Plist.write_to_path(info_plist_contents, info_plist_path)
330
382
 
331
383
  native_app_target.build_configurations.each do |bc|
332
- bc.build_settings['INFOPLIST_FILE'] = "${SRCROOT}/App/#{platform_name}/Info.plist"
384
+ bc.build_settings['INFOPLIST_FILE'] = "${SRCROOT}/App-#{platform_name}/Info.plist"
333
385
  end
334
386
 
335
- group = app_project.main_group.find_subpath("App-#{platform_name}", true)
336
- group.new_file(info_plist_path)
337
- native_app_target.resources_build_phase.add_file_reference group.new_file(launch_storyboard)
387
+ group = group_for_platform_name(app_project, platform_name)
388
+ group.files.find { |f| f.display_name == 'Info.plist' } || group.new_file(info_plist_path)
389
+ launch_storyboard_file_ref = group.files.find { |f| f.display_name == 'LaunchScreen.storyboard' } || group.new_file(launch_storyboard)
390
+ native_app_target.resources_build_phase.add_file_reference(launch_storyboard_file_ref)
391
+ end
392
+
393
+ def group_for_platform_name(project, platform_name, should_create = true)
394
+ project.main_group.find_subpath("App-#{platform_name}", should_create)
338
395
  end
339
396
 
340
397
  def print_post_install_message
@@ -345,8 +402,36 @@ module Pod
345
402
  Executable.execute_command 'open', [workspace_path]
346
403
  end
347
404
  else
348
- UI.info "Open #{UI.path workspace_path} to work on #{spec.name}"
405
+ UI.info "Open #{UI.path workspace_path} to work on it!"
406
+ end
407
+ end
408
+
409
+ def share_scheme(project, scheme_name)
410
+ scheme = Xcodeproj::XCScheme.user_data_dir(project.path) + "#{scheme_name}.xcscheme"
411
+ return unless File.exist?(scheme)
412
+ Xcodeproj::XCScheme.share_scheme(project.path, scheme_name)
413
+ end
414
+
415
+ def create_main_source_file(project, pod_targets, name)
416
+ source_file = project.path.dirname.+("#{name}/main.m")
417
+ source_file.parent.mkpath
418
+
419
+ import_statements = pod_targets.map do |pod_target|
420
+ if pod_target.should_build? && pod_target.defines_module?
421
+ "@import #{pod_target.product_module_name};"
422
+ else
423
+ header_name = "#{pod_target.product_module_name}/#{pod_target.product_module_name}.h"
424
+ "#import <#{header_name}>" if pod_target.sandbox.public_headers.root.+(header_name).file?
425
+ end
426
+ end.compact
427
+
428
+ source_file.open('w') do |f|
429
+ f << import_statements.join("\n")
430
+ f << "\n" unless import_statements.empty?
431
+ f << "int main() { return 0; }\n"
349
432
  end
433
+
434
+ source_file
350
435
  end
351
436
  end
352
437
  end
@@ -14,26 +14,27 @@ 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)
32
+ dir = configuration.gen_dir_for_specs(specs)
33
+ project_name = configuration.project_name_for_specs(specs)
33
34
 
34
35
  Pod::Podfile.new do
35
- project "#{spec.name}.xcodeproj"
36
- workspace "#{spec.name}.xcworkspace"
36
+ project "#{project_name}.xcodeproj"
37
+ workspace "#{project_name}.xcworkspace"
37
38
 
38
39
  plugin 'cocoapods-generate'
39
40
 
@@ -43,7 +44,7 @@ module Pod
43
44
  plugin(*[name, options].compact)
44
45
  end
45
46
 
46
- use_frameworks!(generator.configuration.use_frameworks?)
47
+ use_frameworks!(generator.use_frameworks_value)
47
48
 
48
49
  if (supported_swift_versions = generator.supported_swift_versions)
49
50
  supports_swift_versions(supported_swift_versions)
@@ -56,24 +57,32 @@ module Pod
56
57
 
57
58
  self.defined_in_file = dir.join('CocoaPods.podfile.yaml')
58
59
 
59
- test_specs = spec.recursive_subspecs.select(&:test_specification?)
60
- app_specs = if spec.respond_to?(:app_specification?)
61
- spec.recursive_subspecs.select(&:app_specification?)
62
- else
63
- []
64
- end
60
+ test_specs_by_spec = Hash[specs.map do |spec|
61
+ [spec, spec.recursive_subspecs.select(&:test_specification?)]
62
+ end]
63
+ app_specs_by_spec = Hash[specs.map do |spec|
64
+ app_specs = if spec.respond_to?(:app_specification?)
65
+ spec.recursive_subspecs.select(&:app_specification?)
66
+ else
67
+ []
68
+ end
69
+ [spec, app_specs]
70
+ end]
65
71
 
66
72
  # Stick all of the transitive dependencies in an abstract target.
67
73
  # This allows us to force CocoaPods to use the versions / sources / external sources
68
74
  # that we want.
69
- # By using an abstract target,
70
75
  abstract_target 'Transitive Dependencies' do
71
- pods_for_transitive_dependencies = [spec.name]
72
- .concat(test_specs.map(&:name))
73
- .concat(test_specs.flat_map { |ts| ts.dependencies.flat_map(&:name) })
74
- .concat(app_specs.map(&:name))
75
- .concat(app_specs.flat_map { |as| as.dependencies.flat_map(&:name) })
76
+ pods_for_transitive_dependencies = specs.flat_map do |spec|
77
+ [spec.name]
78
+ .concat(test_specs_by_spec.keys.map(&:name))
79
+ .concat(test_specs_by_spec.values.flatten.flat_map { |ts| ts.dependencies.flat_map(&:name) })
80
+ .concat(app_specs_by_spec.keys.map(&:name))
81
+ .concat(app_specs_by_spec.values.flatten.flat_map { |as| as.dependencies.flat_map(&:name) })
82
+ end
83
+ pods_for_transitive_dependencies.uniq!
76
84
 
85
+ spec_names = specs.map { |s| s.root.name }.to_set
77
86
  dependencies = generator
78
87
  .transitive_dependencies_by_pod
79
88
  .values_at(*pods_for_transitive_dependencies)
@@ -81,7 +90,7 @@ module Pod
81
90
  .flatten(1)
82
91
  .uniq
83
92
  .sort_by(&:name)
84
- .reject { |d| d.root_name == spec.root.name }
93
+ .reject { |d| spec_names.include?(d.root_name) }
85
94
 
86
95
  dependencies.each do |dependency|
87
96
  pod_args = generator.pod_args_for_dependency(self, dependency)
@@ -89,9 +98,8 @@ module Pod
89
98
  end
90
99
  end
91
100
 
92
- # Add platform-specific concrete targets that inherit the
93
- # `pod` declaration for the local pod.
94
- spec_platform_names = spec.available_platforms.map(&:string_name).flatten.each.reject do |platform_name|
101
+ # Add platform-specific concrete targets that inherit the `pod` declaration for the local pod.
102
+ spec_platform_names = specs.flat_map { |s| s.available_platforms.map(&:string_name) }.uniq.each.reject do |platform_name|
95
103
  !generator.configuration.platforms.nil? && !generator.configuration.platforms.include?(platform_name.downcase)
96
104
  end
97
105
 
@@ -116,50 +124,59 @@ module Pod
116
124
  inhibit_all_warnings! if generator.inhibit_all_warnings?
117
125
  use_modular_headers! if generator.use_modular_headers?
118
126
 
119
- # This is the pod declaration for the local pod,
120
- # it will be inherited by the concrete target definitions below
121
- pod_options = generator.dependency_compilation_kwargs(spec.name)
122
- pod_options[:path] = spec.defined_in_file.relative_path_from(dir).to_s
123
- { testspecs: test_specs, appspecs: app_specs }.each do |key, specs|
124
- pod_options[key] = specs.map { |s| s.name.sub(%r{^#{Regexp.escape spec.root.name}/}, '') }.sort unless specs.empty?
125
- end
127
+ specs.each do |spec|
128
+ # This is the pod declaration for the local pod,
129
+ # it will be inherited by the concrete target definitions below
130
+ pod_options = generator.dependency_compilation_kwargs(spec.name)
126
131
 
127
- pod spec.name, **pod_options
132
+ path = spec.defined_in_file.relative_path_from(dir).to_s
133
+ pod_options[:path] = path
134
+ { testspecs: test_specs_by_spec[spec], appspecs: app_specs_by_spec[spec] }.each do |key, subspecs|
135
+ pod_options[key] = subspecs.map { |s| s.name.sub(%r{^#{Regexp.escape spec.root.name}/}, '') }.sort unless subspecs.blank?
136
+ end
137
+ pod spec.name, **pod_options
138
+ end
128
139
 
129
140
  # Implement local-sources option to set up dependencies to podspecs in the local filesystem.
130
141
  next if generator.configuration.local_sources.empty?
131
- generator.transitive_local_dependencies(spec, generator.configuration.local_sources).each do |dependency, podspec_file|
132
- pod_options = generator.dependency_compilation_kwargs(dependency.name)
133
- pod_options[:path] = if podspec_file[0] == '/' # absolute path
134
- podspec_file
135
- else
136
- '../../' + podspec_file
137
- end
138
- pod dependency.name, **pod_options
142
+ specs.each do |spec|
143
+ generator.transitive_local_dependencies(spec, generator.configuration.local_sources).sort_by(&:first).each do |dependency, podspec_file|
144
+ pod_options = generator.dependency_compilation_kwargs(dependency.name)
145
+ pod_options[:path] = if podspec_file[0] == '/' # absolute path
146
+ podspec_file
147
+ else
148
+ '../../' + podspec_file
149
+ end
150
+ pod dependency.name, **pod_options
151
+ end
139
152
  end
140
153
  end
141
154
  end
142
155
 
143
- def transitive_local_dependencies(spec, paths)
144
- dependencies = spec.dependencies
145
- return_list = []
146
- dependencies.each do |dependency|
156
+ def transitive_local_dependencies(spec, paths, found_podspecs: {}, include_non_library_subspecs: true)
157
+ if include_non_library_subspecs
158
+ non_library_specs = spec.recursive_subspecs.select do |ss|
159
+ ss.test_specification? || (ss.respond_to?(:app_specification?) && ss.app_specification?)
160
+ end
161
+ non_library_specs.each do |subspec|
162
+ transitive_local_dependencies(subspec, paths, found_podspecs: found_podspecs, include_non_library_subspecs: false)
163
+ end
164
+ end
165
+ spec.dependencies.each do |dependency|
166
+ next if found_podspecs.key?(dependency)
147
167
  found_podspec_file = nil
148
168
  name = dependency.name.split('/')[0]
149
169
  paths.each do |path|
150
- podspec_file = path + '/' + name + '.podspec'
170
+ podspec_file = File.join(path, name + '.podspec')
151
171
  next unless File.file?(podspec_file)
152
172
  found_podspec_file = podspec_file
153
173
  break
154
174
  end
155
175
  next unless found_podspec_file
156
- return_list << [dependency, found_podspec_file]
157
- dep_spec = Pod::Specification.from_file(found_podspec_file)
158
- dep_spec.dependencies.each do |d_dep|
159
- dependencies << d_dep unless dependencies.include? d_dep
160
- end
176
+ found_podspecs[dependency] = found_podspec_file.sub(%r{\A\./}, '')
177
+ transitive_local_dependencies(Pod::Specification.from_file(found_podspec_file), paths, found_podspecs: found_podspecs)
161
178
  end
162
- return_list
179
+ found_podspecs
163
180
  end
164
181
 
165
182
  # @return [Boolean]
@@ -189,6 +206,27 @@ module Pod
189
206
  end
190
207
  end
191
208
 
209
+ # @return [Boolean, Hash]
210
+ # the value to use for `use_frameworks!` DSL directive
211
+ #
212
+ def use_frameworks_value
213
+ return configuration.use_frameworks? unless configuration.use_podfile?
214
+ use_framework_values = target_definition_list.map do |target_definition|
215
+ if target_definition.respond_to?(:build_type) # CocoaPods >= 1.9
216
+ build_type = target_definition.build_type
217
+ if build_type.static_library?
218
+ false
219
+ else
220
+ { linkage: build_type == BuildType.dynamic_framework ? :dynamic : :static }
221
+ end
222
+ else
223
+ target_definition.uses_frameworks?
224
+ end
225
+ end.uniq
226
+ raise Informative, 'Multiple use_frameworks! values detected in user Podfile.' unless use_framework_values.count == 1
227
+ use_framework_values.first
228
+ end
229
+
192
230
  # @return [Hash]
193
231
  # a hash with "compilation"-related dependency options for the `pod` DSL method
194
232
  #
@@ -299,7 +337,7 @@ module Pod
299
337
  def installation_options
300
338
  installation_options = {
301
339
  deterministic_uuids: configuration.deterministic_uuids?,
302
- share_schemes_for_development_pods: configuration.share_schemes_for_development_pods?,
340
+ share_schemes_for_development_pods: configuration.share_schemes_for_development_pods,
303
341
  warn_for_multiple_pod_sources: configuration.warn_for_multiple_pod_sources?
304
342
  }
305
343
 
@@ -311,6 +349,10 @@ module Pod
311
349
  installation_options[:incremental_installation] = configuration.incremental_installation?
312
350
  end
313
351
 
352
+ if Pod::Installer::InstallationOptions.all_options.include?('disable_input_output_paths')
353
+ installation_options[:disable_input_output_paths] = configuration.disable_input_output_paths
354
+ end
355
+
314
356
  installation_options
315
357
  end
316
358
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if Pod::VERSION >= '1.5.0'
3
+ if Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.5.0')
4
4
  require 'cocoapods/command/gen'
5
5
  else
6
6
  Pod::UI.warn 'cocoapods-generate requires CocoaPods >= 1.5.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocoapods-generate
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Giddins
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-09-03 00:00:00.000000000 Z
11
+ date: 2021-01-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cocoapods-disable-podfile-validations
@@ -86,7 +86,7 @@ homepage: https://github.com/square/cocoapods-generate
86
86
  licenses:
87
87
  - MIT
88
88
  metadata: {}
89
- post_install_message:
89
+ post_install_message:
90
90
  rdoc_options: []
91
91
  require_paths:
92
92
  - lib
@@ -101,8 +101,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
101
  - !ruby/object:Gem::Version
102
102
  version: '0'
103
103
  requirements: []
104
- rubygems_version: 3.0.4
105
- signing_key:
104
+ rubygems_version: 3.1.3
105
+ signing_key:
106
106
  specification_version: 4
107
107
  summary: Generates Xcode workspaces from a podspec.
108
108
  test_files: []