pod-builder 0.1.8.beta → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,10 @@ module PodBuilder
7
7
 
8
8
  init_git(Configuration.build_path) # this is needed to be able to call safe_rm_rf
9
9
 
10
- File.write("#{Configuration.build_path}/Podfile", podfile_content)
10
+ podfile_path = "#{Configuration.build_path}/Podfile"
11
+ File.write(podfile_path, podfile_content)
12
+ Podfile.update_path_entires(podfile_path, true)
13
+ Podfile.update_project_entries(podfile_path, true)
11
14
 
12
15
  begin
13
16
  lock_file = "#{Configuration.build_path}/pod_builder.lock"
@@ -48,7 +51,7 @@ module PodBuilder
48
51
  def self.framework_rel_path(framework_path, podfile_items)
49
52
  framework_name = File.basename(framework_path)
50
53
  framework_name_no_ext = File.basename(framework_name, File.extname(framework_name))
51
- if podfile_item = podfile_items.detect { |x| x.module_name == framework_name_no_ext }
54
+ if podfile_item = podfile_items.detect { |x| x.module_name == framework_name_no_ext && Configuration.subspecs_to_split.include?(x.name) }
52
55
  return "#{podfile_item.prebuilt_rel_path}"
53
56
  else
54
57
  return framework_name
@@ -2,8 +2,11 @@ require 'pod_builder/cocoapods/analyzer'
2
2
 
3
3
  module PodBuilder
4
4
  class Podfile
5
-
6
- PRE_INSTALL_ACTIONS = ["raise \"\\n🚨 Do not launch 'pod install' manually, use `pod_builder` instead!\\n\" if !File.exist?('pod_builder.lock')"]
5
+ PODBUILDER_LOCK_ACTION = ["raise \"\\n🚨 Do not launch 'pod install' manually, use `pod_builder` instead!\\n\" if !File.exist?('pod_builder.lock')"].freeze
6
+ POST_INSTALL_ACTIONS = ["require 'pod_builder/podfile/post_actions'", "PodBuilder::Podfile::remove_target_support_duplicate_entries", "PodBuilder::Podfile::check_target_support_resource_collisions"].freeze
7
+
8
+ PRE_INSTALL_ACTIONS = ["Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_duplicate_framework_and_library_names) {}"].freeze
9
+ private_constant :PRE_INSTALL_ACTIONS
7
10
 
8
11
  def self.from_podfile_items(items, analyzer)
9
12
  raise "no items" unless items.count > 0
@@ -12,21 +15,36 @@ module PodBuilder
12
15
 
13
16
  cwd = File.dirname(File.expand_path(__FILE__))
14
17
  podfile = File.read("#{cwd}/templates/build_podfile.template")
15
-
18
+
19
+ platform = analyzer.result.targets.first.platform
20
+ podfile.sub!("%%%platform_name%%%", platform.name.to_s)
21
+ podfile.sub!("%%%deployment_version%%%", platform.deployment_target.version)
22
+
16
23
  podfile.sub!("%%%sources%%%", sources.map { |x| "source '#{x.url}'" }.join("\n"))
17
24
 
18
25
  build_configurations = items.map(&:build_configuration).uniq
19
26
  raise "Found different build configurations in #{items}" if build_configurations.count != 1
20
27
  podfile.sub!("%%%build_configuration%%%", build_configurations.first.capitalize)
21
28
 
22
- build_settings = Configuration.build_settings
23
29
  podfile_build_settings = ""
24
30
 
25
31
  pod_dependencies = {}
26
32
 
27
33
  items.each do |item|
34
+ build_settings = Configuration.build_settings.dup
35
+
28
36
  item_build_settings = Configuration.build_settings_overrides[item.name] || {}
37
+
38
+ # These settings need to be set as is to properly build frameworks
39
+ build_settings['SWIFT_COMPILATION_MODE'] = 'singlefile'
40
+ build_settings['CLANG_ENABLE_MODULE_DEBUGGING'] = 'NO'
41
+ build_settings['ONLY_ACTIVE_ARCH'] = 'NO'
42
+
29
43
  build_settings['SWIFT_VERSION'] = item_build_settings["SWIFT_VERSION"] || project_swift_version(analyzer)
