pod-builder-y 2.3.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.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/Gemfile +8 -0
  4. data/LICENSE.txt +13 -0
  5. data/README.md +385 -0
  6. data/Rakefile +2 -0
  7. data/bin/console +16 -0
  8. data/bin/setup +8 -0
  9. data/exe/pod_builder_y +406 -0
  10. data/lib/core_ext/string.rb +5 -0
  11. data/lib/pod_builder/analyze.rb +59 -0
  12. data/lib/pod_builder/analyzer.rb +16 -0
  13. data/lib/pod_builder/command.rb +14 -0
  14. data/lib/pod_builder/command/build.rb +228 -0
  15. data/lib/pod_builder/command/build_all.rb +15 -0
  16. data/lib/pod_builder/command/clean.rb +75 -0
  17. data/lib/pod_builder/command/deintegrate.rb +101 -0
  18. data/lib/pod_builder/command/generate_lldbinit.rb +128 -0
  19. data/lib/pod_builder/command/generate_podspec.rb +22 -0
  20. data/lib/pod_builder/command/info.rb +18 -0
  21. data/lib/pod_builder/command/init.rb +148 -0
  22. data/lib/pod_builder/command/install_sources.rb +79 -0
  23. data/lib/pod_builder/command/none.rb +16 -0
  24. data/lib/pod_builder/command/restore_all.rb +33 -0
  25. data/lib/pod_builder/command/switch.rb +224 -0
  26. data/lib/pod_builder/command/sync_podfile.rb +34 -0
  27. data/lib/pod_builder/command/update.rb +43 -0
  28. data/lib/pod_builder/configuration.rb +300 -0
  29. data/lib/pod_builder/core.rb +222 -0
  30. data/lib/pod_builder/info.rb +90 -0
  31. data/lib/pod_builder/install.rb +505 -0
  32. data/lib/pod_builder/licenses.rb +73 -0
  33. data/lib/pod_builder/podfile.rb +700 -0
  34. data/lib/pod_builder/podfile/pre_actions_swizzles.rb +84 -0
  35. data/lib/pod_builder/podfile_cp.rb +99 -0
  36. data/lib/pod_builder/podfile_item.rb +530 -0
  37. data/lib/pod_builder/podspec.rb +269 -0
  38. data/lib/pod_builder/rome/post_install.rb +446 -0
  39. data/lib/pod_builder/rome/pre_install.rb +6 -0
  40. data/lib/pod_builder/templates/build_podfile.template +70 -0
  41. data/lib/pod_builder/templates/build_podspec.template +19 -0
  42. data/lib/pod_builder/version.rb +4 -0
  43. data/pod-builder.gemspec +37 -0
  44. metadata +240 -0
