cocoapods-generate 1.5.0 → 2.1.1

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: 52f85405e2e27e0c197fac736a0f1c3d61f47e601238737f6082aa6913512c7c
4
- data.tar.gz: 2fe15ee1fd79bd155bf94140fbe0a7bfbd2f318d355c43bac59b743e42da738e
3
+ metadata.gz: 6a8a9087ec80789ce819fb41abc24a050e4519320fd2423f6ee2467bc59d7bb1
4
+ data.tar.gz: e461543cdb4cea9b93bca67fe27fe9cac78488ba582a8f045cb010e7bd6b29a2
5
5
  SHA512:
6
- metadata.gz: db80754352a3a07467f11099713f58788fd1a342e54c7fd75e975b3bd73f3230980c07f271de56102a696d3e6663b29a1a21ed4efc38f8ca2bc7a5a62c06f600
7
- data.tar.gz: 64c521033f329de4ad9d232ce147b33d25b885c70a020175e27e65c3ce639144d2cd27c6f864a08381b0b0d05b25488693b345b62ac641ad1a88483e70eb2fe3
6
+ metadata.gz: 00d45b22642ad325b63ed94dbdd853c319ea591950129a5885b178f4fa64bc1fd3bdba7fa6102ac1ad9a5970a288563095bbd1dfac153d913dd889531e7cc81c
7
+ data.tar.gz: b0fb113e1514f18d62bcfce34242d6ae0c91279f97a185977433cee5f7081c853f2d2221460532f4f435cb17523e4570a0f0eb79cd4031ab77881590aeb1bb4f
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
@@ -79,12 +80,18 @@ Options:
79
80
  --local-sources=SOURCE1,SOURCE2 Paths from which to find local podspecs for
80
81
  transitive dependencies. Multiple
81
82
  local-sources must be comma-delimited.
83
+ --platforms=ios,macos Limit to specific platforms. Default is all
84
+ platforms supported by the podspec.
85
+ Multiple platforms must be comma-delimited.
82
86
  --repo-update Force running `pod repo update` before
83
87
  install
84
88
  --use-default-plugins Whether installation should activate
85
89
  default plugins
86
90
  --deterministic-uuids Whether installation should use
87
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)
88
95
  --share-schemes-for-development-pods Whether installation should share schemes
89
96
  for development pods
90
97
  --warn-for-multiple-pod-sources Whether installation should warn when a pod
@@ -94,6 +101,8 @@ Options:
94
101
  modules, as if `use_modular_headers!` were
95
102
  specified. Will error if both this option
96
103
  and a podfile are specified