44
+ if item.is_static
45
+ # https://forums.developer.apple.com/thread/17921
46
+ build_settings['CLANG_ENABLE_MODULE_DEBUGGING'] = "NO"
47
+ end
30
48
 
31
49
  item_build_settings.each do |k, v|
32
50
  build_settings[k] = v
@@ -38,7 +56,7 @@ module PodBuilder
38
56
  if x.split("/").first == item.root_name
39
57
  next nil # remove dependency to parent spec
40
58
  end
41
- if overridded_module_name = Configuration.spec_overrides[x]["module_name"]
59
+ if overridded_module_name = Configuration.spec_overrides.fetch(x, {})["module_name"]
42
60
  next overridded_module_name
43
61
  end
44
62
  }.compact
@@ -62,105 +80,113 @@ module PodBuilder
62
80
  end
63
81
 
64
82
  def self.write_restorable(updated_pods, podfile_items, analyzer)
83
+ puts "Writing Restore Podfile".yellow
84
+
65
85
  podfile_items = podfile_items.dup
66
86
  podfile_restore_path = PodBuilder::basepath("Podfile.restore")
67
87
  podfile_path = PodBuilder::basepath("Podfile")
68
88
 
69
89
  if File.exist?(podfile_restore_path)
70
- podfile_content = File.read(podfile_restore_path)
71
-
72
90
  restore_podfile_items = podfile_items_at(podfile_restore_path)
73
91
 
74
92
  podfile_items.map! { |podfile_item|
75
93
  if updated_pod = updated_pods.detect { |x| x.name == podfile_item.name } then
76
94
  updated_pod
77
- elsif restored_pod = restore_podfile_items.detect { |x| x.name == podfile_item.name }
95
+ elsif updated_pods.any? { |x| podfile_item.root_name == x.root_name } == false && # podfile_item shouldn't be among those being updated (including root specification)
96
+ restored_pod = restore_podfile_items.detect { |x| x.name == podfile_item.name }
78
97
  restored_pod
79
98
  else
80
99
  podfile_item
81
100
  end
82
101
  }
83
- else
84
- podfile_content = File.read(podfile_path)
85
102
  end
86
-
87
- current_target = nil
88
- destination_lines = []
89
- podfile_content.each_line do |line|
90
- stripped_line = strip_line(line)
91
- if current_target.nil?
92
- destination_lines.push(line)
93
103
 
94
- if current_target = target_definition_in(line, false)
95
- target_pods, target_dependencies = analyzer.pods_and_deps_in_target(current_target, podfile_items)
104
+ result_targets = analyzer.result.targets.map(&:name)
105
+ podfile_content = ["# Autogenerated by PodBuilder (https://github.com/Subito-it/PodBuilder)", "# Please don't modify this file", "\n"]
106
+ podfile_content += analyzer.podfile.sources.map { |x| "source '#{x}'" }
107
+ podfile_content += ["", "use_frameworks!", ""]
96
108
 
97
- # dependecies should be listed first
98
- current_target_pods = (target_dependencies + target_pods).uniq
109
+ # multiple platforms not (yet) supported
110
+ # https://github.com/CocoaPods/Rome/issues/37
111
+ platform = analyzer.result.targets.first.platform
112
+ podfile_content += ["platform :#{platform.name}, '#{platform.deployment_target.version}'", ""]
99
113
 
100
- # There should be at most one subspecs per target
101
- # Taking just one subspec is enough to pin to the correct version
102
- current_target_pods = current_target_pods.sort_by(&:name).uniq(&:root_name)
114
+ analyzer.result.specs_by_target.each do |target, specifications|
115
+ target_name = target.name.to_s
103
116
 
104
- current_target_pods.each { |x| destination_lines.push(" #{x.entry}\n") }
105
- end
106
- else
107
- if stripped_line == "end"
108
- destination_lines.push(line)
109
- current_target = nil
110
- end
117
+ unless result_targets.select { |x| x.end_with?(target_name) }.count > 0
118
+ next
111
119
  end
