pod-builder 2.0.0.beta.19 → 2.0.0.beta.21

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -2
  3. data/Example/{Frameworks → PodBuilder}/.gitignore +0 -0
  4. data/Example/{Frameworks → PodBuilder}/.pod_builder/pod_builder +0 -0
  5. data/Example/{Frameworks → PodBuilder}/PodBuilder.json +0 -0
  6. data/Example/{Frameworks → PodBuilder}/Podfile +0 -0
  7. data/Example/{Frameworks → PodBuilder}/Podfile.restore +0 -0
  8. data/Example/Podfile +27 -29
  9. data/Example/Podfile.lock +42 -42
  10. data/README.md +13 -13
  11. data/exe/pod_builder +27 -16
  12. data/lib/pod_builder/command/build.rb +28 -159
  13. data/lib/pod_builder/command/build_all.rb +2 -2
  14. data/lib/pod_builder/command/clean.rb +34 -53
  15. data/lib/pod_builder/command/clear_lldbinit.rb +6 -2
  16. data/lib/pod_builder/command/deintegrate.rb +27 -6
  17. data/lib/pod_builder/command/generate_lfs.rb +1 -1
  18. data/lib/pod_builder/command/generate_podspec.rb +3 -2
  19. data/lib/pod_builder/command/info.rb +1 -1
  20. data/lib/pod_builder/command/init.rb +37 -14
  21. data/lib/pod_builder/command/install_sources.rb +20 -13
  22. data/lib/pod_builder/command/none.rb +2 -2
  23. data/lib/pod_builder/command/restore_all.rb +4 -4
  24. data/lib/pod_builder/command/switch.rb +56 -14
  25. data/lib/pod_builder/command/sync_podfile.rb +3 -2
  26. data/lib/pod_builder/command/update.rb +5 -6
  27. data/lib/pod_builder/command/update_lldbinit.rb +10 -8
  28. data/lib/pod_builder/configuration.rb +27 -7
  29. data/lib/pod_builder/core.rb +35 -9
  30. data/lib/pod_builder/info.rb +11 -11
  31. data/lib/pod_builder/install.rb +178 -184
  32. data/lib/pod_builder/licenses.rb +4 -4
  33. data/lib/pod_builder/podfile.rb +226 -85
  34. data/lib/pod_builder/podfile/post_actions.rb +9 -14
  35. data/lib/pod_builder/podfile_cp.rb +93 -0
  36. data/lib/pod_builder/podfile_item.rb +41 -20
  37. data/lib/pod_builder/podspec.rb +33 -16
  38. data/lib/pod_builder/rome/post_install.rb +121 -129
  39. data/lib/pod_builder/rome/pre_install.rb +1 -1
  40. data/lib/pod_builder/templates/build_podfile.template +2 -2
  41. data/lib/pod_builder/version.rb +1 -1
  42. metadata +8 -7
@@ -1,10 +1,9 @@
1
1
  require 'pod_builder/core'
2
- require 'cfpropertylist'
3
2
 
4
3
  module PodBuilder
5
4
  module Command
6
5
  class Update
7
- def self.call(options)
6
+ def self.call
8
7
  Configuration.check_inited
9
8
  PodBuilder::prepare_basepath
10
9
 
@@ -25,10 +24,10 @@ module PodBuilder
25
24
  pods_to_update.map! { |x| x.split("/").first }.uniq!
26
25
 
27
26
  unless pods_to_update.count > 0
28
- puts "Frameworks in sync!\n".green
27
+ puts "Prebuilt items in sync!\n".green
29
28
  return 0
30
29
  end
31
- if options.has_key?(:dry_run)
30
+ if OPTIONS.has_key?(:dry_run)
32
31
  puts "`#{pods_to_update.join("`, `")}` need to be rebuilt!\n".red
33
32
  return -2
34
33
  end
@@ -36,8 +35,8 @@ module PodBuilder
36
35
  ARGV.clear
37
36
  pods_to_update.each { |x| ARGV << x }
38
37
 
39
- # options[:auto_resolve_dependencies] = true
40
- return PodBuilder::Command::Build.call(options)
38
+ # OPTIONS[:auto_resolve_dependencies] = true
39
+ return PodBuilder::Command::Build.call
41
40
  end
42
41
  end
43
42
  end
@@ -4,9 +4,12 @@ require 'digest'
4
4
  module PodBuilder
5
5
  module Command
6
6
  class UpdateLldbInit
7
- def self.call(options)
7
+ def self.call
8
8
  Configuration.check_inited
9
-
9
+ if Configuration.build_using_repo_paths
10
+ raise "\n\nlldb shenanigans not supported when 'build_using_repo_paths' is enabled".red
11
+ end
12
+
10
13
  argument_pods = ARGV.dup
11
14
 
12
15
  unless argument_pods.count > 0
@@ -55,10 +58,9 @@ module PodBuilder
55
58
  name = File.basename(framework_path, File.extname(framework_path))
56
59
  executable_path = File.join(framework_path, name)
57
60
 
58
- podbuilder_plist = File.join(framework_path, Configuration.framework_plist_filename)
59
-
60
- plist = CFPropertyList::List.new(:file => podbuilder_plist)
61
- data = CFPropertyList.native_types(plist.value)
61
+ parent_framework_path = File.expand_path(File.joing(framework_path, ".."))
62
+ framework_info_path = File.join(parent_framework_path, Configuration.prebuilt_info_filename)
63
+ data = JSON.parse(File.read(framework_info_path))
62
64
 
