pod-builder 2.0.0.beta.22 ā 2.0.0.beta.27
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 +4 -4
- data/README.md +10 -22
- data/exe/pod_builder +12 -34
- data/lib/pod_builder/command.rb +1 -3
- data/lib/pod_builder/command/build.rb +62 -15
- data/lib/pod_builder/command/clean.rb +14 -1
- data/lib/pod_builder/command/generate_lldbinit.rb +151 -0
- data/lib/pod_builder/command/generate_podspec.rb +3 -1
- data/lib/pod_builder/command/init.rb +26 -12
- data/lib/pod_builder/command/install_sources.rb +2 -2
- data/lib/pod_builder/configuration.rb +22 -22
- data/lib/pod_builder/core.rb +17 -7
- data/lib/pod_builder/install.rb +291 -120
- data/lib/pod_builder/podfile.rb +23 -7
- data/lib/pod_builder/podfile_cp.rb +11 -5
- data/lib/pod_builder/podfile_item.rb +33 -39
- data/lib/pod_builder/podspec.rb +82 -29
- data/lib/pod_builder/rome/post_install.rb +169 -42
- data/lib/pod_builder/templates/build_podfile.template +1 -1
- data/lib/pod_builder/version.rb +1 -1
- metadata +3 -5
- data/lib/pod_builder/command/clear_lldbinit.rb +0 -48
- data/lib/pod_builder/command/generate_lfs.rb +0 -70
- data/lib/pod_builder/command/update_lldbinit.rb +0 -162
@@ -10,7 +10,9 @@ module PodBuilder
|
|
10
10
|
installer, analyzer = Analyze.installer_at(PodBuilder::basepath, false)
|
11
11
|
all_buildable_items = Analyze.podfile_items(installer, analyzer)
|
12
12
|
|
13
|
-
|
13
|
+
install_using_frameworks = Podfile::install_using_frameworks(analyzer)
|
14
|
+
|
15
|
+
Podspec::generate(all_buildable_items, analyzer, install_using_frameworks)
|
14
16
|
|
15
17
|
puts "\n\nš done!\n".green
|
16
18
|
return 0
|
@@ -22,17 +22,8 @@ module PodBuilder
|
|
22
22
|
FileUtils.mkdir_p("#{OPTIONS[:prebuild_path]}/.pod_builder")
|
23
23
|
FileUtils.touch("#{OPTIONS[:prebuild_path]}/.pod_builder/pod_builder")
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
git_ignores = ["Pods/",
|
29
|
-
"*.xcworkspace",
|
30
|
-
"*.xcodeproj",
|
31
|
-
"Podfile.lock",
|
32
|
-
source_path_rel_path,
|
33
|
-
development_pods_config_rel_path]
|
34
|
-
|
35
|
-
File.write("#{OPTIONS[:prebuild_path]}/.gitignore", git_ignores.join("\n"))
|
25
|
+
write_gitignore
|
26
|
+
write_gitattributes
|
36
27
|
|
37
28
|
project_podfile_path = PodBuilder::project_path("Podfile")
|
38
29
|
prebuilt_podfile_path = File.join(OPTIONS[:prebuild_path], "Podfile")
|
@@ -45,7 +36,9 @@ module PodBuilder
|
|
45
36
|
podfile_content = Podfile.update_project_entries(podfile_content, Init.method(:podfile_path_transform))
|
46
37
|
podfile_content = Podfile.update_require_entries(podfile_content, Init.method(:podfile_path_transform))
|
47
38
|
|
48
|
-
podfile_content
|
39
|
+
if podfile_content.include?("/node_modules/react-native/")
|
40
|
+
podfile_content = Podfile.prepare_for_react_native(podfile_content)
|
41
|
+
end
|
49
42
|
|
50
43
|
File.write(prebuilt_podfile_path, podfile_content)
|
51
44
|
|
@@ -59,6 +52,27 @@ module PodBuilder
|
|
59
52
|
|
60
53
|
private
|
61
54
|
|
55
|
+
def self.write_gitignore
|
56
|
+
source_path_rel_path = "Sources"
|
57
|
+
development_pods_config_rel_path = Configuration.dev_pods_configuration_filename
|
58
|
+
|
59
|
+
git_ignores = ["Pods/",
|
60
|
+
"*.xcworkspace",
|
61
|
+
"*.xcodeproj",
|
62
|
+
"Podfile.lock",
|
63
|
+
Configuration.lldbinit_name,
|
64
|
+
source_path_rel_path,
|
65
|
+
development_pods_config_rel_path]
|
66
|
+
|
67
|
+
File.write("#{OPTIONS[:prebuild_path]}/.gitignore", git_ignores.join("\n"))
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.write_gitattributes
|
71
|
+
git_attributes = ["#{Configuration.prebuilt_info_filename} binary"]
|
72
|
+
|
73
|
+
File.write("#{OPTIONS[:prebuild_path]}/.gitattributes", git_attributes.join("\n"))
|
74
|
+
end
|
75
|
+
|
62
76
|
def self.podfile_path_transform(path)
|
63
77
|
use_absolute_paths = false
|
64
78
|
podfile_path = File.join(OPTIONS[:prebuild_path], "Podfile")
|
@@ -22,12 +22,12 @@ module PodBuilder
|
|
22
22
|
framework_files.each do |path|
|
23
23
|
rel_path = Pathname.new(path).relative_path_from(Pathname.new(base_path)).to_s
|
24
24
|
|
25
|
-
if podfile_spec = podfile_items.detect { |x| x.prebuilt_rel_path == rel_path }
|
25
|
+
if podfile_spec = podfile_items.detect { |x| "#{x.root_name}/#{x.prebuilt_rel_path}" == rel_path }
|
26
26
|
update_repo(podfile_spec)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
|
30
|
+
Clean::install_sources(podfile_items)
|
31
31
|
|
32
32
|
ARGV << PodBuilder::basepath("Sources")
|
33
33
|
|
@@ -17,13 +17,30 @@ module PodBuilder
|
|
17
17
|
DEFAULT_SPEC_OVERRIDE = {
|
18
18
|
"Google-Mobile-Ads-SDK" => {
|
19
19
|
"module_name": "GoogleMobileAds"
|
20
|
+
},
|
21
|
+
"React-jsiexecutor" => {
|
22
|
+
"remove_module_maps": ["glog"]
|
23
|
+
},
|
24
|
+
"React-Core" => {
|
25
|
+
"remove_module_maps": ["glog"]
|
26
|
+
},
|
27
|
+
"React-Core/Default" => {
|
28
|
+
"public_headers": "React/**/*.{h}"
|
29
|
+
},
|
30
|
+
"React-jsi" => {
|
31
|
+
"remove_module_maps": ["glog"]
|
32
|
+
},
|
33
|
+
"React-cxxreact" => {
|
34
|
+
"remove_module_maps": ["glog"]
|
35
|
+
},
|
36
|
+
"Folly" => {
|
37
|
+
"remove_module_maps": ["glog"]
|
20
38
|
}
|
21
39
|
}.freeze
|
22
|
-
DEFAULT_SKIP_PODS = ["GoogleMaps"
|
23
|
-
DEFAULT_FORCE_PREBUILD_PODS = ["
|
40
|
+
DEFAULT_SKIP_PODS = ["GoogleMaps"]
|
41
|
+
DEFAULT_FORCE_PREBUILD_PODS = ["GoogleTagManager"]
|
24
42
|
DEFAULT_BUILD_SYSTEM = "Legacy".freeze # either Latest (New build system) or Legacy (Standard build system)
|
25
43
|
DEFAULT_LIBRARY_EVOLUTION_SUPPORT = false
|
26
|
-
MIN_LFS_SIZE_KB = 256.freeze
|
27
44
|
DEFAULT_PLATFORMS = ["iphoneos", "iphonesimulator", "appletvos", "appletvsimulator"].freeze
|
28
45
|
DEFAULT_BUILD_FOR_APPLE_SILICON = false
|
29
46
|
DEFAULT_BUILD_USING_REPO_PATHS = false
|
@@ -31,7 +48,6 @@ module PodBuilder
|
|
31
48
|
private_constant :DEFAULT_BUILD_SETTINGS
|
32
49
|
private_constant :DEFAULT_BUILD_SYSTEM
|
33
50
|
private_constant :DEFAULT_LIBRARY_EVOLUTION_SUPPORT
|
34
|
-
private_constant :MIN_LFS_SIZE_KB
|
35
51
|
|
36
52
|
class <<self
|
37
53
|
attr_accessor :allow_building_development_pods
|
@@ -51,9 +67,6 @@ module PodBuilder
|
|
51
67
|
attr_accessor :build_path
|
52
68
|
attr_accessor :configuration_filename
|
53
69
|
attr_accessor :dev_pods_configuration_filename
|
54
|
-
attr_accessor :lfs_min_file_size
|
55
|
-
attr_accessor :lfs_update_gitattributes
|
56
|
-
attr_accessor :lfs_include_pods_folder
|
57
70
|
attr_accessor :project_name
|
58
71
|
attr_accessor :restore_enabled
|
59
72
|
attr_accessor :prebuilt_info_filename
|
@@ -65,6 +78,7 @@ module PodBuilder
|
|
65
78
|
attr_accessor :build_for_apple_silicon
|
66
79
|
attr_accessor :build_using_repo_paths
|
67
80
|
attr_accessor :react_native_project
|
81
|
+
attr_accessor :lldbinit_name
|
68
82
|
end
|
69
83
|
|
70
84
|
@allow_building_development_pods = false
|
@@ -84,14 +98,12 @@ module PodBuilder
|
|
84
98
|
@build_path = build_base_path
|
85
99
|
@configuration_filename = "PodBuilder.json".freeze
|
86
100
|
@dev_pods_configuration_filename = "PodBuilderDevPodsPaths.json".freeze
|
87
|
-
@lfs_min_file_size = MIN_LFS_SIZE_KB
|
88
|
-
@lfs_update_gitattributes = false
|
89
|
-
@lfs_include_pods_folder = false
|
90
101
|
@project_name = ""
|
91
102
|
@restore_enabled = true
|
92
103
|
@prebuilt_info_filename = "PodBuilder.json"
|
93
104
|
@lockfile_name = "PodBuilder.lock"
|
94
105
|
@lockfile_path = "/tmp/#{lockfile_name}"
|
106
|
+
@lldbinit_name = "lldbinit".freeze
|
95
107
|
|
96
108
|
@use_bundler = false
|
97
109
|
@deterministic_build = false
|
@@ -173,16 +185,6 @@ module PodBuilder
|
|
173
185
|
Configuration.subspecs_to_split = value
|
174
186
|
end
|
175
187
|
end
|
176
|
-
if value = json["lfs_update_gitattributes"]
|
177
|
-
if [TrueClass, FalseClass].include?(value.class)
|
178
|
-
Configuration.lfs_update_gitattributes = value
|
179
|
-
end
|
180
|
-
end
|
181
|
-
if value = json["lfs_include_pods_folder"]
|
182
|
-
if [TrueClass, FalseClass].include?(value.class)
|
183
|
-
Configuration.lfs_include_pods_folder = value
|
184
|
-
end
|
185
|
-
end
|
186
188
|
if value = json["project_name"]
|
187
189
|
if value.is_a?(String) && value.length > 0
|
188
190
|
Configuration.project_name = value
|
@@ -262,8 +264,6 @@ module PodBuilder
|
|
262
264
|
config["library_evolution_support"] = Configuration.library_evolution_support
|
263
265
|
config["license_filename"] = Configuration.license_filename
|
264
266
|
config["subspecs_to_split"] = Configuration.subspecs_to_split
|
265
|
-
config["lfs_update_gitattributes"] = Configuration.lfs_update_gitattributes
|
266
|
-
config["lfs_include_pods_folder"] = Configuration.lfs_include_pods_folder
|
267
267
|
config["restore_enabled"] = Configuration.restore_enabled
|
268
268
|
config["allow_building_development_pods"] = Configuration.allow_building_development_pods
|
269
269
|
config["use_bundler"] = Configuration.use_bundler
|
data/lib/pod_builder/core.rb
CHANGED
@@ -19,6 +19,10 @@ module PodBuilder
|
|
19
19
|
@@xcodeproj_path = nil
|
20
20
|
@@xcodeworkspace_path = nil
|
21
21
|
|
22
|
+
def self.git_rootpath
|
23
|
+
return `git rev-parse --show-toplevel`.strip()
|
24
|
+
end
|
25
|
+
|
22
26
|
def self.safe_rm_rf(path)
|
23
27
|
unless File.exist?(path)
|
24
28
|
return
|
@@ -34,8 +38,8 @@ module PodBuilder
|
|
34
38
|
|
35
39
|
Dir.chdir(path)
|
36
40
|
|
37
|
-
|
38
|
-
raise "\n\nNo git repository found in '#{path}', can't delete files!\n".red if
|
41
|
+
rootpath = git_rootpath()
|
42
|
+
raise "\n\nNo git repository found in '#{path}', can't delete files!\n".red if rootpath.empty? && !path.start_with?(Configuration.build_base_path)
|
39
43
|
|
40
44
|
FileUtils.rm_rf(path)
|
41
45
|
|
@@ -45,6 +49,12 @@ module PodBuilder
|
|
45
49
|
Dir.chdir(basepath)
|
46
50
|
end
|
47
51
|
end
|
52
|
+
|
53
|
+
def self.gitignoredfiles
|
54
|
+
Dir.chdir(git_rootpath) do
|
55
|
+
return `git status --ignored -s | grep "^\!\!" | cut -c4-`.strip().split("\n")
|
56
|
+
end
|
57
|
+
end
|
48
58
|
|
49
59
|
def self.basepath(child = "")
|
50
60
|
if child.nil?
|
@@ -120,7 +130,7 @@ module PodBuilder
|
|
120
130
|
|
121
131
|
xcodeprojects = Dir.glob("#{home}/**/#{project_name}.xcodeproj").select { |x|
|
122
132
|
folder_in_home = x.gsub(home, "")
|
123
|
-
!folder_in_home.include?("/Pods/") && !x.include?(PodBuilder::basepath("Sources")) && !x.include?(basepath)
|
133
|
+
!folder_in_home.include?("/Pods/") && !x.include?(PodBuilder::basepath("Sources")) && !x.include?(PodBuilder::basepath + "/")
|
124
134
|
}
|
125
135
|
raise "\n\nxcodeproj not found!".red if xcodeprojects.count == 0
|
126
136
|
raise "\n\nFound multiple xcodeproj:\n#{xcodeprojects.join("\n")}".red if xcodeprojects.count > 1
|
@@ -136,7 +146,7 @@ module PodBuilder
|
|
136
146
|
|
137
147
|
xcworkspaces = Dir.glob("#{home}/**/#{Configuration.project_name}*.xcworkspace").select { |x|
|
138
148
|
folder_in_home = x.gsub(home, "")
|
139
|
-
!folder_in_home.include?("/Pods/") && !x.include?(PodBuilder::basepath("Sources")) && !x.include?(basepath) && !x.include?(".xcodeproj/")
|
149
|
+
!folder_in_home.include?("/Pods/") && !x.include?(PodBuilder::basepath("Sources")) && !x.include?(PodBuilder::basepath + "/") && !x.include?(".xcodeproj/")
|
140
150
|
}
|
141
151
|
raise "\n\nxcworkspace not found!".red if xcworkspaces.count == 0
|
142
152
|
raise "\n\nFound multiple xcworkspaces:\n#{xcworkspaces.join("\n")}".red if xcworkspaces.count > 1
|
@@ -205,8 +215,8 @@ module PodBuilder
|
|
205
215
|
private
|
206
216
|
|
207
217
|
def self.home
|
208
|
-
|
209
|
-
raise "\n\nNo git repository found in current folder `#{Dir.pwd}`!\n".red if
|
210
|
-
return
|
218
|
+
rootpath = git_rootpath
|
219
|
+
raise "\n\nNo git repository found in current folder `#{Dir.pwd}`!\n".red if rootpath.empty?
|
220
|
+
return rootpath
|
211
221
|
end
|
212
222
|
end
|
data/lib/pod_builder/install.rb
CHANGED
@@ -10,29 +10,29 @@ require 'highline/import'
|
|
10
10
|
# - https://github.com/leavez/cocoapods-binary/issues/50
|
11
11
|
begin
|
12
12
|
require 'cocoapods/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb'
|
13
|
-
|
13
|
+
|
14
14
|
class Pod::Specification
|
15
15
|
Pod::Specification.singleton_class.send(:alias_method, :swz_from_hash, :from_hash)
|
16
16
|
Pod::Specification.singleton_class.send(:alias_method, :swz_from_string, :from_string)
|
17
|
-
|
17
|
+
|
18
18
|
def self.from_string(*args)
|
19
19
|
spec = swz_from_string(*args)
|
20
|
-
|
20
|
+
|
21
21
|
if overrides = PodBuilder::Configuration.spec_overrides[spec.name]
|
22
22
|
overrides.each do |k, v|
|
23
23
|
spec.attributes_hash[k] = v
|
24
24
|
end
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
spec
|
28
28
|
end
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
class Pod::Target
|
32
32
|
attr_accessor :mock_dynamic_framework
|
33
|
-
|
33
|
+
|
34
34
|
alias_method :swz_build_type, :build_type
|
35
|
-
|
35
|
+
|
36
36
|
def build_type
|
37
37
|
if mock_dynamic_framework == true
|
38
38
|
if defined?(Pod::BuildType) # CocoaPods 1.9 and later
|
@@ -47,23 +47,23 @@ begin
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
# Starting from CocoaPods 1.10.0 and later resources are no longer copied inside the .framework
|
52
52
|
# when building static frameworks. While this is correct when using CP normally, for redistributable
|
53
53
|
# frameworks we require resources to be shipped along the binary
|
54
54
|
class Pod::Installer::Xcode::PodsProjectGenerator::PodTargetInstaller
|
55
55
|
alias_method :swz_add_files_to_build_phases, :add_files_to_build_phases
|
56
|
-
|
56
|
+
|
57
57
|
def add_files_to_build_phases(native_target, test_native_targets, app_native_targets)
|
58
58
|
target.mock_dynamic_framework = target.build_as_static_framework?
|
59
59
|
swz_add_files_to_build_phases(native_target, test_native_targets, app_native_targets)
|
60
60
|
target.mock_dynamic_framework = false
|
61
61
|
end
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
class Pod::Installer::Xcode::PodTargetDependencyInstaller
|
65
65
|
alias_method :swz_wire_resource_bundle_targets, :wire_resource_bundle_targets
|
66
|
-
|
66
|
+
|
67
67
|
def wire_resource_bundle_targets(resource_bundle_targets, native_target, pod_target)
|
68
68
|
pod_target.mock_dynamic_framework = pod_target.build_as_static_framework?
|
69
69
|
res = swz_wire_resource_bundle_targets(resource_bundle_targets, native_target, pod_target)
|
@@ -71,48 +71,110 @@ begin
|
|
71
71
|
return res
|
72
72
|
end
|
73
73
|
end
|
74
|
+
|
75
|
+
class Pod::Target::BuildSettings
|
76
|
+
alias_method :swz_save_as, :save_as
|
77
|
+
|
78
|
+
@specs_remove_module_maps = Hash.new
|
79
|
+
|
80
|
+
class << self
|
81
|
+
attr_accessor :specs_remove_module_maps
|
82
|
+
end
|
83
|
+
|
84
|
+
def save_as(path)
|
85
|
+
Pod::Target::BuildSettings.specs_remove_module_maps.each do |root_name, module_maps_to_remove|
|
86
|
+
if target.name == root_name
|
87
|
+
module_maps_to_remove.each do |module_map_to_remove|
|
88
|
+
xcconfig.attributes["OTHER_CFLAGS"] = xcconfig.attributes["OTHER_CFLAGS"].gsub(/-fmodule-map-file=\S*#{module_map_to_remove}.modulemap.*?(\s|$)/, '')
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
swz_save_as(path)
|
94
|
+
end
|
95
|
+
end
|
74
96
|
rescue LoadError
|
75
97
|
# CocoaPods 1.6.2 or earlier
|
76
98
|
end
|
77
99
|
|
78
100
|
module PodBuilder
|
101
|
+
class InstallResult
|
102
|
+
# @return [Array<Hash>] The installed licenses
|
103
|
+
#
|
104
|
+
attr_reader :licenses
|
105
|
+
|
106
|
+
# @return [Hash] A hash containing the expected prebuilt_info filename and content
|
107
|
+
#
|
108
|
+
attr_reader :prebuilt_info
|
109
|
+
|
110
|
+
def initialize(licenses = [], prebuilt_info = Hash.new)
|
111
|
+
@licenses = licenses
|
112
|
+
@prebuilt_info = prebuilt_info
|
113
|
+
end
|
114
|
+
|
115
|
+
def +(obj)
|
116
|
+
merged_licenses = @licenses.dup + obj.licenses
|
117
|
+
merged_prebuilt_info = @prebuilt_info.dup
|
118
|
+
|
119
|
+
merged_prebuilt_info.each do |key, value|
|
120
|
+
if obj.prebuilt_info.has_key?(key)
|
121
|
+
specs = merged_prebuilt_info[key]["specs"] || []
|
122
|
+
specs += (obj.prebuilt_info[key]["specs"] || [])
|
123
|
+
merged_prebuilt_info[key]["specs"] = specs.uniq
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
merged_prebuilt_info = obj.prebuilt_info.merge(merged_prebuilt_info)
|
128
|
+
|
129
|
+
return InstallResult.new(merged_licenses, merged_prebuilt_info)
|
130
|
+
end
|
131
|
+
|
132
|
+
def write_prebuilt_info_files
|
133
|
+
prebuilt_info.each do |file_path, file_content|
|
134
|
+
File.write(file_path, JSON.pretty_generate(file_content))
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
79
139
|
class Install
|
80
140
|
# This method will generate prebuilt data by building from "/tmp/pod_builder/Podfile"
|
81
141
|
def self.podfile(podfile_content, podfile_items, build_configuration)
|
82
142
|
puts "Preparing build Podfile".yellow
|
83
|
-
|
143
|
+
|
84
144
|
PodBuilder::safe_rm_rf(Configuration.build_path)
|
85
145
|
FileUtils.mkdir_p(Configuration.build_path)
|
86
146
|
|
87
147
|
init_git(Configuration.build_path) # this is needed to be able to call safe_rm_rf
|
88
|
-
|
148
|
+
|
89
149
|
podfile_content = copy_development_pods_source_code(podfile_content, podfile_items)
|
90
|
-
|
150
|
+
|
91
151
|
podfile_content = Podfile.update_path_entries(podfile_content, Install.method(:podfile_path_transform))
|
92
152
|
podfile_content = Podfile.update_project_entries(podfile_content, Install.method(:podfile_path_transform))
|
93
153
|
podfile_content = Podfile.update_require_entries(podfile_content, Install.method(:podfile_path_transform))
|
94
|
-
|
154
|
+
|
95
155
|
podfile_path = File.join(Configuration.build_path, "Podfile")
|
96
156
|
File.write(podfile_path, podfile_content)
|
97
|
-
|
157
|
+
|
98
158
|
begin
|
99
159
|
lock_file = "#{Configuration.build_path}/pod_builder.lock"
|
100
160
|
FileUtils.touch(lock_file)
|
161
|
+
|
162
|
+
prebuilt_entries = use_prebuilt_entries_for_unchanged_pods(podfile_path, podfile_items)
|
101
163
|
|
102
|
-
|
103
|
-
|
164
|
+
prepare_for_static_framework_workarounds(podfile_content, podfile_items)
|
165
|
+
|
104
166
|
install
|
167
|
+
|
168
|
+
copy_prebuilt_items(podfile_items - prebuilt_entries)
|
105
169
|
|
106
|
-
|
107
|
-
add_prebuilt_info_file(podfile_items)
|
108
|
-
|
170
|
+
prebuilt_info = prebuilt_info(podfile_items)
|
109
171
|
licenses = license_specifiers()
|
110
|
-
|
172
|
+
|
111
173
|
if !OPTIONS.has_key?(:debug)
|
112
174
|
PodBuilder::safe_rm_rf(Configuration.build_path)
|
113
175
|
end
|
114
|
-
|
115
|
-
return licenses
|
176
|
+
|
177
|
+
return InstallResult.new(licenses, prebuilt_info)
|
116
178
|
rescue Exception => e
|
117
179
|
if File.directory?("#{Configuration.build_path}/Pods/Pods.xcodeproj")
|
118
180
|
if ENV['DEBUGGING']
|
@@ -124,87 +186,165 @@ module PodBuilder
|
|
124
186
|
end
|
125
187
|
end
|
126
188
|
end
|
127
|
-
|
189
|
+
|
128
190
|
raise e
|
129
191
|
ensure
|
130
192
|
FileUtils.rm(lock_file) if File.exist?(lock_file)
|
131
193
|
end
|
132
194
|
end
|
133
195
|
|
196
|
+
def self.prebuilt_info(podfile_items)
|
197
|
+
gitignored_files = PodBuilder::gitignoredfiles
|
198
|
+
|
199
|
+
swift_version = PodBuilder::system_swift_version
|
200
|
+
|
201
|
+
write_prebuilt_info_filename_gitattributes
|
202
|
+
|
203
|
+
ret = Hash.new
|
204
|
+
root_names = podfile_items.reject(&:is_prebuilt).map(&:root_name).uniq
|
205
|
+
root_names.each do |prebuilt_name|
|
206
|
+
path = PodBuilder::prebuiltpath(prebuilt_name)
|
207
|
+
|
208
|
+
unless File.directory?(path)
|
209
|
+
puts "Prebuilt items for #{prebuilt_name} not found".blue
|
210
|
+
next
|
211
|
+
end
|
212
|
+
|
213
|
+
unless podfile_item = podfile_items.detect { |t| t.name == prebuilt_name } || podfile_items.detect { |t| t.root_name == prebuilt_name }
|
214
|
+
puts "Prebuilt items for #{prebuilt_name} not found #2".blue
|
215
|
+
next
|
216
|
+
end
|
217
|
+
|
218
|
+
podbuilder_file = File.join(path, Configuration.prebuilt_info_filename)
|
219
|
+
entry = podfile_item.entry(true, false)
|
220
|
+
if Configuration.subspecs_to_split.include?(podfile_item.name)
|
221
|
+
entry.gsub!("'#{podfile_item.name}'", "'#{podfile_item.root_name}'")
|
222
|
+
end
|
223
|
+
|
224
|
+
data = {}
|
225
|
+
data["entry"] = entry
|
226
|
+
data["is_prebuilt"] = podfile_item.is_prebuilt
|
227
|
+
if Dir.glob(File.join(path, "#{podfile_item.prebuilt_rel_path}/Headers/*-Swift.h")).count > 0
|
228
|
+
data["swift_version"] = swift_version
|
229
|
+
end
|
230
|
+
|
231
|
+
specs = podfile_items.select { |x| x.module_name == podfile_item.module_name }
|
232
|
+
subspecs_deps = specs.map(&:dependency_names).flatten
|
233
|
+
subspec_self_deps = subspecs_deps.select { |x| x.start_with?("#{prebuilt_name}/") }
|
234
|
+
data["specs"] = (specs.map(&:name) + subspec_self_deps).uniq
|
235
|
+
data["is_static"] = podfile_item.is_static
|
236
|
+
data["original_compile_path"] = Configuration.build_path.gsub(/^\/private/, "") # Use realpath for /private/tmp
|
237
|
+
if hash = build_folder_hash(podfile_item, gitignored_files)
|
238
|
+
data["build_folder_hash"] = hash
|
239
|
+
end
|
240
|
+
|
241
|
+
ret.merge!({ podbuilder_file => data })
|
242
|
+
end
|
243
|
+
|
244
|
+
return ret
|
245
|
+
end
|
134
246
|
private
|
135
247
|
|
248
|
+
def self.prepare_for_static_framework_workarounds(podfile_content, podfile_items)
|
249
|
+
unless podfile_content.include?("use_modular_headers!")
|
250
|
+
return
|
251
|
+
end
|
252
|
+
|
253
|
+
podfile_items.each do |podfile_item|
|
254
|
+
Pod::Target::BuildSettings.specs_remove_module_maps[podfile_item.root_name] = podfile_item.remove_module_maps
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
136
258
|
def self.license_specifiers
|
137
259
|
acknowledge_file = "#{Configuration.build_path}/Pods/Target Support Files/Pods-DummyTarget/Pods-DummyTarget-acknowledgements.plist"
|
138
260
|
unless File.exist?(acknowledge_file)
|
139
261
|
raise "\n\nLicense file not found".red
|
140
262
|
end
|
141
|
-
|
263
|
+
|
142
264
|
plist = CFPropertyList::List.new(:file => acknowledge_file)
|
143
265
|
data = CFPropertyList.native_types(plist.value)
|
144
|
-
|
266
|
+
|
145
267
|
return data["PreferenceSpecifiers"] || []
|
146
268
|
end
|
147
|
-
|
269
|
+
|
148
270
|
def self.copy_development_pods_source_code(podfile_content, podfile_items)
|
149
271
|
if Configuration.build_using_repo_paths
|
150
272
|
return podfile_content
|
151
273
|
end
|
152
|
-
|
274
|
+
|
153
275
|
# Development pods are normally built/integrated without moving files from their original paths.
|
154
276
|
# It is important that CocoaPods compiles the files under Configuration.build_path in order that
|
155
277
|
# DWARF debug info reference to this constant path. Doing otherwise breaks the assumptions that
|
156
|
-
# makes the `
|
278
|
+
# makes the `generate_lldbinit` command work.
|
157
279
|
development_pods = podfile_items.select { |x| x.is_development_pod }
|
158
280
|
development_pods.each do |podfile_item|
|
159
281
|
destination_path = "#{Configuration.build_path}/Pods/#{podfile_item.name}"
|
160
282
|
FileUtils.mkdir_p(destination_path)
|
161
|
-
|
283
|
+
|
162
284
|
if Pathname.new(podfile_item.path).absolute?
|
163
285
|
FileUtils.cp_r("#{podfile_item.path}/.", destination_path)
|
164
286
|
else
|
165
287
|
FileUtils.cp_r("#{PodBuilder::basepath(podfile_item.path)}/.", destination_path)
|
166
288
|
end
|
167
|
-
|
289
|
+
|
168
290
|
podfile_content.gsub!("'#{podfile_item.path}'", "'#{destination_path}'")
|
169
291
|
end
|
170
|
-
|
292
|
+
|
171
293
|
return podfile_content
|
172
294
|
end
|
173
|
-
|
295
|
+
|
174
296
|
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
297
|
podfile_content = File.read(podfile_path)
|
298
|
+
|
299
|
+
replaced_items = []
|
182
300
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
301
|
+
if OPTIONS.has_key?(:force_rebuild)
|
302
|
+
podfile_content.gsub!("%%%prebuilt_root_paths%%%", "{}")
|
303
|
+
else
|
304
|
+
download # Copy files under #{Configuration.build_path}/Pods so that we can determine build folder hashes
|
305
|
+
|
306
|
+
gitignored_files = PodBuilder::gitignoredfiles
|
307
|
+
|
308
|
+
prebuilt_root_paths = Hash.new
|
309
|
+
|
310
|
+
# Replace prebuilt entries in Podfile for Pods that have no changes in source code which will avoid rebuilding them
|
311
|
+
items = podfile_items.group_by { |t| t.root_name }.map { |k, v| v.first } # Return one podfile_item per root_name
|
312
|
+
items.each do |item|
|
313
|
+
podspec_path = item.prebuilt_podspec_path
|
314
|
+
if last_build_folder_hash = build_folder_hash_in_prebuilt_info_file(item)
|
315
|
+
if last_build_folder_hash == build_folder_hash(item, gitignored_files)
|
316
|
+
if Configuration.subspecs_to_split.include?(item.name)
|
317
|
+
puts "No changes detected to '#{item.name}', will skip rebuild".blue
|
318
|
+
else
|
319
|
+
puts "No changes detected to '#{item.root_name}', will skip rebuild".blue
|
320
|
+
end
|
321
|
+
replaced_items.push(item)
|
322
|
+
|
323
|
+
podfile_items.select { |t| t.root_name == item.root_name }.each do |replace_item|
|
324
|
+
replace_regex = "pod '#{Regexp.quote(replace_item.name)}', .*"
|
325
|
+
replace_line_found = podfile_content =~ /#{replace_regex}/i
|
326
|
+
raise "\n\nFailed finding pod entry for '#{replace_item.name}'".red unless replace_line_found
|
327
|
+
podfile_content.gsub!(/#{replace_regex}/, replace_item.prebuilt_entry(true, true))
|
328
|
+
|
329
|
+
prebuilt_root_paths[replace_item.root_name] = PodBuilder::prebuiltpath
|
330
|
+
end
|
195
331
|
end
|
196
332
|
end
|
197
333
|
end
|
334
|
+
|
335
|
+
podfile_content.gsub!("%%%prebuilt_root_paths%%%", prebuilt_root_paths.to_s)
|
198
336
|
end
|
199
337
|
|
200
338
|
File.write(podfile_path, podfile_content)
|
201
|
-
end
|
202
339
|
|
340
|
+
return replaced_items
|
341
|
+
end
|
342
|
+
|
203
343
|
def self.install
|
204
344
|
puts "Prebuilding items".yellow
|
205
|
-
|
345
|
+
|
206
346
|
CLAide::Command::PluginManager.load_plugins("cocoapods")
|
207
|
-
|
347
|
+
|
208
348
|
Dir.chdir(Configuration.build_path) do
|
209
349
|
config = Pod::Config.new()
|
210
350
|
installer = Pod::Installer.new(config.sandbox, config.podfile, config.lockfile)
|
@@ -212,21 +352,22 @@ module PodBuilder
|
|
212
352
|
installer.update = false
|
213
353
|
|
214
354
|
install_start_time = Time.now
|
355
|
+
|
215
356
|
installer.install!
|
216
357
|
install_time = Time.now - install_start_time
|
217
|
-
|
358
|
+
|
218
359
|
puts "Build completed in #{install_time.to_i} seconds".blue
|
219
360
|
end
|
220
361
|
end
|
221
|
-
|
362
|
+
|
222
363
|
def self.download
|
223
364
|
puts "Downloading Pods source code".yellow
|
224
|
-
|
365
|
+
|
225
366
|
CLAide::Command::PluginManager.load_plugins("cocoapods")
|
226
|
-
|
367
|
+
|
227
368
|
Dir.chdir(Configuration.build_path) do
|
228
369
|
Pod::UserInterface::config.silent = true
|
229
|
-
|
370
|
+
|
230
371
|
config = Pod::Config.new()
|
231
372
|
installer = Pod::Installer.new(config.sandbox, config.podfile, config.lockfile)
|
232
373
|
installer.repo_update = false
|
@@ -234,86 +375,92 @@ module PodBuilder
|
|
234
375
|
installer.prepare
|
235
376
|
installer.resolve_dependencies
|
236
377
|
installer.download_dependencies
|
237
|
-
|
378
|
+
|
238
379
|
Pod::UserInterface::config.silent = false
|
239
380
|
end
|
240
381
|
end
|
241
|
-
|
382
|
+
|
242
383
|
def self.copy_prebuilt_items(podfile_items)
|
243
384
|
FileUtils.mkdir_p(PodBuilder::prebuiltpath)
|
244
385
|
|
245
|
-
|
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
|
254
|
-
end
|
386
|
+
non_prebuilt_items = podfile_items.reject(&:is_prebuilt)
|
255
387
|
|
256
|
-
|
257
|
-
|
258
|
-
end
|
388
|
+
splitted_pods = non_prebuilt_items.map { |t| splitted_pod(t, podfile_items) }.flatten.uniq
|
389
|
+
splitted_pods_root_name = splitted_pods.map { |t| t.root_name }.uniq
|
259
390
|
|
260
|
-
|
261
|
-
if File.directory?(PodBuilder::buildpath_dsympath)
|
262
|
-
FileUtils.mkdir_p(PodBuilder::dsympath)
|
263
|
-
FileUtils.cp_r(PodBuilder::buildpath_dsympath, PodBuilder::basepath)
|
264
|
-
end
|
265
|
-
end
|
391
|
+
pod_names = non_prebuilt_items.reject { |t| splitted_pods_root_name.include?(t.root_name) }.map(&:root_name).uniq + splitted_pods.map(&:name)
|
266
392
|
|
267
|
-
|
268
|
-
|
393
|
+
pod_names.reject! { |t|
|
394
|
+
folder_path = PodBuilder::buildpath_prebuiltpath(t)
|
395
|
+
File.directory?(folder_path) && Dir.empty?(folder_path) # When using prebuilt items we end up with empty folders
|
396
|
+
}
|
269
397
|
|
270
|
-
|
271
|
-
|
272
|
-
|
398
|
+
# Selectively delete destination folder.
|
399
|
+
# If it's a splitted spec we just need to wipe the Subspecs/#{pod_name}
|
400
|
+
# If it's not we need to wipe everything except the Subspecs folder
|
401
|
+
pod_names.each do |pod_name|
|
402
|
+
root_name = pod_name.split("/").first
|
403
|
+
if pod_name.include?("/") # Splitted pod
|
404
|
+
PodBuilder::safe_rm_rf(PodBuilder::prebuiltpath("#{root_name}/Subspecs/#{pod_name.gsub("/", "_") }"))
|
405
|
+
else
|
406
|
+
items_to_delete = Dir.glob("#{PodBuilder::prebuiltpath(root_name)}/**/*")
|
407
|
+
items_to_delete.reject! { |t| t.include?(PodBuilder::prebuiltpath("#{root_name}/Subspecs")) }
|
273
408
|
|
274
|
-
|
275
|
-
puts "Prebuilt items for #{prebuilt_name} not found".blue
|
276
|
-
next
|
409
|
+
items_to_delete.each { |t| PodBuilder::safe_rm_rf(t) }
|
277
410
|
end
|
411
|
+
end
|
278
412
|
|
279
|
-
|
280
|
-
|
413
|
+
# Now copy
|
414
|
+
splitted_items_copied = false
|
415
|
+
pod_names.each do |pod_name|
|
416
|
+
root_name = pod_name.split("/").first
|
417
|
+
source_path = PodBuilder::buildpath_prebuiltpath(root_name)
|
418
|
+
|
419
|
+
unless File.directory?(source_path)
|
420
|
+
puts "Prebuilt items for #{pod_name} not found".blue
|
281
421
|
next
|
282
422
|
end
|
283
423
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
424
|
+
if Configuration.subspecs_to_split.include?(pod_name)
|
425
|
+
destination_folder = PodBuilder::prebuiltpath("#{root_name}/Subspecs/#{pod_name.gsub("/", "_") }")
|
426
|
+
FileUtils.mkdir_p(destination_folder)
|
427
|
+
unless splitted_items_copied
|
428
|
+
FileUtils.cp_r("#{source_path}/.", destination_folder)
|
429
|
+
splitted_items_copied = true
|
430
|
+
end
|
431
|
+
else
|
432
|
+
destination_folder = PodBuilder::prebuiltpath(root_name)
|
433
|
+
FileUtils.mkdir_p(destination_folder)
|
434
|
+
FileUtils.cp_r("#{source_path}/.", destination_folder)
|
292
435
|
end
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
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))
|
436
|
+
end
|
437
|
+
|
438
|
+
# Folder won't exist if no dSYM were generated (all static libs)
|
439
|
+
if File.directory?(PodBuilder::buildpath_dsympath)
|
440
|
+
FileUtils.mkdir_p(PodBuilder::dsympath)
|
441
|
+
FileUtils.cp_r(PodBuilder::buildpath_dsympath, PodBuilder::basepath)
|
303
442
|
end
|
304
443
|
end
|
305
444
|
|
445
|
+
def self.write_prebuilt_info_filename_gitattributes
|
446
|
+
gitattributes_path = PodBuilder::basepath(".gitattributes")
|
447
|
+
expected_attributes = ["#{Configuration.configuration_filename} binary"].join
|
448
|
+
unless File.exists?(gitattributes_path) && File.read(gitattributes_path).include?(expected_attributes)
|
449
|
+
File.write(gitattributes_path, expected_attributes, mode: 'a')
|
450
|
+
end
|
451
|
+
end
|
452
|
+
|
306
453
|
def self.init_git(path)
|
307
454
|
current_dir = Dir.pwd
|
308
|
-
|
455
|
+
|
309
456
|
Dir.chdir(path)
|
310
457
|
system("git init")
|
311
458
|
Dir.chdir(current_dir)
|
312
459
|
end
|
313
|
-
|
460
|
+
|
314
461
|
def self.build_folder_hash_in_prebuilt_info_file(podfile_item)
|
315
462
|
prebuilt_info_path = PodBuilder::prebuiltpath(File.join(podfile_item.root_name, Configuration.prebuilt_info_filename))
|
316
|
-
|
463
|
+
|
317
464
|
if File.exist?(prebuilt_info_path)
|
318
465
|
data = JSON.parse(File.read(prebuilt_info_path))
|
319
466
|
return data['build_folder_hash']
|
@@ -321,19 +468,39 @@ module PodBuilder
|
|
321
468
|
return nil
|
322
469
|
end
|
323
470
|
end
|
324
|
-
|
325
|
-
def self.build_folder_hash(podfile_item)
|
471
|
+
|
472
|
+
def self.build_folder_hash(podfile_item, exclude_files)
|
326
473
|
if podfile_item.is_development_pod
|
327
474
|
if Pathname.new(podfile_item.path).absolute?
|
328
475
|
item_path = podfile_item.path
|
329
476
|
else
|
330
477
|
item_path = PodBuilder::basepath(podfile_item.path)
|
331
478
|
end
|
479
|
+
|
480
|
+
rootpath = PodBuilder::git_rootpath
|
481
|
+
file_hashes = []
|
482
|
+
Dir.glob("#{item_path}/**/*", File::FNM_DOTMATCH) do |path|
|
483
|
+
unless File.file?(path)
|
484
|
+
next
|
485
|
+
end
|
486
|
+
|
487
|
+
path = File.expand_path(path)
|
488
|
+
rel_path = path.gsub(rootpath, "")[1..]
|
489
|
+
unless exclude_files.include?(rel_path)
|
490
|
+
file_hashes.push(Digest::MD5.hexdigest(File.read(path)))
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
return Digest::MD5.hexdigest(file_hashes.join)
|
332
495
|
else
|
496
|
+
# Pod folder might be under .gitignore
|
333
497
|
item_path = "#{Configuration.build_path}/Pods/#{podfile_item.root_name}"
|
498
|
+
if File.directory?(item_path)
|
499
|
+
return `find '#{item_path}' -type f -print0 | sort -z | xargs -0 shasum | shasum | cut -d' ' -f1`.strip()
|
500
|
+
else
|
501
|
+
return nil
|
502
|
+
end
|
334
503
|
end
|
335
|
-
|
336
|
-
return `find '#{item_path}' -type f -print0 | sort -z | xargs -0 shasum | shasum | cut -d' ' -f1`.strip()
|
337
504
|
end
|
338
505
|
|
339
506
|
def self.podfile_path_transform(path)
|
@@ -343,17 +510,21 @@ module PodBuilder
|
|
343
510
|
use_absolute_paths = true
|
344
511
|
podfile_path = File.join(Configuration.build_path, "Podfile")
|
345
512
|
original_basepath = PodBuilder::basepath
|
346
|
-
|
513
|
+
|
347
514
|
podfile_base_path = Pathname.new(File.dirname(podfile_path))
|
348
|
-
|
515
|
+
|
349
516
|
original_path = Pathname.new(File.join(original_basepath, path))
|
350
517
|
replace_path = original_path.relative_path_from(podfile_base_path)
|
351
518
|
if use_absolute_paths
|
352
519
|
replace_path = replace_path.expand_path(podfile_base_path)
|
353
520
|
end
|
354
|
-
|
521
|
+
|
355
522
|
return replace_path
|
356
523
|
end
|
357
|
-
end
|
524
|
+
end
|
525
|
+
|
526
|
+
def self.splitted_pod(podfile_item, podfile_items)
|
527
|
+
return podfile_items.select { |t| t.root_name == podfile_item.root_name && Configuration.subspecs_to_split.include?(t.name) }
|
528
|
+
end
|
358
529
|
end
|
359
530
|
end
|