120
+
121
+ podfile_content.push("target '#{target_name}' do")
122
+
123
+ specifications.each do |spec|
124
+ item = podfile_items.detect { |x| x.name == spec.name }
125
+ podfile_content.push("\t#{item.entry}")
126
+ end
127
+
128
+ podfile_content.push("end\n")
112
129
  end
113
130
 
114
- podfile_content = destination_lines.join
115
- File.write(podfile_restore_path, podfile_content)
131
+ File.write(podfile_restore_path, podfile_content.join("\n"))
116
132
  end
117
133
 
118
- def self.update_prebuilt(updated_pods, podfile_items, analyzer)
119
- project_podfile_path = PodBuilder::xcodepath("Podfile")
134
+ def self.write_prebuilt(all_buildable_items, analyzer)
135
+ puts "Updating Application Podfile".yellow
120
136
 
121
- podfile_content = File.read(project_podfile_path)
137
+ podbuilder_podfile_path = PodBuilder::basepath("Podfile")
138
+ rel_path = Pathname.new(podbuilder_podfile_path).relative_path_from(Pathname.new(PodBuilder::project_path)).to_s
139
+
140
+ frameworks_base_path = PodBuilder::basepath("Rome")
141
+
142
+ podfile_content = File.read(podbuilder_podfile_path)
122
143
 
123
- stripped_prebuilt_entries = (updated_pods + podfile_items).map(&:prebuilt_entry).map { |x| strip_line(x) }
124
- podfile_items_name = podfile_items.map(&:name)
144
+ exclude_lines = Podfile::PODBUILDER_LOCK_ACTION.map { |x| Podfile.strip_line(x) }
125
145
 
126
- destination_lines = []
146
+ prebuilt_lines = ["# Autogenerated by PodBuilder (https://github.com/Subito-it/PodBuilder)\n", "# Any change to this file should be done on #{rel_path}\n", "\n"]
127
147
  podfile_content.each_line do |line|
128
148
  stripped_line = strip_line(line)
129
149
 
130
150
  if pod_name = pod_definition_in(line, true)
131
- if updated_pod = updated_pods.detect { |x| x.name == pod_name }
132
- destination_lines.push(" #{updated_pod.prebuilt_entry}\n")
133
- destination_lines.push(" # #{updated_pod.entry(false)}\n")
134
- next
135
- elsif !podfile_items_name.include?(pod_name) && !stripped_prebuilt_entries.include?(stripped_line)
136
- next
151
+ if podfile_item = all_buildable_items.detect { |x| x.name == pod_name }
152
+ if File.exist?("#{frameworks_base_path}/#{podfile_item.prebuilt_rel_path}")
153
+ line = "#{line.detect_indentation}#{podfile_item.prebuilt_entry}\n"
154
+ end
137
155
  end
138
156
  end
139
157
 
140
- destination_lines.push(line)
158
+ if !exclude_lines.include?(stripped_line)
159
+ prebuilt_lines.push(line)
160
+ end
141
161
  end
142
162
 
143
- # remove adiacent duplicated entries
144
- destination_lines = destination_lines.chunk { |x| x }.map(&:first)
163
+ project_podfile_path = PodBuilder::project_path("Podfile")
164
+ File.write(project_podfile_path, prebuilt_lines.join)
165
+ Podfile.update_path_entires(project_podfile_path, false)
166
+ Podfile.update_project_entries(project_podfile_path, false)
145
167
 
146
- podfile_content = destination_lines.join
147
- File.write(project_podfile_path, podfile_content)
168
+ add_pre_install_actions(project_podfile_path)
169
+ add_post_install_checks(project_podfile_path)
148
170
  end
149
171
 
150
172
  def self.deintegrate_install
173
+ puts "Running pod install".yellow
174
+
151
175
  current_dir = Dir.pwd
152
176
 
153
- Dir.chdir(PodBuilder::xcodepath)
154
- system("pod deintegrate; pod install;")
177
+ Dir.chdir(PodBuilder::project_path)
178
+ system("pod install;")
155
179
  Dir.chdir(current_dir)