63
65
  original_compile_path = data["original_compile_path"]
64
66
  is_prebuilt = data.fetch("is_prebuilt", true)
@@ -125,7 +127,7 @@ module PodBuilder
125
127
  puts "Writing #{lldbinit_path}".yellow
126
128
 
127
129
  FileUtils.touch(lldbinit_path)
128
- raise "\n\nDestination file should be a file" unless File.exist?(lldbinit_path)
130
+ raise "\n\nDestination file should be a file".red unless File.exist?(lldbinit_path)
129
131
 
130
132
  lldbinit_lines = []
131
133
  skipNext = false
@@ -138,7 +140,7 @@ module PodBuilder
138
140
  next
139
141
  elsif line != "\n"
140
142
  if line.include?("settings set target.source-map")
141
- raise "\n\n#{lldbinit_destination_path} already includes a manual `settings set target.source-map`. This is unsupported and you'll have to manually remove that entry\n"
143
+ raise "\n\n#{lldbinit_destination_path} already includes a manual `settings set target.source-map`. This is unsupported and you'll have to manually remove that entry\n".red
142
144
  end
143
145
  lldbinit_lines.push(line)
144
146
  end
@@ -19,13 +19,14 @@ module PodBuilder
19
19
  "module_name": "GoogleMobileAds"
20
20
  }
21
21
  }.freeze
22
- DEFAULT_SKIP_PODS = ["GoogleMaps"]
22
+ DEFAULT_SKIP_PODS = ["GoogleMaps", "Flipper", "FlipperKit", "Flipper-DoubleConversion", "Flipper-Folly", "Flipper-Glog", "Flipper-PeerTalk", "Flipper-RSocket", "React-cxxreact"]
23
23
  DEFAULT_FORCE_PREBUILD_PODS = ["Firebase", "GoogleTagManager"]
24
24
  DEFAULT_BUILD_SYSTEM = "Legacy".freeze # either Latest (New build system) or Legacy (Standard build system)
25
25
  DEFAULT_LIBRARY_EVOLUTION_SUPPORT = false
26
26
  MIN_LFS_SIZE_KB = 256.freeze
27
27
  DEFAULT_PLATFORMS = ["iphoneos", "iphonesimulator", "appletvos", "appletvsimulator"].freeze
28
28
  DEFAULT_BUILD_FOR_APPLE_SILICON = false
29
+ DEFAULT_BUILD_USING_REPO_PATHS = false
29
30
 
30
31
  private_constant :DEFAULT_BUILD_SETTINGS
31
32
  private_constant :DEFAULT_BUILD_SYSTEM
@@ -55,13 +56,15 @@ module PodBuilder
55
56
  attr_accessor :lfs_include_pods_folder
56
57
  attr_accessor :project_name
57
58
  attr_accessor :restore_enabled
58
- attr_accessor :framework_plist_filename
59
+ attr_accessor :prebuilt_info_filename
59
60
  attr_accessor :lockfile_name
60
61
  attr_accessor :lockfile_path
61
62
  attr_accessor :use_bundler
62
63
  attr_accessor :deterministic_build
63
64
  attr_accessor :supported_platforms
64
65
  attr_accessor :build_for_apple_silicon
66
+ attr_accessor :build_using_repo_paths
67
+ attr_accessor :react_native_project
65
68
  end
66
69
 
67
70
  @allow_building_development_pods = false
@@ -69,7 +72,7 @@ module PodBuilder
69
72
  @build_settings_overrides = {}
70
73
  @build_system = DEFAULT_BUILD_SYSTEM
71
74
  @library_evolution_support = DEFAULT_LIBRARY_EVOLUTION_SUPPORT
72
- @base_path = "Frameworks" # Not nice. This value is used only for initial initization. Once config is loaded it will be an absolute path. FIXME
75
+ @base_path = "PodBuilder" # Not nice. This value is used only for initial initization. Once config is loaded it will be an absolute path. FIXME
73
76
  @spec_overrides = DEFAULT_SPEC_OVERRIDE
74
77
  @skip_licenses = []
75
78
  @skip_pods = DEFAULT_SKIP_PODS
@@ -86,7 +89,7 @@ module PodBuilder
86
89
  @lfs_include_pods_folder = false
87
90
  @project_name = ""
88
91
  @restore_enabled = true
89
- @framework_plist_filename = "PodBuilder.plist"
92
+ @prebuilt_info_filename = "PodBuilder.json"
90
93
  @lockfile_name = "PodBuilder.lock"
91
94
  @lockfile_path = "/tmp/#{lockfile_name}"
92
95
 
@@ -95,6 +98,8 @@ module PodBuilder
95
98
 
96
99
  @supported_platforms = DEFAULT_PLATFORMS
97
100
  @build_for_apple_silicon = DEFAULT_BUILD_FOR_APPLE_SILICON
101
+ @build_using_repo_paths = DEFAULT_BUILD_USING_REPO_PATHS
102
+ @react_native_project = false
98
103
 
99
104
  def self.check_inited
100
105
  raise "\n\nNot inited, run `pod_builder init`\n".red if podbuilder_path.nil?
@@ -208,12 +213,20 @@ module PodBuilder
208
213
  Configuration.build_for_apple_silicon = value
209
214
  end
210
215
  end