@@ -0,0 +1,16 @@
1
+ require 'cocoapods/installer/analyzer.rb'
2
+
3
+ module Pod
4
+ class Installer
5
+ class Analyzer
6
+ def explicit_pods
7
+ pods = []
8
+ podfile.root_target_definitions[0].children.each do |children|
9
+ pods += children.dependencies
10
+ end
11
+
12
+ pods.flatten.uniq.sort
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ require 'pod_builder/command/none'
2
+ require 'pod_builder/command/build'
3
+ require 'pod_builder/command/build_all'
4
+ require 'pod_builder/command/update'
5
+ require 'pod_builder/command/restore_all'
6
+ require 'pod_builder/command/init'
7
+ require 'pod_builder/command/clean'
8
+ require 'pod_builder/command/deintegrate'
9
+ require 'pod_builder/command/generate_podspec'
10
+ require 'pod_builder/command/install_sources'
11
+ require 'pod_builder/command/switch'
12
+ require 'pod_builder/command/sync_podfile'
13
+ require 'pod_builder/command/info'
14
+ require 'pod_builder/command/generate_lldbinit'
@@ -0,0 +1,228 @@
1
+ require 'pod_builder/core'
2
+
3
+ module PodBuilder
4
+ module Command
5
+ class Build
6
+ def self.call
7
+ Configuration.check_inited
8
+ PodBuilder::prepare_basepath
9
+
10
+ argument_pods = ARGV.dup
11
+
12
+ unless argument_pods.count > 0
13
+ return -1
14
+ end
15
+
16
+ raise "\n\nPlease rename your Xcode installation path removing spaces, current `#{`xcode-select -p`.strip()}`\n".red if `xcode-select -p`.strip().include?(" ")
17
+
18
+ Podfile.sanity_check()
19
+ check_not_building_subspecs(argument_pods)
20
+
21
+ puts "Loading Podfile".yellow
22
+
23
+ install_update_repo = OPTIONS.fetch(:update_repos, true)
24
+ installer, analyzer = Analyze.installer_at(PodBuilder::basepath, install_update_repo)
25
+
26
+ all_buildable_items = Analyze.podfile_items(installer, analyzer)
27
+ prebuilt_items = all_buildable_items.select { |x| x.is_prebuilt }
28
+ buildable_items = all_buildable_items - prebuilt_items
29
+
30
+ build_all = argument_pods.first == "*"
31
+ if build_all
32
+ argument_pods = all_buildable_items.map(&:root_name).uniq
33
+ else
34
+ argument_pods = Podfile::resolve_pod_names(argument_pods, all_buildable_items)
35
+ deps = all_buildable_items.select { |t| argument_pods.include?(t.root_name) }.map(&:dependency_names).flatten.map { |t| t.split("/").first }
36
+ argument_pods += deps
37
+ argument_pods.uniq!
38
+ end
39
+
40
+ available_argument_pods = argument_pods.select { |x| all_buildable_items.map(&:root_name).include?(x) }
41
+ (argument_pods - available_argument_pods).each { |x|
42
+ puts "'#{x}' not found, skipping".magenta
43
+ }
44
+ argument_pods = available_argument_pods.uniq
45
+
46
+ prebuilt_pods_to_install = prebuilt_items.select { |x| argument_pods.include?(x.root_name) }
47
+
48
+ Podfile.restore_podfile_clean(all_buildable_items)
49
+
50
+ restore_file_error = Podfile.restore_file_sanity_check
51
+
52
+ check_pods_exists(argument_pods, all_buildable_items)
53
+
54
+ pods_to_build = resolve_pods_to_build(argument_pods, buildable_items)
55
+ buildable_items -= pods_to_build
56
+
57
+ # We need to split pods to build in 3 groups
58
+ # 1. pods to build in release
59
+ # 2. pods to build in debug
60
+
61
+ check_not_building_development_pods(pods_to_build)
62
+
63
+ pods_to_build_debug = pods_to_build.select { |x| x.build_configuration == "debug" }
64
+ pods_to_build_release = pods_to_build - pods_to_build_debug
65
+
66
+ check_dependencies_build_configurations(all_buildable_items)
67
+
68
+ podfiles_items = [pods_to_build_debug] + [pods_to_build_release]
69
+
70
+ install_using_frameworks = Podfile::install_using_frameworks(analyzer)
71
+ if Configuration.react_native_project
72
+ if install_using_frameworks
73
+ raise "\n\nOnly static library packaging currently supported for react native projects. Please remove 'use_frameworks!' in #{PodBuilder::basepath("Podfile")}".red
74
+ end
75
+ prepare_defines_modules_override(all_buildable_items)
76
+ else
77
+ unless install_using_frameworks
78
+ raise "\n\nOnly framework packaging currently supported. Please add 'use_frameworks!' at root level (not nested in targets) in #{PodBuilder::basepath("Podfile")}".red
79
+ end
80
+ end
81
+
82
+ build_catalyst = should_build_catalyst(installer)
83
+
84
+ install_result = InstallResult.new
85
+ podfiles_items.reject { |x| x.empty? }.each do |podfile_items|
86
+ build_configuration = podfile_items.map(&:build_configuration).uniq.first
87
+
88
+ podfile_items = podfile_items.map { |t| t.recursive_dependencies(all_buildable_items) }.flatten.uniq
89
+ podfile_content = Podfile.from_podfile_items(podfile_items, analyzer, build_configuration, install_using_frameworks, build_catalyst, Configuration.build_xcframeworks)
90
+
91
+ install_result += Install.podfile(podfile_content, podfile_items, podfile_items.first.build_configuration)
92
+
93
+ FileUtils.rm_f(PodBuilder::basepath("Podfile.lock"))
94
+ end
95
+
96
+ install_result.write_prebuilt_info_files
97
+
98
+ Clean::prebuilt_items(all_buildable_items)
99
+
100
+ Licenses::write(install_result.licenses, all_buildable_items)
101
+
102
+ Podspec::generate(all_buildable_items, analyzer, install_using_frameworks)
103
+
104
+ builded_pods = podfiles_items.flatten
105
+
106
+ builded_pods_and_deps = podfiles_items.flatten.map { |t| t.recursive_dependencies(all_buildable_items) }.flatten.uniq
107
+ builded_pods_and_deps.select! { |x| !x.is_prebuilt }
108
+
109
+ Podfile::write_restorable(builded_pods_and_deps + prebuilt_pods_to_install, all_buildable_items, analyzer)
110
+ if !OPTIONS.has_key?(:skip_prebuild_update)
111
+ Podfile::write_prebuilt(all_buildable_items, analyzer)
112
+ end
113
+
114
+ Podfile::install
115
+
116
+ sanity_checks
117
+
118
+ if (restore_file_error = restore_file_error) && Configuration.restore_enabled
119
+ puts "\n\n⚠️ Podfile.restore was found invalid and was overwritten. Error:\n #{restore_file_error}".red
120
+ end
121
+
122
+ puts "\n\n🎉 done!\n".green
123
+ return 0
124
+ end
125
+
126
+ private
127
+
128
+ def self.should_build_catalyst(installer)
129
+ build_settings = installer.analysis_result.targets.map { |t| t.user_project.root_object.targets.map { |u| u.build_configuration_list.build_configurations.map { |v| v.build_settings } } }.flatten
130
+ build_catalyst = build_settings.detect { |t| t["SUPPORTS_MACCATALYST"] == "YES" } != nil
131
+
132
+ puts "\nTo support Catalyst you should enable 'build_xcframeworks' in PodBuilder.json\n".red if build_catalyst && !Configuration.build_xcframeworks
133
+
134
+ return build_catalyst
135
+ end
136
+
137
+ def self.prepare_defines_modules_override(all_buildable_items)
138
+ all_buildable_items.each do |item|
139
+ unless item.defines_module.nil?
140
+ Pod::PodTarget.modules_override[item.root_name] = item.defines_module
141
+ end
142
+ end
143
+ end
144
+
145
+ def self.check_not_building_subspecs(pods_to_build)
146
+ pods_to_build.each do |pod_to_build|
147
+ if pod_to_build.include?("/")
148
+ raise "\n\nCan't build subspec #{pod_to_build} refer to podspec name.\n\nUse `pod_builder build #{pods_to_build.map { |x| x.split("/").first }.uniq.join(" ")}` instead\n\n".red
149
+ end
150
+ end
151
+ end
152
+
153
+ def self.check_pods_exists(pods, buildable_items)
154
+ raise "\n\nEmpty Podfile?".red if buildable_items.nil?
155
+
156
+ buildable_items = buildable_items.map(&:root_name)
157
+ pods.each do |pod|
158
+ raise "\n\nPod `#{pod}` wasn't found in Podfile.\n\nFound:\n#{buildable_items.join("\n")}\n\n".red if !buildable_items.include?(pod)
159
+ end
160
+ end
161
+
162
+ def self.check_dependencies_build_configurations(pods)
163
+ pods.each do |pod|
164
+ pod_dependency_names = pod.dependency_names.select { |x| !pod.has_common_spec(x) }
165
+
166
+ remaining_pods = pods - [pod]
167
+ pods_with_common_deps = remaining_pods.select { |x| x.dependency_names.any? { |y| pod_dependency_names.include?(y) && !x.has_common_spec(y) } }
168
+
169
+ pods_with_unaligned_build_configuration = pods_with_common_deps.select { |x| x.build_configuration != pod.build_configuration }
170
+ pods_with_unaligned_build_configuration.map!(&:name)
171
+
172
+ raise "\n\nDependencies of `#{pod.name}` don't have the same build configuration (#{pod.build_configuration}) of `#{pods_with_unaligned_build_configuration.join(",")}`'s dependencies".red if pods_with_unaligned_build_configuration.count > 0
173
+ end
174
+ end
175
+
176
+ def self.check_not_building_development_pods(pods)
177
+ if (development_pods = pods.select { |x| x.is_development_pod }) && development_pods.count > 0 && (OPTIONS[:allow_warnings].nil? && Configuration.allow_building_development_pods == false && Configuration.react_native_project == false)
178
+ pod_names = development_pods.map(&:name).join(", ")
179
+ raise "\n\nThe following pods are in development mode: `#{pod_names}`, won't proceed building.\n\nYou can ignore this error by passing the `--allow-warnings` flag to the build command\n".red
180
+ end
181
+ end
182
+
183
+ def self.other_subspecs(pods_to_build, buildable_items)
184
+ buildable_subspecs = buildable_items.select { |x| x.is_subspec }
185
+ pods_to_build_subspecs = pods_to_build.select { |x| x.is_subspec }.map(&:root_name)
186
+
187
+ buildable_subspecs.select! { |x| pods_to_build_subspecs.include?(x.root_name) }
188
+
189
+ return buildable_subspecs - pods_to_build
190
+ end
191
+
192
+ def self.sanity_checks
193
+ lines = File.read(PodBuilder::project_path("Podfile")).split("\n")
194
+ stripped_lines = lines.map { |x| Podfile.strip_line(x) }.select { |x| !x.start_with?("#")}
195
+
196
+ expected_stripped = Podfile::PRE_INSTALL_ACTIONS.map { |x| Podfile.strip_line(x) }
197
+
198
+ if !expected_stripped.all? { |x| stripped_lines.include?(x) }
199
+ warn_message = "PodBuilder's pre install actions missing from application Podfile!\n"
200
+ if OPTIONS[:allow_warnings]
201
+ puts "\n\n#{warn_message}".yellow
202
+ else
203
+ raise "\n\n#{warn_message}".red
204
+ end
205
+ end
206
+ end
207
+
208
+ def self.resolve_pods_to_build(argument_pods, buildable_items)
209
+ pods_to_build = []
210
+
211
+ pods_to_build = buildable_items.select { |x| argument_pods.include?(x.root_name) }
212
+ pods_to_build += other_subspecs(pods_to_build, buildable_items)
213
+
214
+ if OPTIONS[:resolve_parent_dependencies]
215
+ dependencies = []
216
+ buildable_items.each do |pod|
217
+ if !(pod.dependencies(buildable_items) & pods_to_build).empty?
218
+ dependencies.push(pod)
219
+ end
220
+ end
221
+ pods_to_build += dependencies
222
+ end
223
+
224
+ return pods_to_build.uniq
225
+ end
226
+ end
227
+ end
228
+ end
@@ -0,0 +1,15 @@
1
+ require 'pod_builder/core'
2
+
3
+ module PodBuilder
4
+ module Command
5
+ class BuildAll
6
+ def self.call
7
+ Configuration.check_inited
8
+ PodBuilder::prepare_basepath
9
+
10
+ ARGV << "*"
11
+ return Command::Build::call
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,75 @@
1
+ require 'pod_builder/core'
2
+ require 'highline/import'
3
+
4
+ module PodBuilder
5
+ module Command
6
+ class Clean
7
+ def self.call
8
+ Configuration.check_inited
9
+ PodBuilder::prepare_basepath
10
+
11
+ install_update_repo = OPTIONS.fetch(:update_repos, true)
12
+ installer, analyzer = Analyze.installer_at(PodBuilder::basepath, install_update_repo)
13
+ all_buildable_items = Analyze.podfile_items(installer, analyzer)
14
+
15
+ prebuilt_items(all_buildable_items)
16
+ install_sources(all_buildable_items)
17
+
18
+ puts "\n\n🎉 done!\n".green
19
+ return 0
20
+ end
21
+
22
+ def self.prebuilt_items(buildable_items)
23
+ puts "Cleaning prebuilt folder".yellow
24
+
25
+ root_names = buildable_items.map(&:root_name).uniq
26
+ Dir.glob(PodBuilder::prebuiltpath("*")).each do |path|
27
+ basename = File.basename(path)
28
+ unless root_names.include?(basename)
29
+ puts "Cleanining up `#{basename}`, no longer found among dependencies".blue
30
+ PodBuilder::safe_rm_rf(path)
31
+ end
32
+ end
33
+
34
+ puts "Cleaning dSYM folder".yellow
35
+ module_names = buildable_items.map(&:module_name).uniq
36
+ Dir.glob(File.join(PodBuilder::dsympath, "**/*.dSYM")).each do |path|
37
+ dsym_basename = File.basename(path, ".*")
38
+ dsym_basename.gsub!(/\.framework$/, "")
39
+ unless module_names.include?(dsym_basename)
40
+ puts "Cleanining up `#{dsym_basename}`, no longer found among dependencies".blue
41
+ PodBuilder::safe_rm_rf(path)
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ def self.install_sources(buildable_items)
48
+ puts "Looking for unused sources".yellow
49
+
50
+ podspec_names = buildable_items.map(&:root_name).uniq
51
+
52
+ base_path = PodBuilder::basepath("Sources")
53
+
54
+ paths_to_delete = []
55
+ repo_paths = Dir.glob("#{base_path}/*")
56
+ repo_paths.each do |path|
57
+ podspec_name = File.basename(path)
58
+
59
+ if podspec_names.include?(podspec_name)
60
+ next
61
+ end
62
+
63
+ paths_to_delete.push(path)
64
+ end
65
+
66
+ paths_to_delete.flatten.each do |path|
67
+ confirm = ask("#{path} unused.\nDelete it? [Y/N] ") { |yn| yn.limit = 1, yn.validate = /[yn]/i }
68
+ if confirm.downcase == 'y' || OPTIONS.has_key?(:no_stdin_available)
69
+ PodBuilder::safe_rm_rf(path)
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,101 @@
1
+ require 'pod_builder/core'
2
+
3
+ module PodBuilder
4
+ module Command
5
+ class Deintegrate
6
+ def self.call
7
+ raise "\n\nPodBuilder not initialized!\n".red if !Configuration.exists
8
+
9
+ prebuilt_podfile = PodBuilder::basepath("Podfile")
10
+ restored_podfile = PodBuilder::project_path("Podfile")
11
+
12
+ FileUtils.cp(prebuilt_podfile, restored_podfile)
13
+
14
+ podfile_content = File.read(restored_podfile)
15
+ podfile_lines = []
16
+ pre_install_indx = -1
17
+ podfile_content.each_line.with_index do |line, index|
18
+ if Podfile::PODBUILDER_LOCK_ACTION.detect { |x| Podfile::strip_line(x) == Podfile::strip_line(line) }
19
+ if pre_install_indx == -1
20
+ pre_install_indx = index
21
+ end
22
+ else
23
+ podfile_lines.push(line)
24
+ end
25
+ end
26
+
27
+ if pre_install_indx > 0 &&
28
+ Podfile::strip_line(podfile_lines[pre_install_indx - 1]).include?("pre_installdo|") &&
29
+ Podfile::strip_line(podfile_lines[pre_install_indx]) == "end"
30
+ podfile_lines.delete_at(pre_install_indx)
31
+ podfile_lines.delete_at(pre_install_indx - 1)
32
+ end
33
+
34
+ FileUtils.rm_f(restored_podfile)
35
+
36
+ podfile_content = podfile_lines.join
37
+
38
+ podfile_content = Podfile.update_path_entries(podfile_content, Deintegrate.method(:podfile_path_transform))
39
+ podfile_content = Podfile.update_project_entries(podfile_content, Deintegrate.method(:podfile_path_transform))
40
+ podfile_content = Podfile.update_require_entries(podfile_content, Deintegrate.method(:podfile_path_transform))
41
+
42
+ File.write(restored_podfile, podfile_content)
43
+
44
+ PodBuilder::safe_rm_rf(Configuration.base_path)
45
+
46
+ Dir.chdir(PodBuilder::project_path)
47
+ bundler_prefix = Configuration.use_bundler ? "bundle exec " : ""
48
+ system("#{bundler_prefix}pod install;")
49
+
50
+ license_base = PodBuilder::project_path(Configuration.license_filename)
51
+ FileUtils.rm_f("#{license_base}.plist")
52
+ FileUtils.rm_f("#{license_base}.md")
53
+
54
+ update_gemfile
55
+
56
+ puts "\n\n🎉 done!\n".green
57
+ return 0
58
+ end
59
+
60
+ private
61
+
62
+ def self.podfile_path_transform(path)
63
+ use_absolute_paths = false
64
+ podfile_path = PodBuilder::project_path("Podfile")
65
+ original_basepath = PodBuilder::basepath
66
+
67
+ podfile_base_path = Pathname.new(File.dirname(podfile_path))
68
+
69
+ original_path = Pathname.new(File.join(original_basepath, path))
70
+ replace_path = original_path.relative_path_from(podfile_base_path)
71
+ if use_absolute_paths
72
+ replace_path = replace_path.expand_path(podfile_base_path)
73
+ end
74
+
75
+ return replace_path
76
+ end
77
+
78
+ def self.update_gemfile
79
+ gemfile_path = File.join(PodBuilder::home, "Gemfile")
80
+ unless File.exist?(gemfile_path)
81
+ FileUtils.touch(gemfile_path)
82
+ end
83
+
84
+ podbuilder_line = "gem 'pod-builder'"
85
+
86
+ gemfile = File.read(gemfile_path)
87
+
88
+ gemfile_lines = gemfile.split("\n")
89
+ gemfile_lines.select! { |x| !trim_gemfile_line(x).include?(trim_gemfile_line(podbuilder_line)) }
90
+ File.write(gemfile_path, gemfile_lines.join("\n"))
91
+
92
+ Dir.chdir(PodBuilder::home)
93
+ system("bundle")
94
+ end
95
+
96
+ def self.trim_gemfile_line(line)
97
+ return line.gsub("\"", "'").gsub(" ", "")
98
+ end
99
+ end
100
+ end
101
+ end