104
+ --single-workspace Whether to produce a single workspace for
105
+ all podspecs specified.
97
106
  ```
98
107
  <!-- end cli usage -->
99
108
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.5.0
1
+ 2.1.1
@@ -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) }
@@ -169,7 +169,7 @@ module Pod
169
169
  ->(paths) { ('paths do not exist' unless paths.all? { |p| p.is_a?(URI) || p.exist? }) },
170
170
  ->(paths) { paths && paths.map { |path| path.to_s =~ %r{https?://} ? URI(path) : Pathname(path).expand_path } }
171
171
  option :podspecs, ArrayOf.new(Pod::Specification),
172
- 'self.class.podspecs_from_paths(podspec_paths)',
172
+ 'self.class.podspecs_from_paths(podspec_paths, gen_directory)',
173
173
  nil,
174
174
  nil,
175
175
  ->(specs) { 'no podspecs found' if specs.empty? },
@@ -188,12 +188,23 @@ module Pod
188
188
  'SOURCE1,SOURCE2',
189
189
  ->(_) { nil },
190
190
  ->(local_sources) { Array(local_sources).flat_map { |s| s.split(',') } }
191
+ option :platforms, ArrayOf.new(String),
192
+ nil,
193
+ 'Limit to specific platforms. Default is all platforms supported by the podspec. Multiple platforms must be comma-delimited.',
194
+ 'ios,macos',
195
+ lambda { |platforms|
196
+ valid_platforms = Platform.all.map { |p| p.string_name.downcase }
197
+ valid_platforms unless (platforms - valid_platforms).empty?
198
+ }, # validates platforms is a subset of Platform.all
199
+ ->(platforms) { Array(platforms).flat_map { |s| s.split(',') } }
191
200
  option :repo_update, BOOLEAN, 'false', 'Force running `pod repo update` before install', nil, nil, coerce_to_bool
192
201
  option :use_default_plugins, BOOLEAN, 'false', 'Whether installation should activate default plugins', nil, nil, coerce_to_bool
193
- option :deterministic_uuids, BOOLEAN, 'false', 'Whether installation should use deterministic UUIDs for pods projects', nil, nil, coerce_to_bool
194
- option :share_schemes_for_development_pods, BOOLEAN, 'true', 'Whether installation should share schemes for development pods', nil, nil, coerce_to_bool
195
- 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
202
+ 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
203
+ 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
204
+ 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
205
+ 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
196
206
  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
207
+ option :single_workspace, BOOLEAN, 'false', 'Whether to produce a single workspace for all podspecs specified.', nil, nil, coerce_to_bool
197
208
 
198
209
  options.freeze
199
210
  options.each do |o|
@@ -293,12 +304,13 @@ module Pod
293
304
  end << ' }'
294
305
  end
295
306
 
296
- # @return [Pathname] the directory for installation of the generated workspace
307
+ # @return [Pathname] the directory for installation of the generated workspace.
297
308
  #
298
- # @param [String] name the name of the pod
309
+ # @param [Array<Specification>] specs The specs to get a directory name for.
299
310
  #
300
- def gen_dir_for_pod(name)
301
- gen_directory.join(name)
311
+ def gen_dir_for_specs(specs)
312
+ basename = specs.count == 1 ? specs.first.name : 'Workspace'
313
+ gen_directory.join(basename)
302
314
  end
303
315
 
304
316
  # @return [Boolean] whether gen should install with dynamic frameworks
@@ -307,13 +319,29 @@ module Pod
307
319
  !use_libraries?
308
320
  end
309
321
 
322
+ # @return [String] The project name to use for generating this workspace.
323
+ #
324
+ # @param [Array<Specification>] specs
325
+ # the specifications to generate project name for.
326
+ #
327
+ def project_name_for_specs(specs)
328
+ project_name = specs.count == 1 ? +specs.first.name.dup : +'Workspace'
329
+ # When using multiple Xcode project the project name will collide with the actual .xcodeproj meant for the pod
330
+ # that we are generating the workspace for.
331
+ project_name << 'Sample' if generate_multiple_pod_projects? && specs.count == 1
332
+ project_name
333
+ end
334
+
310
335
  # @return [Array<Specification>] the podspecs found at the given paths.
311
336
  # This method will download specs from URLs and traverse a directory's children.
312
337
  #
313
338
  # @param [Array<Pathname,URI>] paths
314
339
  # the paths to search for podspecs
315
340
  #
316
- def self.podspecs_from_paths(paths)
341
+ # @param [Pathname] gen_directory
342
+ # the directory that the gen installation would occur into.
343
+ #
344
+ def self.podspecs_from_paths(paths, gen_directory)
317
345
  paths = [Pathname('.')] if paths.empty?
318
346
  paths.flat_map do |path|
319
347
  if path.is_a?(URI)
@@ -329,9 +357,9 @@ module Pod
329
357
  $ERROR_INFO
330
358
  end
331
359
  elsif path.directory?
332
- glob = Pathname.glob(path + '*.podspec{.json,}')
360
+ glob = Pathname.glob(path.expand_path + '**/*.podspec{.json,}').select { |f| f.relative_path_from(gen_directory).to_s.start_with?('..') }
333
361
  next StandardError.new "no specs found in #{UI.path path}" if glob.empty?
334
- glob.map { |f| Pod::Specification.from_file(f) }
362
+ glob.map { |f| Pod::Specification.from_file(f) }.sort_by(&:name)
335
363
  else
336
364
  Pod::Specification.from_file(path)
337
365
  end
@@ -9,19 +9,19 @@ module Pod
9
9
  #
10
10
  attr_reader :configuration
11
11
 
12
- # @return [Specification]
12
+ # @return [Array<Specification>]
13
13
  # the spec whose workspace is being created
14
14
  #
15
- attr_reader :spec
15
+ attr_reader :specs
16
16
 
17
17
  # @return [Podfile]
18
18
  # the podfile to install
19
19
  #
20
20
  attr_reader :podfile
21
21
 
22
- def initialize(configuration, spec, podfile)
22
+ def initialize(configuration, specs, podfile)
23
23
  @configuration = configuration
24
- @spec = spec
24
+ @specs = specs
25
25
  @podfile = podfile
26
26
  end
27
27
 
@@ -37,7 +37,7 @@ module Pod
37
37
  # @return [void]
38
38
  #
39
39
  def install!
40
- UI.title "Generating #{spec.name} in #{UI.path install_directory}" do
40
+ UI.title "Generating workspace in #{UI.path install_directory}" do
41
41
  clean! if configuration.clean?
42
42
  install_directory.mkpath
43
43
 
@@ -51,7 +51,12 @@ module Pod
51
51
 
52
52
  installer = nil
53
53
  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
54
+ configuration.pod_config.with_changes(installation_root: install_directory, podfile: podfile,
55
+ lockfile: configuration.lockfile, sandbox: nil,
56
+ sandbox_root: install_directory + 'Pods',
57
+ podfile_path: podfile.defined_in_file,
58
+ silent: !configuration.pod_config.verbose?, verbose: false,
59
+ lockfile_path: nil) do
55
60
  installer = ::Pod::Installer.new(configuration.pod_config.sandbox, podfile, configuration.lockfile)
56
61
  installer.use_default_plugins = configuration.use_default_plugins
57
62
  installer.install!
@@ -59,7 +64,12 @@ module Pod
59
64
  end
60
65
 
61
66
  UI.section 'Performing post-installation steps' do
62
- perform_post_install_steps(open_app_project, installer)
67
+ should_perform_post_install = if installer.respond_to?(:generated_aggregate_targets) # CocoaPods 1.7.0
68
+ !installer.generated_aggregate_targets.empty?
69
+ else
70
+ true
71
+ end
72
+ perform_post_install_steps(open_app_project, installer) if should_perform_post_install
63
73
  end
64
74
 
65
75
  print_post_install_message
@@ -79,7 +89,7 @@ module Pod
79
89
  end
80
90
 
81
91
  def open_app_project(recreate: false)
82
- app_project_path = install_directory.join("#{spec.name}.xcodeproj")
92
+ app_project_path = install_directory.join("#{configuration.project_name_for_specs(specs)}.xcodeproj")
83
93
  if !recreate && app_project_path.exist?
84
94
  Xcodeproj::Project.open(app_project_path)
85
95
  else
@@ -92,31 +102,47 @@ module Pod
92
102
  # @return [Xcodeproj::Project]
93
103
  #
94
104
  def create_app_project
95
- app_project = open_app_project(recreate: true)
96
-
97
- spec.available_platforms.map do |platform|
98
- consumer = spec.consumer(platform)
99
- target_name = "App-#{Platform.string_name(consumer.platform_name)}"
100
- native_app_target = Pod::Generator::AppTargetHelper.add_app_target(app_project, consumer.platform_name, deployment_target(consumer), target_name)
101
- # Temporarily set Swift version to pass validator checks for pods which do not specify Swift version.
102
- # It will then be re-set again within #perform_post_install_steps.
103
- Pod::Generator::AppTargetHelper.add_swift_version(native_app_target, Pod::Validator::DEFAULT_SWIFT_VERSION)
104
- native_app_target
105
+ app_project = open_app_project(recreate: !configuration.incremental_installation?)
106
+
107
+ platforms_by_spec = Hash[specs.map do |spec|
108
+ platforms = spec.available_platforms.flatten.reject do |platform|
109
+ !configuration.platforms.nil? && !configuration.platforms.include?(platform.string_name.downcase)
110
+ end
111
+ [spec, platforms]
112
+ end]
113
+
114
+ if platforms_by_spec.values.all?(&:empty?)
115
+ Pod::Command::Gen.help! Pod::StandardError.new "No available platforms for podspecs #{specs.map(&:name).to_sentence} match requested platforms: #{configuration.platforms}"
105
116
  end
106
- .tap do
107
- app_project.recreate_user_schemes do |scheme, target|
108
- installation_result = installation_result_from_target(target)
109
- next unless installation_result
110
- installation_result.test_native_targets.each do |test_native_target|
111
- scheme.add_test_target(test_native_target)
112
- end
113
- end
117
+
118
+ platforms_by_spec
119
+ .flat_map do |spec, platforms|
120
+ platforms.map do |platform|
121
+ consumer = spec.consumer(platform)
122
+ target_name = "App-#{Platform.string_name(consumer.platform_name)}"
123
+ next if app_project.targets.map(&:name).include? target_name
124
+ native_app_target = Pod::Generator::AppTargetHelper.add_app_target(app_project, consumer.platform_name,
125
+ deployment_target(consumer), target_name)
126
+ # Temporarily set Swift version to pass validator checks for pods which do not specify Swift version.
127
+ # It will then be re-set again within #perform_post_install_steps.
128
+ Pod::Generator::AppTargetHelper.add_swift_version(native_app_target, Pod::Validator::DEFAULT_SWIFT_VERSION)
129
+ native_app_target
114
130
  end
115
- .each do |target|
116
- Xcodeproj::XCScheme.share_scheme(app_project.path, target.name)
131
+ end
132
+ .compact.uniq.tap do
133
+ app_project.recreate_user_schemes do |scheme, target|
134
+ installation_result = installation_result_from_target(target)
135
+ next unless installation_result
136
+ installation_result.test_native_targets.each do |test_native_target|
137
+ scheme.add_test_target(test_native_target)
138
+ end
117
139
  end
118
-
140
+ end
141
+ .each do |target|
142
+ Xcodeproj::XCScheme.share_scheme(app_project.path.to_s, target.name) if target
143
+ end
119
144
  app_project.save
145
+ app_project
120
146
  end
121
147
 
122
148
  def deployment_target(consumer)
@@ -132,8 +158,13 @@ module Pod
132
158
  app_project.native_targets.each do |native_app_target|
133
159
  remove_script_phase_from_target(native_app_target, 'Check Pods Manifest.lock')
134
160
 
135
- pod_target = installer.pod_targets.find { |pt| pt.platform.name == native_app_target.platform_name && pt.pod_name == spec.name }
136
- raise "unable to find a pod target for #{native_app_target} / #{spec}" unless pod_target
161
+ spec_names = specs.map(&:name)
162
+ pod_targets = installer.pod_targets.select do |pt|
163
+ pt.platform.name == native_app_target.platform_name && spec_names.include?(pt.pod_name)
164
+ end
165
+
166
+ native_app_target.source_build_phase.clear
167
+ native_app_target.resources_build_phase.clear
137
168
 
138
169
  if (app_host_source_dir = configuration.app_host_source_dir)
139
170
  relative_app_host_source_dir = app_host_source_dir.relative_path_from(installer.sandbox.root)
@@ -166,10 +197,18 @@ module Pod
166
197
  source_file_ref = group.new_file(file.basename)
167
198
  native_app_target.add_file_references([source_file_ref])
168
199
  end
169
- elsif Pod::Generator::AppTargetHelper.method(:add_app_project_import).arity == -5 # CocoaPods >= 1.6
170
- Pod::Generator::AppTargetHelper.add_app_project_import(app_project, native_app_target, pod_target, pod_target.platform.name, native_app_target.name)
171
200
  else
172
- 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)
201
+ platform_name = Platform.string_name(native_app_target.platform_name)
202
+ group = group_for_platform_name(app_project, platform_name)
203
+ main_file_ref = group.files.find { |f| f.display_name == 'main.m' }
204
+ if main_file_ref.nil?
205
+ source_file = create_main_source_file(app_project, pod_targets, native_app_target.name)
206
+ group = app_project[group.name] || app_project.new_group(group.name, group.name)
207
+ source_file_ref = group.new_file(source_file)
208
+ native_app_target.add_file_references([source_file_ref])
209
+ else
210
+ native_app_target.add_file_references([main_file_ref])
211
+ end
173
212
  end
174
213
 
175
214
  # Set `PRODUCT_BUNDLE_IDENTIFIER`
@@ -179,21 +218,25 @@ module Pod
179
218
 
180
219
  case native_app_target.platform_name
181
220
  when :ios
182
- make_ios_app_launchable(installer, app_project, native_app_target)
221
+ make_ios_app_launchable(app_project, native_app_target)
183
222
  end
184
223
 
185
- Pod::Generator::AppTargetHelper.add_swift_version(native_app_target, pod_target.swift_version) unless pod_target.swift_version.blank?
224
+ swift_version = pod_targets.map { |pt| Pod::Version.new(pt.swift_version) }.max.to_s
225
+
226
+ Pod::Generator::AppTargetHelper.add_swift_version(native_app_target, swift_version) unless swift_version.blank?
186
227
  if installer.pod_targets.any? { |pt| pt.spec_consumers.any? { |c| c.frameworks.include?('XCTest') } }
187
228
  Pod::Generator::AppTargetHelper.add_xctest_search_paths(native_app_target)
188
229
  end
189
230
 
190
- # Share the pods xcscheme only if it exists. For pre-built vendored pods there is no xcscheme generated.
191
- if installer.respond_to?(:generated_projects) # CocoaPods 1.7.0
192
- installer.generated_projects.each do |project|
193
- Xcodeproj::XCScheme.share_scheme(project.path, pod_target.label) if File.exist?(project.path + pod_target.label)
231
+ pod_targets.each do |pod_target|
232
+ result = installer.target_installation_results.pod_target_installation_results[pod_target.name]
233
+ share_scheme(result.native_target.project, pod_target.label)
234
+ pod_target.test_specs.each do |test_spec|
235
+ share_scheme(result.native_target.project, pod_target.test_target_label(test_spec))
236
+ end
237
+ pod_target.app_specs.each do |app_spec|
238
+ share_scheme(result.native_target.project, pod_target.app_target_label(app_spec))
194
239
  end
195
- elsif File.exist?(installer.pods_project.path + pod_target.label)
196
- Xcodeproj::XCScheme.share_scheme(installer.pods_project.path, pod_target.label)
197
240
  end
198
241
 
199
242
  add_test_spec_schemes_to_app_scheme(installer, app_project)
@@ -217,25 +260,22 @@ module Pod
217
260
  end
218
261
 
219
262
  def add_test_spec_schemes_to_app_scheme(installer, app_project)
263
+ spec_root_names = Set.new(specs.map { |s| s.root.name })
264
+
220
265
  test_native_targets =
221
- if installer.respond_to?(:target_installation_results) # CocoaPods >= 1.6
222
- installer
223
- .target_installation_results
224
- .pod_target_installation_results
225
- .values
226
- .flatten(1)
227
- .select { |installation_result| installation_result.target.pod_name == spec.root.name }
228
- else
229
- installer
230
- .pod_targets
231
- .select { |pod_target| pod_target.pod_name == spec.root.name }
232
- end
266
+ installer
267
+ .target_installation_results
268
+ .pod_target_installation_results
269
+ .values
270
+ .flatten(1)
271
+ .select { |installation_result| spec_root_names.include?(installation_result.target.pod_name) }
233
272
  .flat_map(&:test_native_targets)
234
273
  .group_by(&:platform_name)
235
274
 
275
+ workspace_path = install_directory + (configuration.project_name_for_specs(specs) + '.xcworkspace')
236
276
  Xcodeproj::Plist.write_to_path(
237
277
  { 'IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded' => false },
238
- app_project.path.sub_ext('.xcworkspace').join('xcshareddata').tap(&:mkpath).join('WorkspaceSettings.xcsettings')
278
+ workspace_path.join('xcshareddata').tap(&:mkpath).join('WorkspaceSettings.xcsettings')
239
279
  )
240
280
 
241
281
  test_native_targets.each do |platform_name, test_targets|
@@ -251,7 +291,7 @@ module Pod
251
291
 
252
292
  testable = Xcodeproj::XCScheme::TestAction::TestableReference.new(target)
253
293
  testable.buildable_references.each do |buildable|
254
- buildable.xml_element.attributes['ReferencedContainer'] = 'container:Pods.xcodeproj'
294
+ buildable.xml_element.attributes['ReferencedContainer'] = "container:Pods/#{File.basename(target.project.path)}"
255
295
  end
256
296
  test_action.add_testable(testable)
257
297
  end
@@ -260,9 +300,9 @@ module Pod
260
300
  end
261
301
  end
262
302
 
263
- def make_ios_app_launchable(installer, app_project, native_app_target)
303
+ def make_ios_app_launchable(app_project, native_app_target)
264
304
  platform_name = Platform.string_name(native_app_target.platform_name)
265
- generated_source_dir = installer.sandbox.root.join('App', platform_name).tap(&:mkpath)
305
+ generated_source_dir = install_directory.join("App-#{platform_name}").tap(&:mkpath)
266
306
 
267
307
  # Add `LaunchScreen.storyboard`
268
308
  launch_storyboard = generated_source_dir.join('LaunchScreen.storyboard')
@@ -323,12 +363,17 @@ module Pod
323
363
  Xcodeproj::Plist.write_to_path(info_plist_contents, info_plist_path)
324
364
 
325
365
  native_app_target.build_configurations.each do |bc|
326
- bc.build_settings['INFOPLIST_FILE'] = "${SRCROOT}/App/#{platform_name}/Info.plist"
366
+ bc.build_settings['INFOPLIST_FILE'] = "${SRCROOT}/App-#{platform_name}/Info.plist"
327
367
  end
328
368
 
329
- group = app_project.main_group.find_subpath("App-#{platform_name}", true)
330
- group.new_file(info_plist_path)
331
- native_app_target.resources_build_phase.add_file_reference group.new_file(launch_storyboard)
369
+ group = group_for_platform_name(app_project, platform_name)
370
+ group.files.find { |f| f.display_name == 'Info.plist' } || group.new_file(info_plist_path)
371
+ launch_storyboard_file_ref = group.files.find { |f| f.display_name == 'LaunchScreen.storyboard' } || group.new_file(launch_storyboard)
372
+ native_app_target.resources_build_phase.add_file_reference(launch_storyboard_file_ref)
373
+ end
374
+
375
+ def group_for_platform_name(project, platform_name, should_create = true)
376
+ project.main_group.find_subpath("App-#{platform_name}", should_create)
332
377
  end
333
378
 
334
379
  def print_post_install_message
@@ -339,8 +384,36 @@ module Pod
339
384
  Executable.execute_command 'open', [workspace_path]
340
385
  end
341
386
  else
342
- UI.info "Open #{UI.path workspace_path} to work on #{spec.name}"
387
+ UI.info "Open #{UI.path workspace_path} to work on it!"
388
+ end
389
+ end
390
+
391
+ def share_scheme(project, scheme_name)
392
+ scheme = Xcodeproj::XCScheme.user_data_dir(project.path) + "#{scheme_name}.xcscheme"
393
+ return unless File.exist?(scheme)
394
+ Xcodeproj::XCScheme.share_scheme(project.path, scheme_name)
395
+ end
396
+
397
+ def create_main_source_file(project, pod_targets, name)
398
+ source_file = project.path.dirname.+("#{name}/main.m")
399
+ source_file.parent.mkpath
400
+
401
+ import_statements = pod_targets.map do |pod_target|
402
+ if pod_target.should_build? && pod_target.defines_module?
403
+ "@import #{pod_target.product_module_name};"
404
+ else
405
+ header_name = "#{pod_target.product_module_name}/#{pod_target.product_module_name}.h"
406
+ "#import <#{header_name}>" if pod_target.sandbox.public_headers.root.+(header_name).file?
407
+ end
408
+ end.compact
409
+
410
+ source_file.open('w') do |f|
411
+ f << import_statements.join("\n")
412
+ f << "\n" unless import_statements.empty?
413
+ f << "int main() { return 0; }\n"
343
414
  end
415
+
416
+ source_file
344
417
  end
345
418
  end
346
419
  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,12 @@ 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.available_platforms.map(&:string_name).sort.each 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|
103
+ !generator.configuration.platforms.nil? && !generator.configuration.platforms.include?(platform_name.downcase)
104
+ end
105
+
106
+ spec_platform_names.sort.each do |platform_name|
95
107
  target "App-#{platform_name}" do
96
108
  current_target_definition.swift_version = generator.swift_version if generator.swift_version
97
109
  end
@@ -112,50 +124,59 @@ module Pod
112
124
  inhibit_all_warnings! if generator.inhibit_all_warnings?
113
125
  use_modular_headers! if generator.use_modular_headers?
114
126
 
115
- # This is the pod declaration for the local pod,
116
- # it will be inherited by the concrete target definitions below
117
- pod_options = generator.dependency_compilation_kwargs(spec.name)
118
- pod_options[:path] = spec.defined_in_file.relative_path_from(dir).to_s
119
- { testspecs: test_specs, appspecs: app_specs }.each do |key, specs|
120
- pod_options[key] = specs.map { |s| s.name.sub(%r{^#{Regexp.escape spec.root.name}/}, '') }.sort unless specs.empty?
121
- 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)
122
131
 
123
- 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
124
139
 
125
140
  # Implement local-sources option to set up dependencies to podspecs in the local filesystem.
126
141
  next if generator.configuration.local_sources.empty?
127
- generator.transitive_local_dependencies(spec, generator.configuration.local_sources).each do |dependency, podspec_file|
128
- pod_options = generator.dependency_compilation_kwargs(dependency.name)
129
- pod_options[:path] = if podspec_file[0] == '/' # absolute path
130
- podspec_file
131
- else
132
- '../../' + podspec_file
133
- end
134
- 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
135
152
  end
136
153
  end
137
154
  end
138
155
 
139
- def transitive_local_dependencies(spec, paths)
140
- dependencies = spec.dependencies
141
- return_list = []
142
- 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)
143
167
  found_podspec_file = nil
144
168
  name = dependency.name.split('/')[0]
145
169
  paths.each do |path|
146
- podspec_file = path + '/' + name + '.podspec'
170
+ podspec_file = File.join(path, name + '.podspec')
147
171
  next unless File.file?(podspec_file)
148
172
  found_podspec_file = podspec_file
149
173
  break
150
174
  end
151
175
  next unless found_podspec_file
152
- return_list << [dependency, found_podspec_file]
153
- dep_spec = Pod::Specification.from_file(found_podspec_file)
154
- dep_spec.dependencies.each do |d_dep|
155
- dependencies << d_dep unless dependencies.include? d_dep
156
- 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)
157
178
  end
158
- return_list
179
+ found_podspecs
159
180
  end
160
181
 
161
182
  # @return [Boolean]
@@ -185,6 +206,27 @@ module Pod
185
206
  end
186
207
  end
187
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
+
188
230
  # @return [Hash]
189
231
  # a hash with "compilation"-related dependency options for the `pod` DSL method
190
232
  #
@@ -295,7 +337,7 @@ module Pod
295
337
  def installation_options
296
338
  installation_options = {
297
339
  deterministic_uuids: configuration.deterministic_uuids?,
298
- share_schemes_for_development_pods: configuration.share_schemes_for_development_pods?,
340
+ share_schemes_for_development_pods: configuration.share_schemes_for_development_pods,
299
341
  warn_for_multiple_pod_sources: configuration.warn_for_multiple_pod_sources?
300
342
  }
301
343
 
@@ -307,6 +349,10 @@ module Pod
307
349
  installation_options[:incremental_installation] = configuration.incremental_installation?
308
350
  end
309
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
+
310
356
  installation_options
311
357
  end
312
358
 
@@ -349,6 +395,7 @@ module Pod
349
395
  #
350
396
  def modular_headers?(pod_name)
351
397
  return true if configuration.use_modular_headers?
398
+ return false unless configuration.use_podfile?
352
399
  target_definitions_for_pod(pod_name).all? do |target_definition|
353
400
  target_definition.build_pod_as_module?(pod_name)
354
401
  end
@@ -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.5.0
4
+ version: 2.1.1
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-05-15 00:00:00.000000000 Z
11
+ date: 2021-01-04 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.1
105
- signing_key:
104
+ rubygems_version: 3.0.3
105
+ signing_key:
106
106
  specification_version: 4
107
107
  summary: Generates Xcode workspaces from a podspec.
108
108
  test_files: []