156
180
  end
157
181
 
158
182
  def self.strip_line(line)
159
- stripped_line = line.dup
160
- return stripped_line.gsub("\"", "'").gsub(" ", "").gsub("\n", "")
183
+ stripped_line = line.strip
184
+ return stripped_line.gsub("\"", "'").gsub(" ", "").gsub("\t", "").gsub("\n", "")
161
185
  end
162
186
 
163
- private
187
+ def self.add_install_block(podfile_path)
188
+ add(PODBUILDER_LOCK_ACTION, "pre_install", podfile_path)
189
+ end
164
190
 
165
191
  def self.pod_definition_in(line, include_commented)
166
192
  stripped_line = strip_line(line)
@@ -173,19 +199,30 @@ module PodBuilder
173
199
  end
174
200
  end
175
201
 
176
- def self.target_definition_in(line, include_commented)
177
- stripped_line = strip_line(line)
178
- matches = stripped_line.match(/(^target')(.*?)(')/)
179
-
180
- if matches&.size == 4 && (include_commented || !stripped_line.start_with?("#"))
181
- return matches[2]
182
- else
183
- return nil
202
+ private
203
+
204
+ def self.indentation_from_file(path)
205
+ content = File.read(path)
206
+
207
+ lines = content.split("\n").select { |x| !x.empty? }
208
+
209
+ if lines.count > 2
210
+ lines[0..-2].each_with_index do |current_line, index|
211
+ next_line = lines[index + 1]
212
+ next_line_first_char = next_line.chars.first
213
+ current_doesnt_begin_with_whitespace = current_line[/\A\S*/] != nil
214
+
215
+ if current_doesnt_begin_with_whitespace && [" ", "\t"].include?(next_line_first_char)
216
+ return next_line[/\A\s*/]
217
+ end
218
+ end
184
219
  end
220
+
221
+ return " "
185
222
  end
186
223
 
187
224
  def self.project_swift_version(analyzer)
188
- swift_versions = analyzer.result.target_inspections.values.map { |x| x.target_definition.swift_version }.uniq
225
+ swift_versions = analyzer.result.target_inspections.values.map { |x| x.target_definition.swift_version }.compact.uniq
189
226
 
190
227
  raise "Found different Swift versions in targets. Expecting one, got `#{swift_versions}`" if swift_versions.count != 1
191
228
 
@@ -208,7 +245,7 @@ module PodBuilder
208
245
  installer, analyzer = Analyze.installer_at(PodBuilder::basepath)
209
246
 
210
247
  podfile_items = Analyze.podfile_items(installer, analyzer)
211
- buildable_items = podfile_items.select { |item| item.is_prebuilt == false }
248
+ buildable_items = podfile_items.select { |item| !item.is_prebuilt }
212
249
  rescue Exception => e
213
250
  raise e
214
251
  ensure
@@ -221,5 +258,106 @@ module PodBuilder
221
258
 
222
259
  return buildable_items
223
260
  end
