cocoapods-generate 1.5.0 → 2.1.1

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