216
+ if value = json["build_using_repo_paths"]
217
+ if [TrueClass, FalseClass].include?(value.class)
218
+ Configuration.build_using_repo_paths = value
219
+ end
220
+ end
221
+ if value = json["react_native_project"]
222
+ if [TrueClass, FalseClass].include?(value.class)
223
+ Configuration.react_native_project = value
224
+ end
225
+ end
211
226
 
212
227
  Configuration.build_settings.freeze
213
228
 
214
229
  sanity_check()
215
- else
216
- write
217
230
  end
218
231
 
219
232
  dev_pods_configuration_path = File.join(Configuration.base_path, Configuration.dev_pods_configuration_filename)
@@ -251,6 +264,13 @@ module PodBuilder
251
264
  config["subspecs_to_split"] = Configuration.subspecs_to_split
252
265
  config["lfs_update_gitattributes"] = Configuration.lfs_update_gitattributes
253
266
  config["lfs_include_pods_folder"] = Configuration.lfs_include_pods_folder
267
+ config["restore_enabled"] = Configuration.restore_enabled
268
+ config["allow_building_development_pods"] = Configuration.allow_building_development_pods
269
+ config["use_bundler"] = Configuration.use_bundler
270
+ config["deterministic_build"] = Configuration.deterministic_build
271
+ config["build_for_apple_silicon"] = Configuration.build_for_apple_silicon
272
+ config["build_using_repo_paths"] = Configuration.build_using_repo_paths
273
+ config["react_native_project"] = Configuration.react_native_project
254
274
 
255
275
  File.write(config_path, JSON.pretty_generate(config))
256
276
  end
@@ -275,7 +295,7 @@ module PodBuilder
275
295
 
276
296
  def self.podbuilder_path
277
297
  paths = Dir.glob("#{PodBuilder::home}/**/.pod_builder")