261
+
262
+ def self.add_pre_install_actions(podfile_path)
263
+ add(PRE_INSTALL_ACTIONS + [" "], "pre_install", podfile_path)
264
+ end
265
+
266
+ def self.add_post_install_checks(podfile_path)
267
+ add(POST_INSTALL_ACTIONS + [" "], "post_install", podfile_path)
268
+ end
269
+
270
+ def self.add(entries, marker, podfile_path)
271
+ podfile_content = File.read(podfile_path)
272
+
273
+ file_indentation = indentation_from_file(podfile_path)
274
+
275
+ entries = entries.map { |x| "#{file_indentation}#{x}\n"}
276
+
277
+ marker_found = false
278
+ podfile_lines = []
279
+ podfile_content.each_line do |line|
280
+ stripped_line = Podfile::strip_line(line)
281
+
282
+ podfile_lines.push(line)
283
+ if stripped_line.start_with?("#{marker}do|")
284
+ marker_found = true
285
+ podfile_lines.push(entries)
286
+ end
287
+ end
288
+
289
+ if !marker_found
290
+ podfile_lines.push("\n#{marker} do |installer|\n")
291
+ podfile_lines.push(entries)
292
+ podfile_lines.push("end\n")
293
+ end
294
+
295
+ File.write(podfile_path, podfile_lines.join)
296
+ end
297
+
298
+ def self.update_path_entires(podfile_path, use_absolute_paths = false, path_base = PodBuilder::basepath(""))
299
+ podfile_content = File.read(podfile_path)
300
+
301
+ base_path = Pathname.new(File.dirname(podfile_path))
302
+ regex = "(\s*pod\s*['|\"])(.*?)(['|\"])(.*?)(:path\s*=>\s*['|\"])(.*?)(['|\"])"
303
+
304
+ podfile_lines = []
305
+ podfile_content.each_line do |line|
306
+ stripped_line = strip_line(line)
307
+ matches = line.match(/#{regex}/)
308
+
309
+ if matches&.size == 8 && !stripped_line.start_with?("#")
310
+ pod_name = matches[2]
311
+ path = matches[6]
312
+ unless !pod_name.start_with?("PodBuilder/")
313
+ podfile_lines.push(line)
314
+ next
315
+ end
316
+
317
+ original_path = Pathname.new(File.join(path_base, path))
318
+ replace_path = original_path.relative_path_from(base_path)
319
+ if use_absolute_paths
320
+ replace_path = replace_path.expand_path(base_path)
321
+ end
322
+
323
+ updated_path_line = line.gsub(/#{regex}/, '\1\2\3\4\5' + replace_path.to_s + '\7\8')
324
+ podfile_lines.push(updated_path_line)
325
+ else
326
+ podfile_lines.push(line)
327
+ end
328
+ end
329
+
330
+ File.write(podfile_path, podfile_lines.join)
331
+ end
332
+
333
+ def self.update_project_entries(podfile_path, use_absolute_paths = false, path_base = PodBuilder::basepath(""))
334
+ podfile_content = File.read(podfile_path)
335
+
336
+ base_path = Pathname.new(File.dirname(podfile_path))
337
+ regex = "(\s*project\s*['|\"])(.*?)(['|\"])"
338
+
339
+ podfile_lines = []
340
+ podfile_content.each_line do |line|
341
+ stripped_line = strip_line(line)
342
+ matches = line.match(/#{regex}/)
343
+
344
+ if matches&.size == 4 && !stripped_line.start_with?("#")
345
+ path = matches[2]
346
+
347
+ original_path = Pathname.new(File.join(path_base, path))
348
+ replace_path = original_path.relative_path_from(base_path)
349
+ if use_absolute_paths
350
+ replace_path = replace_path.expand_path(base_path)
351
+ end
352
+
353
+ updated_path_line = line.gsub(/#{regex}/, '\1' + replace_path.to_s + '\3\4')
354
+ podfile_lines.push(updated_path_line)
355
+ else
356
+ podfile_lines.push(line)
357
+ end
358
+ end
359
+
360
+ File.write(podfile_path, podfile_lines.join)
361
+ end
224
362
  end
225
363
  end
@@ -128,12 +128,8 @@ module PodBuilder
128
128
  end
129
129
  end
130
130
 
131
- def self.find_xcodeproj_targets
132
- xcodeprojects = Dir.glob("#{PodBuilder::home}/**/*.xcodeproj").select { |x| !x.include?("/Pods/") && !x.include?(PodBuilder::basepath) }
133
- raise "xcdeoproj not found!".red if xcodeprojects.count == 0
134
- raise "Found multiple xcdeoprojs:\n#{xcodeprojects.join("\n")}".red if xcodeprojects.count > 1
135
-
136
- project = Xcodeproj::Project.open(xcodeprojects.first)
131
+ def self.find_xcodeproj_targets
132
+ project = Xcodeproj::Project.open(PodBuilder::find_xcodeproj)
137
133
 
138
134
  return project.targets
139
135
  end
@@ -28,7 +28,7 @@ module PodBuilder
28
28
 
29
29
  # @return [String] Local path, if any
30
30
  #
31
- attr_reader :path
31
+ attr_accessor :path
32
32
 
33
33
  # @return [String] The pinned commit of the pod, if any
34
34
  #
@@ -62,6 +62,26 @@ module PodBuilder
62
62
  #
63
63
  attr_accessor :build_configuration
64
64
 
65
+ # @return [String] The pod's vendored items (frameworks and libraries)
66
+ #
67
+ attr_accessor :vendored_items
68
+
69
+ # @return [String] Framweworks the pod needs to link to
70
+ #
71
+ attr_accessor :frameworks
72
+
73
+ # @return [String] Weak framweworks the pod needs to link to
74
+ #
75
+ attr_accessor :weak_frameworks
76
+
77
+ # @return [String] Libraries the pod needs to link to
78
+ #
79
+ attr_accessor :libraries
80
+
81
+ # @return [Bool] Returns true if the source_files key is present
82
+ #
83
+ attr_accessor :has_source_files_key
84
+
65
85
  # Initialize a new instance
66
86
  #
67
87
  # @param [Specification] spec
@@ -81,12 +101,14 @@ module PodBuilder
81
101
  @name = spec.name
82
102
  @root_name = spec.name.split("/").first
83
103
 
84
- if checkout_options.has_key?(name)
85
- @repo = checkout_options[name][:git]
86
- @tag = checkout_options[name][:tag]
87
- @commit = checkout_options[name][:commit]
88
- @path = checkout_options[name][:path]
89
- @branch = checkout_options[name][:branch]
104
+ checkout_options_keys = [@name, @root_name]
105
+
106
+ if opts_key = checkout_options_keys.detect { |x| checkout_options.has_key?(x) }
107
+ @repo = checkout_options[opts_key][:git]
108
+ @tag = checkout_options[opts_key][:tag]
109
+ @commit = checkout_options[opts_key][:commit]
110
+ @path = checkout_options[opts_key][:path]
111
+ @branch = checkout_options[opts_key][:branch]
90
112
  @is_external = true
91
113
  else
92
114
  @repo = spec.root.source[:git]
@@ -94,7 +116,27 @@ module PodBuilder
94
116
  @commit = spec.root.source[:commit]
95
117
  @is_external = false
96
118
  end
97
-
119
+
120
+ @vendored_items = recursive_vendored_items(spec)
121
+
122
+ @frameworks = []
123
+ @frameworks += extract_array(spec, "framework")
124
+ @frameworks += extract_array(spec, "frameworks")
125
+ @frameworks += extract_array(spec.root, "framework")
126
+ @frameworks += extract_array(spec.root, "frameworks")
127
+
128
+ @weak_frameworks = []
129
+ @weak_frameworks += extract_array(spec, "weak_frameworks")
130
+ @weak_frameworks += extract_array(spec, "weak_frameworks")
131
+ @weak_frameworks += extract_array(spec.root, "weak_frameworks")
132
+ @weak_frameworks += extract_array(spec.root, "weak_frameworks")
133
+
134
+ @libraries = []
135
+ @libraries += extract_array(spec, "library")
136
+ @libraries += extract_array(spec, "libraries")
137
+ @libraries += extract_array(spec.root, "library")
138
+ @libraries += extract_array(spec.root, "libraries")
139
+
98
140
  @version = spec.root.version.version
99
141
 
100
142
  @swift_version = spec.root.swift_version&.to_s
@@ -104,22 +146,78 @@ module PodBuilder
104
146
 
105
147
  @is_static = spec.root.attributes_hash["static_framework"] || false
106
148
  @xcconfig = spec.root.attributes_hash["xcconfig"] || {}
149
+
150
+ @has_source_files_key = spec.root.attributes_hash.has_key?("source_files") || spec.attributes_hash.has_key?("source_files")
151
+
107
152
  @build_configuration = spec.root.attributes_hash.dig("pod_target_xcconfig", "prebuild_configuration") || "release"
108
153
  @build_configuration.downcase!
109
154
  end
155
+
156
+ def pod_specification(all_poditems, parent_spec = nil)
157
+ spec_raw = {}
158
+
159
+ spec_raw["name"] = @name
160
+ spec_raw["module_name"] = @module_name
161
+
162
+ spec_raw["source"] = {}
163
+ if repo = @repo
164
+ spec_raw["source"]["git"] = repo
165
+ end
166
+ if tag = @tag
167
+ spec_raw["source"]["tag"] = tag
168
+ end
169
+ if commit = @commit
170
+ spec_raw["source"]["commit"] = commit
171
+ end
172
+
173
+ spec_raw["version"] = @version
174
+ if swift_version = @swift_version
175
+ spec_raw["swift_version"] = swift_version
176
+ end
177
+
178
+ spec_raw["static_framework"] = is_static
179
+
180
+ spec_raw["frameworks"] = @frameworks
181
+ spec_raw["libraries"] = @libraries
182
+
183
+ spec_raw["xcconfig"] = @xcconfig
184
+
185
+ spec_raw["dependencies"] = @dependency_names.map { |x| [x, []] }.to_h
186
+
187
+ spec = Pod::Specification.from_hash(spec_raw, parent_spec)
188
+ all_subspec_items = all_poditems.select { |x| x.is_subspec && x.root_name == @name }
189
+ spec.subspecs = all_subspec_items.map { |x| x.pod_specification(all_poditems, spec) }
190
+
191
+ return spec
192
+ end
110
193
 
111
194
  def inspect
112
195
  return "#{@name} repo=#{@repo} pinned=#{@tag || @commit} is_static=#{@is_static} deps=#{@dependencies || "[]"}"
113
196
  end
114
197
 
198
+ def to_s
199
+ return @name
200
+ end
201
+
115
202
  def dependencies(available_pods)
116
- return available_pods.select { |x| dependency_names.include?(x.name) }
203
+ return available_pods.select { |x| @dependency_names.include?(x.name) }
117
204
  end
118
205
 
119
206
  # @return [Bool] True if it's a pod that doesn't provide source code (is already shipped as a prebuilt pod)
120
207
  #
121
208
  def is_prebuilt
122
- @repo.nil? && @path.nil?
209
+ # We treat pods to skip like prebuilt ones
210
+ if Configuration.skip_pods.include?(@root_name) || Configuration.skip_pods.include?(@name)
211
+ return true
212
+ end
213
+
214
+ # checking if there's a vendored_item matching the module name is a pretty good guess for a prebuilt pod.
215
+ # Still suboptimal, maybe it should be more appropriate to use FileAccessor and check that no source code is provided (no *.{m,mm,c,cpp,swift, etc})
216
+ if vendored_items.map { |x| File.basename(x) }.include?("#{@module_name}.framework")
217
+ return true
218
+ else
219
+ return !@has_source_files_key && @vendored_items.count > 0
220
+ end
123
221
  end
124
222
 
125
223
  # @return [Bool] True if it's a subspec
@@ -130,7 +228,7 @@ module PodBuilder
130
228
 
131
229
  # @return [String] The podfile entry
132
230
  #
133
- def entry(include_version = true)
231
+ def entry(include_version = true, include_pb_entry = true)
134
232
  e = "pod '#{@name}'"
135
233
 
136
234
  unless include_version
@@ -138,25 +236,30 @@ module PodBuilder
138
236
  end
139
237
 
140
238
  if is_external
141
- if @repo
142
- e += ", :git => '#{@repo}'"
143
- end
144
- if @tag
145
- e += ", :tag => '#{@tag}'"
146
- end
147
- if @commit
148
- e += ", :commit => '#{@commit}'"
149
- end
150
239
  if @path
151
240
  e += ", :path => '#{@path}'"
152
- end
153
- if @branch
154
- e += ", :branch => '#{@branch}'"
241
+ else
242
+ if @repo
243
+ e += ", :git => '#{@repo}'"
244
+ end
245
+ if @tag
246
+ e += ", :tag => '#{@tag}'"
247
+ end
248
+ if @commit
249
+ e += ", :commit => '#{@commit}'"
250
+ end
251
+ if @branch
252
+ e += ", :branch => '#{@branch}'"
253
+ end
155
254
  end
156
255
  else
157
256
  e += ", '=#{@version}'"
158
257
  end
159
258
 
259
+ if include_pb_entry
260
+ e += " # pb<#{name}>"
261
+ end
262
+
160
263
  return e
161
264
  end
162
265
 
@@ -165,16 +268,26 @@ module PodBuilder
165
268
  end
166
269
 
167
270
  def prebuilt_rel_path
168
- if is_subspec
271
+ if is_subspec && Configuration.subspecs_to_split.include?(name)
169
272
  return "#{name}/#{module_name}.framework"
170
273
  else
171
274
  return "#{module_name}.framework"
172
275
  end
173
276
  end
174
277
 
175
- def prebuilt_entry
176
- relative_path = Pathname.new(Configuration.base_path).relative_path_from(Pathname.new(PodBuilder::xcodepath)).to_s
177
- return "pod 'PodBuilder/#{podspec_name}', :path => '#{relative_path}'"
278
+ def prebuilt_entry(include_pb_entry = true)
279
+ relative_path = Pathname.new(Configuration.base_path).relative_path_from(Pathname.new(PodBuilder::project_path)).to_s
280
+ if Configuration.subspecs_to_split.include?(name)
281
+ entry = "pod 'PodBuilder/#{podspec_name}', :path => '#{relative_path}'"
282
+ else
283
+ entry = "pod 'PodBuilder/#{root_name}', :path => '#{relative_path}'"
284
+ end
285
+
286
+ if include_pb_entry
287
+ entry += " # pb<#{name}>"
288
+ end
289
+
290
+ return entry
178
291
  end
179
292
 
180
293
  def has_subspec(named)
@@ -203,5 +316,46 @@ module PodBuilder
203
316
 
204
317
  return nil
205
318
  end
319
+
320
+ private
321
+
322
+ def recursive_vendored_items(spec)
323
+ items = []
324
+
325
+ items += [spec.root.attributes_hash["vendored_frameworks"]]
326
+ items += [spec.root.attributes_hash["vendored_framework"]]
327
+ items += [spec.root.attributes_hash["vendored_libraries"]]
328
+ items += [spec.root.attributes_hash["vendored_library"]]
329
+
330
+ items += [spec.attributes_hash["vendored_frameworks"]]
331
+ items += [spec.attributes_hash["vendored_framework"]]
332
+ items += [spec.attributes_hash["vendored_libraries"]]
333
+ items += [spec.attributes_hash["vendored_library"]]
334
+
335
+ supported_platforms = spec.available_platforms.flatten.map(&:name).map(&:to_s)
336
+
337
+ items += supported_platforms.map { |x| spec.root.attributes_hash.fetch(x, {})["vendored_frameworks"] }
338
+ items += supported_platforms.map { |x| spec.root.attributes_hash.fetch(x, {})["vendored_framework"] }
339
+ items += supported_platforms.map { |x| spec.root.attributes_hash.fetch(x, {})["vendored_libraries"] }
340
+ items += supported_platforms.map { |x| spec.root.attributes_hash.fetch(x, {})["vendored_library"] }
341
+
342
+ items += supported_platforms.map { |x| spec.attributes_hash.fetch(x, {})["vendored_frameworks"] }
343
+ items += supported_platforms.map { |x| spec.attributes_hash.fetch(x, {})["vendored_framework"] }
344
+ items += supported_platforms.map { |x| spec.attributes_hash.fetch(x, {})["vendored_libraries"] }
345
+ items += supported_platforms.map { |x| spec.attributes_hash.fetch(x, {})["vendored_library"] }
346
+
347
+ items = items.flatten.compact
348
+
349
+ return items.flatten
350
+ end
351
+
352
+ def extract_array(spec, key)
353
+ element = spec.attributes_hash.fetch(key, [])
354
+ if element.instance_of? String
355
+ element = [element]
356
+ end
357
+
358
+ return element
359
+ end
206
360
  end
207
361
  end