cocoapods-generate 1.6.0 → 2.2.0

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: 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: []