278
- paths.reject! { |t| t.match(/pod-builder-.*\/Example\/Frameworks\/\.pod_builder$/i) }
298
+ paths.reject! { |t| t.match(/pod-builder-.*\/Example\/#{File.basename(Configuration.base_path)}\/\.pod_builder$/i) }
279
299
  raise "\n\nToo many .pod_builder found `#{paths.join("\n")}`\n".red if paths.count > 1
280
300
 
281
301
  return paths.count > 0 ? File.dirname(paths.first) : nil
@@ -3,6 +3,7 @@ require 'fileutils'
3
3
  require 'colored'
4
4
 
5
5
  require 'pod_builder/podfile'
6
+ require 'pod_builder/podfile_cp'
6
7
  require 'pod_builder/podfile_item'
7
8
  require 'pod_builder/analyze'
8
9
  require 'pod_builder/analyzer'
@@ -15,6 +16,9 @@ require 'pod_builder/licenses'
15
16
  require 'core_ext/string'
16
17
 
17
18
  module PodBuilder
19
+ @@xcodeproj_path = nil
20
+ @@xcodeworkspace_path = nil
21
+
18
22
  def self.safe_rm_rf(path)
19
23
  unless File.exist?(path)
20
24
  return
@@ -55,7 +59,7 @@ module PodBuilder
55
59
  return nil
56
60
  end
57
61
 
58
- path = basepath("Rome")
62
+ path = basepath("Prebuilt")
59
63
  if child.length > 0
60
64
  path += "/#{child}"
61
65
  end
@@ -68,7 +72,20 @@ module PodBuilder
68
72
  return nil
69
73
  end
70
74
 
71
- path = "#{Configuration.build_path}/Rome"
75
+ path = "#{Configuration.build_path}/Prebuilt"
76
+ if child.length > 0
77
+ path += "/#{child}"
78
+ end
79
+
80
+ return path
81
+ end
82
+
83
+ def self.buildpath_dsympath(child = "")
84
+ if child.nil?
85
+ return nil
86
+ end
87
+
88
+ path = "#{Configuration.build_path}/dSYM"
72
89
  if child.length > 0
73
90
  path += "/#{child}"
74
91
  end
@@ -96,27 +113,36 @@ module PodBuilder
96
113
  end
97
114
 
98
115
  def self.find_xcodeproj
116
+ unless @@xcodeproj_path.nil?
117
+ return @@xcodeproj_path
118
+ end
99
119
  project_name = File.basename(find_xcodeworkspace, ".*")
100
120
 
101
121
  xcodeprojects = Dir.glob("#{home}/**/#{project_name}.xcodeproj").select { |x|
102
122
  folder_in_home = x.gsub(home, "")
103
123
  !folder_in_home.include?("/Pods/") && !x.include?(PodBuilder::basepath("Sources")) && !x.include?(basepath)
104
124
  }
105
- raise "xcodeproj not found!".red if xcodeprojects.count == 0
106
- raise "Found multiple xcodeproj:\n#{xcodeprojects.join("\n")}".red if xcodeprojects.count > 1
125
+ raise "\n\nxcodeproj not found!".red if xcodeprojects.count == 0
126
+ raise "\n\nFound multiple xcodeproj:\n#{xcodeprojects.join("\n")}".red if xcodeprojects.count > 1
107
127
 
108
- return xcodeprojects.first
128
+ @@xcodeproj_path = xcodeprojects.first
129
+ return @@xcodeproj_path
109
130
  end
110
131
 
111
132
  def self.find_xcodeworkspace
133
+ unless @@xcodeworkspace_path.nil?
134
+ return @@xcodeworkspace_path
135
+ end
136
+
112
137
  xcworkspaces = Dir.glob("#{home}/**/#{Configuration.project_name}*.xcworkspace").select { |x|
113
138
  folder_in_home = x.gsub(home, "")
114
139
  !folder_in_home.include?("/Pods/") && !x.include?(PodBuilder::basepath("Sources")) && !x.include?(basepath) && !x.include?(".xcodeproj/")
115
140
  }
116
- raise "xcworkspace not found!".red if xcworkspaces.count == 0
117
- raise "Found multiple xcworkspaces:\n#{xcworkspaces.join("\n")}".red if xcworkspaces.count > 1
141
+ raise "\n\nxcworkspace not found!".red if xcworkspaces.count == 0
142
+ raise "\n\nFound multiple xcworkspaces:\n#{xcworkspaces.join("\n")}".red if xcworkspaces.count > 1
118
143
 
119
- return xcworkspaces.first
144
+ @@xcodeworkspace_path = xcworkspaces.first
145
+ return @@xcodeworkspace_path
120
146
  end
121
147
 
122
148
  def self.prepare_basepath
@@ -143,7 +169,7 @@ module PodBuilder
143
169
 
144
170
  def self.system_swift_version
145
171
  swift_version = `swiftc --version | grep -o 'swiftlang-.*\s'`.strip()
146
- raise "Unsupported swift compiler version, expecting `swiftlang` keyword in `swiftc --version`" if swift_version.length == 0
172
+ raise "\n\nUnsupported swift compiler version, expecting `swiftlang` keyword in `swiftc --version`".red if swift_version.length == 0
147
173
  return swift_version
148
174
  end
149
175
 
@@ -1,4 +1,4 @@
1
- require 'cfpropertylist'
1
+ require 'json'
2
2
 
3
3
  module PodBuilder
4
4
  class Info
@@ -7,10 +7,8 @@ module PodBuilder
7
7
  result = {}
8
8
  name = nil
9
9
 
10
- Dir.glob(PodBuilder::prebuiltpath("**/*.framework")).each do |path|
11
- plist_path = File.join(path, Configuration.framework_plist_filename)
12
-
13
- name, prebuilt_info = prebuilt_info(plist_path)
10
+ Dir.glob(PodBuilder::prebuiltpath("**/#{Configuration.prebuilt_info_filename}")).each do |json_path|
11
+ name, prebuilt_info = prebuilt_info(json_path)
14
12
  result[name] = prebuilt_info
15
13
  end
16
14
 
@@ -56,9 +54,13 @@ module PodBuilder
56
54
  elsif (matches = line&.match(/pod '(.*)', :path => '(.*)'/)) && matches.size == 3
57
55
  pod_name = matches[1]
58
56
 
57
+ return { "repo": "local" }
58
+ elsif (matches = line&.match(/pod '(.*)', :podspec => '(.*)'/)) && matches.size == 3
59
+ pod_name = matches[1]
60
+
59
61
  return { "repo": "local" }
60
62
  else
61
- raise "Failed extracting version from line:\n#{line}\n\n"
63
+ raise "\n\nFailed extracting version from line:\n#{line}\n\n".red
62
64
  end
63
65
  end
64
66
 
@@ -66,10 +68,9 @@ module PodBuilder
66
68
  unless File.exist?(path)
67
69
  return {}
68
70
  end
69
-
70
- plist = CFPropertyList::List.new(:file => path)
71
- data = CFPropertyList.native_types(plist.value)
72
-
71
+
72
+ data = JSON.load(File.read(path))
73
+
73
74
  result = {}
74
75
  if swift_version = data["swift_version"]
75
76
  result.merge!({ "swift_version": swift_version})
@@ -78,7 +79,6 @@ module PodBuilder
78
79
  pod_version = version_info_from_entry(data["entry"])
79
80
  pod_name = pod_name_from_entry(data["entry"])
80
81
 
81
-
82
82
  result.merge!({ "version": pod_version })
83
83
  result.merge!({ "specs": (data["specs"] || []) })
84
84
  result.merge!({ "is_static": (data["is_static"] || false) })
@@ -1,6 +1,8 @@
1
- require 'cfpropertylist'
2
1
  require 'digest'
3
2
  require 'colored'
3
+ require 'highline/import'
4
+
5
+ # The following begin/end clause contains a set of monkey patches of the original CP implementation
4
6
 
5
7
  # The Pod::Target and Pod::Installer::Xcode::PodTargetDependencyInstaller swizzles patch
6
8
  # the following issues:
@@ -38,7 +40,7 @@ begin
38
40
  elsif defined?(Pod::Target::BuildType) # CocoaPods 1.7, 1.8
39
41
  Pod::Target::BuildType.new(linkage: :dynamic, packaging: :framework)
40
42
  else
41
- raise "BuildType not found. Open an issue reporting your CocoaPods version"
43
+ raise "\n\nBuildType not found. Open an issue reporting your CocoaPods version".red
42
44
  end
43
45
  else
44
46
  swz_build_type()
@@ -75,89 +77,131 @@ end
75
77
 
76
78
  module PodBuilder
77
79
  class Install
80
+ # This method will generate prebuilt data by building from "/tmp/pod_builder/Podfile"
78
81
  def self.podfile(podfile_content, podfile_items, build_configuration)
79
82
  puts "Preparing build Podfile".yellow
80
83
 
81
84
  PodBuilder::safe_rm_rf(Configuration.build_path)
82
85
  FileUtils.mkdir_p(Configuration.build_path)
83
-
84
- # Copy the repo to extract license (and potentially other files in the future)
85
- podfile_items.select { |x| x.is_development_pod }.each do |podfile_item|
86
- destination_path = "#{Configuration.build_path}/Pods/#{podfile_item.name}"
87
- FileUtils.mkdir_p(destination_path)
88
-
89
- if Pathname.new(podfile_item.path).absolute?
90
- FileUtils.cp_r("#{podfile_item.path}/.", destination_path)
91
- else
92
- FileUtils.cp_r("#{PodBuilder::basepath(podfile_item.path)}/.", destination_path)
93
- end
94
-
95
- # It is important that CocoaPods compiles the files under Configuration.build_path in order that DWARF
96
- # debug info reference to this path. Doing otherwise breaks the assumptions that makes the `update_lldbinit`
97
- # command work
98
- podfile_content.gsub!("'#{podfile_item.path}'", "'#{destination_path}'")
99
-
100
- license_files = Dir.glob("#{destination_path}/**/*acknowledgements.plist").each { |f| File.delete(f) }
101
- end
102
86
 
103
87
  init_git(Configuration.build_path) # this is needed to be able to call safe_rm_rf
104
88
 
105
- podfile_path = "#{Configuration.build_path}/Podfile"
89
+ podfile_content = copy_development_pods_source_code(podfile_content, podfile_items)
90
+
91
+ podfile_content = Podfile.update_path_entries(podfile_content, Install.method(:podfile_path_transform))
92
+ podfile_content = Podfile.update_project_entries(podfile_content, Install.method(:podfile_path_transform))
93
+ podfile_content = Podfile.update_require_entries(podfile_content, Install.method(:podfile_path_transform))
94
+
95
+ podfile_path = File.join(Configuration.build_path, "Podfile")
106
96
  File.write(podfile_path, podfile_content)
107
- Podfile.update_path_entires(podfile_path, true)
108
- Podfile.update_project_entries(podfile_path, true)
109
97
 
110
98
  begin
111
99
  lock_file = "#{Configuration.build_path}/pod_builder.lock"
112
100
  FileUtils.touch(lock_file)
113
101
 
114
- framework_build_hashes = Hash.new
115
- if !OPTIONS.has_key?(:force_rebuild)
116
- download # Copy files under #{Configuration.build_path}/Pods so that we can determine build folder hashes
117
-
118
- # Replace prebuilt entries in Podfile for Pods that have no changes in source code which will avoid rebuilding them
119
- items = podfile_items.group_by { |t| t.root_name }.map { |k, v| v.first } # Return one podfile_item per root_name
120
- items.each do |item|
121
- framework_path = File.join(PodBuilder::prebuiltpath, "#{item.module_name}.framework")
122
- podspec_path = File.join(PodBuilder::prebuiltpath, "#{item.root_name}.podspec")
123
- if (last_build_folder_hash = build_folder_hash_in_framework_plist_info(framework_path)) && File.exist?(podspec_path)
124
- if last_build_folder_hash == build_folder_hash(item)
125
- puts "No changes detected to '#{item.root_name}', will skip rebuild".blue
126
- podfile_items.select { |t| t.root_name == item.root_name }.each do |replace_item|
127
- replace_regex = "pod '#{Regexp.quote(replace_item.name)}', .*"
128
- replace_line_found = podfile_content =~ /#{replace_regex}/i
129
- raise "Failed finding pod entry for '#{replace_item.name}'" unless replace_line_found
130
- podfile_content.gsub!(/#{replace_regex}/, replace_item.prebuilt_entry(true, true))
131
- end
132
- end
133
- end
134
- end
135
-
136
- File.write(podfile_path, podfile_content)
137
- end
102
+ use_prebuilt_entries_for_unchanged_pods(podfile_path, podfile_items)
138
103
 
139
104
  install
140
105
 
141
- add_framework_plist_info(podfile_items)
142
- cleanup_frameworks(podfile_items)
143
- copy_frameworks(podfile_items)
144
- copy_libraries(podfile_items)
145
- copy_dsyms(podfile_items)
146
- rescue Exception => e
147
- raise e
148
- ensure
149
- FileUtils.rm(lock_file)
106
+ copy_prebuilt_items(podfile_items)
107
+ add_prebuilt_info_file(podfile_items)
108
+
109
+ licenses = license_specifiers()
150
110
 
151
111
  if !OPTIONS.has_key?(:debug)
152
112
  PodBuilder::safe_rm_rf(Configuration.build_path)
153
113
  end
114
+
115
+ return licenses
116
+ rescue Exception => e
117
+ if File.directory?("#{Configuration.build_path}/Pods/Pods.xcodeproj")
118
+ if ENV['DEBUGGING']
119
+ system("xed #{Configuration.build_path}/Pods")
120
+ else
121
+ confirm = ask("\n\nOh no! Something went wrong during prebuild phase! Do you want to open the prebuild project to debug the error, you will need to add and run the Pods-Dummy scheme? [Y/N] ".red) { |yn| yn.limit = 1, yn.validate = /[yn]/i }
122
+ if confirm.downcase == 'y'
123
+ system("xed #{Configuration.build_path}/Pods")
124
+ end
125
+ end
126
+ end
127
+
128
+ raise e
129
+ ensure
130
+ FileUtils.rm(lock_file) if File.exist?(lock_file)
154
131
  end
155
132
  end
156
133
 
157
134
  private
158
135
 
136
+ def self.license_specifiers
137
+ acknowledge_file = "#{Configuration.build_path}/Pods/Target Support Files/Pods-DummyTarget/Pods-DummyTarget-acknowledgements.plist"
138
+ unless File.exist?(acknowledge_file)
139
+ raise "\n\nLicense file not found".red
140
+ end
141
+
142
+ plist = CFPropertyList::List.new(:file => acknowledge_file)
143
+ data = CFPropertyList.native_types(plist.value)
144
+
145
+ return data["PreferenceSpecifiers"] || []
146
+ end
147
+
148
+ def self.copy_development_pods_source_code(podfile_content, podfile_items)
149
+ if Configuration.build_using_repo_paths
150
+ return podfile_content
151
+ end
152
+
153
+ # Development pods are normally built/integrated without moving files from their original paths.
154
+ # It is important that CocoaPods compiles the files under Configuration.build_path in order that
155
+ # DWARF debug info reference to this constant path. Doing otherwise breaks the assumptions that
156
+ # makes the `update_lldbinit` command work.
157
+ development_pods = podfile_items.select { |x| x.is_development_pod }
158
+ development_pods.each do |podfile_item|
159
+ destination_path = "#{Configuration.build_path}/Pods/#{podfile_item.name}"
160
+ FileUtils.mkdir_p(destination_path)
161
+
162
+ if Pathname.new(podfile_item.path).absolute?
163
+ FileUtils.cp_r("#{podfile_item.path}/.", destination_path)
164
+ else
165
+ FileUtils.cp_r("#{PodBuilder::basepath(podfile_item.path)}/.", destination_path)
166
+ end
167
+
168
+ podfile_content.gsub!("'#{podfile_item.path}'", "'#{destination_path}'")
169
+ end
170
+
171
+ return podfile_content
172
+ end
173
+
174
+ def self.use_prebuilt_entries_for_unchanged_pods(podfile_path, podfile_items)
175
+ if OPTIONS.has_key?(:force_rebuild)
176
+ return
177
+ end
178
+
179
+ download # Copy files under #{Configuration.build_path}/Pods so that we can determine build folder hashes
180
+
181
+ podfile_content = File.read(podfile_path)
182
+
183
+ # Replace prebuilt entries in Podfile for Pods that have no changes in source code which will avoid rebuilding them
184
+ items = podfile_items.group_by { |t| t.root_name }.map { |k, v| v.first } # Return one podfile_item per root_name
185
+ items.each do |item|
186
+ podspec_path = item.prebuilt_podspec_path
187
+ if last_build_folder_hash = build_folder_hash_in_prebuilt_info_file(item)
188
+ if last_build_folder_hash == build_folder_hash(item)
189
+ puts "No changes detected to '#{item.root_name}', will skip rebuild".blue
190
+ podfile_items.select { |t| t.root_name == item.root_name }.each do |replace_item|
191
+ replace_regex = "pod '#{Regexp.quote(replace_item.name)}', .*"
192
+ replace_line_found = podfile_content =~ /#{replace_regex}/i
193
+ raise "\n\nFailed finding pod entry for '#{replace_item.name}'".red unless replace_line_found
194
+ podfile_content.gsub!(/#{replace_regex}/, replace_item.prebuilt_entry(true, true))
195
+ end
196
+ end
197
+ end
198
+ end
199
+
200
+ File.write(podfile_path, podfile_content)
201
+ end
202
+
159
203
  def self.install
160
- puts "Building frameworks".yellow
204
+ puts "Prebuilding items".yellow
161
205
 
162
206
  CLAide::Command::PluginManager.load_plugins("cocoapods")
163
207
 
@@ -195,135 +239,67 @@ module PodBuilder
195
239
  end
196
240
  end
197
241
 
198
- def self.rel_path(path, podfile_items)
199
- name = File.basename(path)
200
- name_no_ext = File.basename(name, File.extname(name))
201
- if podfile_item = podfile_items.detect { |x| x.module_name == name_no_ext && Configuration.subspecs_to_split.include?(x.name) }
202
- return "#{podfile_item.prebuilt_rel_path}"
203
- else
204
- return name
205
- end
206
- end
242
+ def self.copy_prebuilt_items(podfile_items)
243
+ FileUtils.mkdir_p(PodBuilder::prebuiltpath)
207
244
 
208
- def self.add_framework_plist_info(podfile_items)
209
- swift_version = PodBuilder::system_swift_version
210
- Dir.glob(PodBuilder::buildpath_prebuiltpath("*.framework")) do |framework_path|
211
- filename_ext = File.basename(framework_path)
212
- filename = File.basename(framework_path, ".*")
213
-
214
- specs = podfile_items.select { |x| x.module_name == filename }
215
- specs += podfile_items.select { |x| x.vendored_frameworks.map { |x| File.basename(x) }.include?(filename_ext) }
216
- if podfile_item = specs.first
217
- podbuilder_file = File.join(framework_path, Configuration.framework_plist_filename)
218
- entry = podfile_item.entry(true, false)
219
-
220
- plist = CFPropertyList::List.new
221
- plist_data = {}
222
- plist_data['entry'] = entry
223
- plist_data['is_prebuilt'] = podfile_item.is_prebuilt
224
- if Dir.glob(File.join(framework_path, "Headers/*-Swift.h")).count > 0
225
- plist_data['swift_version'] = swift_version
226
- end
227
- subspecs_deps = specs.map(&:dependency_names).flatten
228
- subspec_self_deps = subspecs_deps.select { |x| x.start_with?("#{podfile_item.root_name}/") }
229
- plist_data['specs'] = (specs.map(&:name) + subspec_self_deps).uniq
230
- plist_data['is_static'] = podfile_item.is_static
231
- plist_data['original_compile_path'] = Pathname.new(Configuration.build_path).realpath.to_s
232
- plist_data['build_folder_hash'] = build_folder_hash(podfile_item)
233
-
234
- plist.value = CFPropertyList.guess(plist_data)
235
- plist.save(podbuilder_file, CFPropertyList::List::FORMAT_BINARY)
236
- else
237
- raise "Unable to detect item for framework #{filename}.framework. Please open a bug report!"
245
+ root_names = podfile_items.reject(&:is_prebuilt).map(&:root_name).uniq
246
+ root_names.each do |prebuilt_name|
247
+ source_path = PodBuilder::buildpath_prebuiltpath(prebuilt_name)
248
+ unless File.directory?(source_path)
249
+ puts "Prebuilt items for #{prebuilt_name} not found".blue
250
+ next
251
+ end
252
+ if Dir.empty?(source_path)
253
+ next # When using prebuilt items we end up with empty folders
238
254
  end
239
- end
240
- end
241
255
 
242
- def self.cleanup_frameworks(podfile_items)
243
- Dir.glob(PodBuilder::buildpath_prebuiltpath("*.framework")) do |framework_path|
244
- framework_rel_path = rel_path(framework_path, podfile_items)
245
- dsym_path = framework_rel_path + ".dSYM"
256
+ PodBuilder::safe_rm_rf(PodBuilder::prebuiltpath(prebuilt_name))
257
+ FileUtils.cp_r(source_path, PodBuilder::prebuiltpath)
258
+ end
246
259
 
247
- PodBuilder::safe_rm_rf(PodBuilder::prebuiltpath(framework_rel_path))
248
- Configuration.supported_platforms.each do |platform|
249
- PodBuilder::safe_rm_rf(PodBuilder::dsympath("#{platform}/#{dsym_path}"))
250
- end
260
+ # Folder won't exist if no dSYM were generated (all static libs)
261
+ if File.directory?(PodBuilder::buildpath_dsympath)
262
+ FileUtils.mkdir_p(PodBuilder::dsympath)
263
+ FileUtils.cp_r(PodBuilder::buildpath_dsympath, PodBuilder::basepath)
251
264
  end
252
265
  end
253
266
 
254
- def self.copy_frameworks(podfile_items)
255
- Dir.glob(PodBuilder::buildpath_prebuiltpath("*.framework")) do |framework_path|
256
- framework_rel_path = rel_path(framework_path, podfile_items)
267
+ def self.add_prebuilt_info_file(podfile_items)
268
+ swift_version = PodBuilder::system_swift_version
257
269
 
258
- destination_path = PodBuilder::prebuiltpath(framework_rel_path)
259
- FileUtils.mkdir_p(File.dirname(destination_path))
260
- FileUtils.cp_r(framework_path, destination_path)
261
- end
262
- end
270
+ root_names = podfile_items.reject(&:is_prebuilt).map(&:root_name).uniq
271
+ root_names.each do |prebuilt_name|
272
+ path = PodBuilder::prebuiltpath(prebuilt_name)
263
273
 
264
- def self.copy_libraries(podfile_items)
265
- Dir.glob(PodBuilder::buildpath_prebuiltpath("*.a")) do |library_path|
266
- library_name = File.basename(library_path)
267
-
268
- # Find vendored libraries in the build folder:
269
- # This allows to determine which Pod is associated to the vendored_library
270
- # because there are cases where vendored_libraries are specified with wildcards (*.a)
271
- # making it impossible to determine the associated Pods when building multiple pods at once
272
- search_base = "#{Configuration.build_path}/Pods/"
273
- podfile_items.each do |podfile_item|
274
- if podfile_item.vendored_framework_path.nil?
275
- next
276
- end
277
-
278
- podfile_item.vendored_libraries.each do |vendored_item|
279
- if result = Dir.glob("#{search_base}**/#{vendored_item}").first
280
- result_path = result.gsub(search_base, "")
281
- module_name = result_path.split("/").first
282
- if module_name == podfile_item.module_name
283
- library_rel_path = rel_path(module_name, podfile_items)
284
-
285
- result_path = result_path.split("/").drop(1).join("/")
286
-
287
- destination_path = PodBuilder::prebuiltpath("#{library_rel_path}/#{result_path}")
288
- FileUtils.mkdir_p(File.dirname(destination_path))
289
- FileUtils.cp_r(library_path, destination_path, :remove_destination => true)
290
- end
291
- end
292
- end
274
+ unless File.directory?(path)
275
+ puts "Prebuilt items for #{prebuilt_name} not found".blue
276
+ next
277
+ end
293
278
 
294
- # A pod might depend upon a static library that is shipped with a prebuilt framework
295
- # which is not added to the Rome folder and podspecs
296
- #
297
- # An example is Google-Mobile-Ads-SDK which adds
298
- # - vendored framework: GooleMobileAds.framework
299
- # - vendored library: libGooleMobileAds.a
300
- # These might be used by another pod (e.g AppNexusSDK/GoogleAdapterThatDependsOnGooglePod)
301
- podfile_item.libraries.each do |library|
302
- if result = Dir.glob("#{search_base}**/lib#{library}.a").first
303
- result_path = result.gsub(search_base, "")
304
-
305
- library_rel_path = rel_path(podfile_item.module_name, podfile_items)
306
-
307
- result_path = result_path.split("/").drop(1).join("/")
308
-
309
- destination_path = PodBuilder::prebuiltpath("#{library_rel_path}/#{result_path}")
310
- FileUtils.mkdir_p(File.dirname(destination_path))
311
- FileUtils.cp_r(library_path, destination_path)
312
- end
313
- end
279
+ unless podfile_item = podfile_items.detect { |t| t.name == prebuilt_name } || podfile_items.detect { |t| t.root_name == prebuilt_name }
280
+ puts "Prebuilt items for #{prebuilt_name} not found #2".blue
281
+ next
314
282
  end
315
- end
316
- end
317
283
 
318
- def self.copy_dsyms(podfile_items)
319
- Configuration.supported_platforms.each do |platform|
320
- Dir.glob("#{Configuration.build_path}/dSYM/#{platform}/**/*.dSYM") do |dsym_path|
321
- framework_rel_path = rel_path(dsym_path.gsub(File.extname(dsym_path), ""), podfile_items)
322
-
323
- destination_path = PodBuilder::dsympath("#{platform}/#{File.dirname(framework_rel_path)}")
324
- FileUtils.mkdir_p(destination_path)
325
- FileUtils.cp_r(dsym_path, destination_path)
326
- end
284
+ podbuilder_file = File.join(path, Configuration.prebuilt_info_filename)
285
+ entry = podfile_item.entry(true, false)
286
+
287
+ data = {}
288
+ data['entry'] = entry
289
+ data['is_prebuilt'] = podfile_item.is_prebuilt
290
+ if Dir.glob(File.join(path, "#{podfile_item.module_name}/Headers/*-Swift.h")).count > 0
291
+ data['swift_version'] = swift_version
292
+ end
293
+
294
+ specs = podfile_items.select { |x| x.module_name == podfile_item.module_name }
295
+ subspecs_deps = specs.map(&:dependency_names).flatten
296
+ subspec_self_deps = subspecs_deps.select { |x| x.start_with?("#{prebuilt_name}/") }
297
+ data['specs'] = (specs.map(&:name) + subspec_self_deps).uniq
298
+ data['is_static'] = podfile_item.is_static
299
+ data['original_compile_path'] = Pathname.new(Configuration.build_path).realpath.to_s
300
+ data['build_folder_hash'] = build_folder_hash(podfile_item)
301
+
302
+ File.write(podbuilder_file, JSON.pretty_generate(data))
327
303
  end
328
304
  end
329
305
 
@@ -335,17 +311,15 @@ module PodBuilder
335
311
  Dir.chdir(current_dir)
336
312
  end
337
313
 
338
- def self.build_folder_hash_in_framework_plist_info(framework_path)
339
- podbuilder_file = File.join(framework_path, Configuration.framework_plist_filename)
314
+ def self.build_folder_hash_in_prebuilt_info_file(podfile_item)
315
+ prebuilt_info_path = PodBuilder::prebuiltpath(File.join(podfile_item.root_name, Configuration.prebuilt_info_filename))
340
316
 
341
- unless File.exist?(podbuilder_file)
317
+ if File.exist?(prebuilt_info_path)
318
+ data = JSON.parse(File.read(prebuilt_info_path))
319
+ return data['build_folder_hash']
320
+ else
342
321
  return nil
343
322
  end
344
-
345
- plist = CFPropertyList::List.new(:file => podbuilder_file)
346
- data = CFPropertyList.native_types(plist.value)
347
-
348
- return data['build_folder_hash']
349
323
  end
350
324
 
351
325
  def self.build_folder_hash(podfile_item)
@@ -359,7 +333,27 @@ module PodBuilder
359
333
  item_path = "#{Configuration.build_path}/Pods/#{podfile_item.root_name}"
360
334
  end
361
335
 
362
- return `find '#{item_path}' -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum | cut -d' ' -f1`.strip()
336
+ return `find '#{item_path}' -type f -print0 | sort -z | xargs -0 shasum | shasum | cut -d' ' -f1`.strip()
363
337
  end
338
+
339
+ def self.podfile_path_transform(path)
340
+ if Configuration.build_using_repo_paths
341
+ return File.expand_path(PodBuilder::basepath(path))
342
+ else
343
+ use_absolute_paths = true
344
+ podfile_path = File.join(Configuration.build_path, "Podfile")
345
+ original_basepath = PodBuilder::basepath
346
+
347
+ podfile_base_path = Pathname.new(File.dirname(podfile_path))
348
+
349
+ original_path = Pathname.new(File.join(original_basepath, path))
350
+ replace_path = original_path.relative_path_from(podfile_base_path)
351
+ if use_absolute_paths
352
+ replace_path = replace_path.expand_path(podfile_base_path)
353
+ end
354
+
355
+ return replace_path
356
+ end
357
+ end
364
358
  end
365
359
  end