pod-builder 0.1.4
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 +7 -0
- data/.gitignore +8 -0
- data/.vscode/launch.json +102 -0
- data/Example/PodBuilderExample.xcodeproj/project.pbxproj +416 -0
- data/Example/PodBuilderExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- data/Example/PodBuilderExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- data/Example/PodBuilderExample.xcodeproj/project.xcworkspace/xcuserdata/tomas.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- data/Example/PodBuilderExample.xcodeproj/xcuserdata/tomas.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
- data/Example/PodBuilderExample.xcworkspace/contents.xcworkspacedata +10 -0
- data/Example/PodBuilderExample/AppDelegate.swift +47 -0
- data/Example/PodBuilderExample/Assets.xcassets/AppIcon.appiconset/Contents.json +98 -0
- data/Example/PodBuilderExample/Assets.xcassets/Contents.json +6 -0
- data/Example/PodBuilderExample/Base.lproj/LaunchScreen.storyboard +25 -0
- data/Example/PodBuilderExample/Base.lproj/Main.storyboard +24 -0
- data/Example/PodBuilderExample/Info.plist +45 -0
- data/Example/PodBuilderExample/ViewController.swift +25 -0
- data/Example/Podfile +8 -0
- data/Example/Podfile.lock +16 -0
- data/Example/Pods/Alamofire/LICENSE +19 -0
- data/Example/Pods/Alamofire/README.md +242 -0
- data/Example/Pods/Alamofire/Source/AFError.swift +460 -0
- data/Example/Pods/Alamofire/Source/Alamofire.swift +465 -0
- data/Example/Pods/Alamofire/Source/DispatchQueue+Alamofire.swift +37 -0
- data/Example/Pods/Alamofire/Source/MultipartFormData.swift +580 -0
- data/Example/Pods/Alamofire/Source/NetworkReachabilityManager.swift +233 -0
- data/Example/Pods/Alamofire/Source/Notifications.swift +55 -0
- data/Example/Pods/Alamofire/Source/ParameterEncoding.swift +483 -0
- data/Example/Pods/Alamofire/Source/Request.swift +654 -0
- data/Example/Pods/Alamofire/Source/Response.swift +567 -0
- data/Example/Pods/Alamofire/Source/ResponseSerialization.swift +715 -0
- data/Example/Pods/Alamofire/Source/Result.swift +300 -0
- data/Example/Pods/Alamofire/Source/ServerTrustPolicy.swift +307 -0
- data/Example/Pods/Alamofire/Source/SessionDelegate.swift +725 -0
- data/Example/Pods/Alamofire/Source/SessionManager.swift +896 -0
- data/Example/Pods/Alamofire/Source/TaskDelegate.swift +466 -0
- data/Example/Pods/Alamofire/Source/Timeline.swift +136 -0
- data/Example/Pods/Alamofire/Source/Validation.swift +315 -0
- data/Example/Pods/Manifest.lock +16 -0
- data/Example/Pods/Pods.xcodeproj/project.pbxproj +673 -0
- data/Example/Pods/Pods.xcodeproj/xcuserdata/tomas.xcuserdatad/xcschemes/Alamofire.xcscheme +60 -0
- data/Example/Pods/Pods.xcodeproj/xcuserdata/tomas.xcuserdatad/xcschemes/Pods-PodBuilderExample.xcscheme +60 -0
- data/Example/Pods/Pods.xcodeproj/xcuserdata/tomas.xcuserdatad/xcschemes/xcschememanagement.plist +21 -0
- data/Example/Pods/Target Support Files/Alamofire/Alamofire-dummy.m +5 -0
- data/Example/Pods/Target Support Files/Alamofire/Alamofire-prefix.pch +12 -0
- data/Example/Pods/Target Support Files/Alamofire/Alamofire-umbrella.h +16 -0
- data/Example/Pods/Target Support Files/Alamofire/Alamofire.modulemap +6 -0
- data/Example/Pods/Target Support Files/Alamofire/Alamofire.xcconfig +9 -0
- data/Example/Pods/Target Support Files/Alamofire/Info.plist +26 -0
- data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Info.plist +26 -0
- data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-acknowledgements.markdown +26 -0
- data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-acknowledgements.plist +58 -0
- data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-dummy.m +5 -0
- data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-frameworks.sh +153 -0
- data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-resources.sh +118 -0
- data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-umbrella.h +16 -0
- data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample.debug.xcconfig +11 -0
- data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample.modulemap +6 -0
- data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample.release.xcconfig +11 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +100 -0
- data/LICENSE.txt +13 -0
- data/README.md +192 -0
- data/Rakefile +2 -0
- data/bin/console +16 -0
- data/bin/setup +8 -0
- data/exe/pod_builder +174 -0
- data/lib/pod_builder/analyze.rb +52 -0
- data/lib/pod_builder/cocoapods/analyzer.rb +24 -0
- data/lib/pod_builder/cocoapods/specification.rb +27 -0
- data/lib/pod_builder/command.rb +9 -0
- data/lib/pod_builder/command/build.rb +240 -0
- data/lib/pod_builder/command/build_all.rb +15 -0
- data/lib/pod_builder/command/clean.rb +80 -0
- data/lib/pod_builder/command/deintegrate.rb +51 -0
- data/lib/pod_builder/command/generate_podspec.rb +17 -0
- data/lib/pod_builder/command/init.rb +86 -0
- data/lib/pod_builder/command/install_sources.rb +82 -0
- data/lib/pod_builder/command/none.rb +16 -0
- data/lib/pod_builder/command/restore_all.rb +30 -0
- data/lib/pod_builder/configuration.rb +91 -0
- data/lib/pod_builder/core.rb +74 -0
- data/lib/pod_builder/install.rb +105 -0
- data/lib/pod_builder/podfile.rb +207 -0
- data/lib/pod_builder/podfile/post_actions.rb +141 -0
- data/lib/pod_builder/podfile_item.rb +216 -0
- data/lib/pod_builder/podspec.rb +71 -0
- data/lib/pod_builder/templates/build_podfile.template +78 -0
- data/lib/pod_builder/templates/build_podspec.template +19 -0
- data/lib/pod_builder/version.rb +4 -0
- data/pod-builder.gemspec +36 -0
- metadata +274 -0
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'cocoapods'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'colored'
|
4
|
+
|
5
|
+
require 'pod_builder/podfile'
|
6
|
+
require 'pod_builder/podfile_item'
|
7
|
+
require 'pod_builder/analyze'
|
8
|
+
require 'pod_builder/install'
|
9
|
+
require 'pod_builder/configuration'
|
10
|
+
require 'pod_builder/podspec'
|
11
|
+
|
12
|
+
module PodBuilder
|
13
|
+
def self.safe_rm_rf(path)
|
14
|
+
unless File.exist?(path)
|
15
|
+
return
|
16
|
+
end
|
17
|
+
|
18
|
+
current_dir = Dir.pwd
|
19
|
+
|
20
|
+
Dir.chdir(path)
|
21
|
+
|
22
|
+
h = `git rev-parse --show-toplevel`.strip()
|
23
|
+
raise "\n\nNo git repository found, can't delete files!\n".red if h.empty?
|
24
|
+
|
25
|
+
FileUtils.rm_rf(path)
|
26
|
+
|
27
|
+
if File.exist?(current_dir)
|
28
|
+
Dir.chdir(current_dir)
|
29
|
+
else
|
30
|
+
Dir.chdir(basepath)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.home
|
35
|
+
h = `git rev-parse --show-toplevel`.strip()
|
36
|
+
raise "\n\nNo git repository found in current folder `#{Dir.pwd}`!\n".red if h.empty?
|
37
|
+
return h
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.basepath(child = "")
|
41
|
+
return "#{Configuration.base_path}/#{child}".gsub("//", "/").gsub(/\/$/, '')
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.xcodepath(child = "")
|
45
|
+
project = PodBuilder::find_xcodeproject
|
46
|
+
|
47
|
+
return project ? "#{File.dirname(project)}/#{child}".gsub("//", "/").gsub(/\/$/, '') : nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.find_xcodeproject
|
51
|
+
return Dir.glob("#{home}/**/*.xcodeproj").detect { |x| !x.include?("Pods.xcodeproj") && !x.include?(basepath) }
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.find_xcodeworkspace
|
55
|
+
return Dir.glob("#{home}/**/*.xcworkspace").detect { |x| !x.include?("Pods.xcworkspace") && !x.include?(basepath) }
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.prepare_basepath
|
59
|
+
project = PodBuilder::find_xcodeproject
|
60
|
+
if project
|
61
|
+
FileUtils.mkdir_p(basepath("Pods/Target Support Files"))
|
62
|
+
FileUtils.cp_r(project, basepath)
|
63
|
+
FileUtils.rm_f(basepath("Podfile.lock"))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.clean_basepath
|
68
|
+
project = PodBuilder::find_xcodeproject
|
69
|
+
if project
|
70
|
+
PodBuilder::safe_rm_rf(basepath(File.basename(project)))
|
71
|
+
PodBuilder::safe_rm_rf(basepath("Pods"))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
|
2
|
+
module PodBuilder
|
3
|
+
class Install
|
4
|
+
def self.podfile(podfile_content, podfile_items, build_configuration)
|
5
|
+
PodBuilder::safe_rm_rf(Configuration.build_path)
|
6
|
+
FileUtils.mkdir_p(Configuration.build_path)
|
7
|
+
|
8
|
+
init_git(Configuration.build_path) # this is needed to be able to call safe_rm_rf
|
9
|
+
|
10
|
+
File.write("#{Configuration.build_path}/Podfile", podfile_content)
|
11
|
+
|
12
|
+
begin
|
13
|
+
lock_file = "#{Configuration.build_path}/pod_builder.lock"
|
14
|
+
FileUtils.touch(lock_file)
|
15
|
+
|
16
|
+
install
|
17
|
+
|
18
|
+
cleanup_frameworks(podfile_items)
|
19
|
+
copy_frameworks(podfile_items)
|
20
|
+
if build_configuration != "debug"
|
21
|
+
copy_dsyms(podfile_items)
|
22
|
+
end
|
23
|
+
rescue Exception => e
|
24
|
+
raise e
|
25
|
+
ensure
|
26
|
+
FileUtils.rm(lock_file)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def self.install
|
33
|
+
CLAide::Command::PluginManager.load_plugins("cocoapods")
|
34
|
+
|
35
|
+
current_dir = Dir.pwd
|
36
|
+
|
37
|
+
Dir.chdir(Configuration.build_path)
|
38
|
+
|
39
|
+
config = Pod::Config.new()
|
40
|
+
installer = Pod::Installer.new(config.sandbox, config.podfile, config.lockfile)
|
41
|
+
installer.repo_update = false
|
42
|
+
installer.update = false
|
43
|
+
installer.install!
|
44
|
+
|
45
|
+
Dir.chdir(current_dir)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.framework_rel_path(framework_path, podfile_items)
|
49
|
+
framework_name = File.basename(framework_path)
|
50
|
+
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 }
|
52
|
+
return "#{podfile_item.prebuilt_rel_path}"
|
53
|
+
else
|
54
|
+
return framework_name
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.cleanup_frameworks(podfile_items)
|
59
|
+
Dir.glob("#{Configuration.build_path}/Rome/*.framework") do |framework_path|
|
60
|
+
framework_rel_path = framework_rel_path(framework_path, podfile_items)
|
61
|
+
dsym_path = framework_rel_path + ".dSYM"
|
62
|
+
|
63
|
+
PodBuilder::safe_rm_rf(PodBuilder::basepath("Rome/#{framework_rel_path}"))
|
64
|
+
PodBuilder::safe_rm_rf(PodBuilder::basepath("dSYM/iphoneos/#{dsym_path}"))
|
65
|
+
PodBuilder::safe_rm_rf(PodBuilder::basepath("dSYM/iphonesimulator/#{dsym_path}"))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.copy_frameworks(podfile_items)
|
70
|
+
Dir.glob("#{Configuration.build_path}/Rome/*.framework") do |framework_path|
|
71
|
+
framework_rel_path = framework_rel_path(framework_path, podfile_items)
|
72
|
+
|
73
|
+
destination_path = PodBuilder::basepath("Rome/#{framework_rel_path}")
|
74
|
+
FileUtils.mkdir_p(File.dirname(destination_path))
|
75
|
+
FileUtils.cp_r(framework_path, destination_path)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.copy_dsyms(podfile_items)
|
80
|
+
Dir.glob("#{Configuration.build_path}/build/*iphoneos/**/*.dSYM") do |dsym_path|
|
81
|
+
framework_rel_path = framework_rel_path(dsym_path.gsub(File.extname(dsym_path), ""), podfile_items)
|
82
|
+
|
83
|
+
destination_path = PodBuilder::basepath("dSYM/iphoneos/#{File.dirname(framework_rel_path)}")
|
84
|
+
FileUtils.mkdir_p(destination_path)
|
85
|
+
FileUtils.cp_r(dsym_path, destination_path)
|
86
|
+
end
|
87
|
+
|
88
|
+
Dir.glob("#{Configuration.build_path}/build/*iphonesimulator/**/*.dSYM") do |dsym_path|
|
89
|
+
framework_rel_path = framework_rel_path(dsym_path.gsub(File.extname(dsym_path), ""), podfile_items)
|
90
|
+
|
91
|
+
destination_path = PodBuilder::basepath("dSYM/iphonesimulator/#{File.dirname(framework_rel_path)}")
|
92
|
+
FileUtils.mkdir_p(destination_path)
|
93
|
+
FileUtils.cp_r(dsym_path, destination_path)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.init_git(path)
|
98
|
+
current_dir = Dir.pwd
|
99
|
+
|
100
|
+
Dir.chdir(path)
|
101
|
+
system("git init")
|
102
|
+
Dir.chdir(current_dir)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'pod_builder/cocoapods/analyzer'
|
2
|
+
|
3
|
+
module PodBuilder
|
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')"]
|
7
|
+
|
8
|
+
def self.from_podfile_items(items, analyzer)
|
9
|
+
raise "no items" unless items.count > 0
|
10
|
+
|
11
|
+
sources = analyzer.sources
|
12
|
+
|
13
|
+
cwd = File.dirname(File.expand_path(__FILE__))
|
14
|
+
podfile = File.read("#{cwd}/templates/build_podfile.template")
|
15
|
+
|
16
|
+
podfile.sub!("%%%sources%%%", sources.map { |x| "source '#{x.url}'" }.join("\n"))
|
17
|
+
|
18
|
+
build_configurations = items.map(&:build_configuration).uniq
|
19
|
+
raise "Found different build configurations in #{items}" if build_configurations.count != 1
|
20
|
+
podfile.sub!("%%%build_configuration%%%", build_configurations.first.capitalize)
|
21
|
+
|
22
|
+
build_settings = Configuration.build_settings
|
23
|
+
podfile_build_settings = ""
|
24
|
+
items.each do |item|
|
25
|
+
build_settings['SWIFT_VERSION'] = item.swift_version || project_swift_version(analyzer)
|
26
|
+
if swift_optimization_level = item.swift_optimization_level
|
27
|
+
build_settings['SWIFT_OPTIMIZATION_LEVEL'] = swift_optimization_level
|
28
|
+
end
|
29
|
+
|
30
|
+
podfile_build_settings += "set_build_settings(\"#{item.root_name}\", #{build_settings.to_s}, installer)\n "
|
31
|
+
end
|
32
|
+
|
33
|
+
podfile.sub!("%%%build_settings%%%", podfile_build_settings)
|
34
|
+
|
35
|
+
podfile.sub!("%%%build_system%%%", Configuration.build_system)
|
36
|
+
|
37
|
+
podfile.sub!("%%%pods%%%", "\"#{items.map(&:name).join('", "')}\"")
|
38
|
+
|
39
|
+
podfile.sub!("%%%dependencies%%%", "\"#{items.map(&:dependency_names).flatten.uniq.join("\",\"")}\"")
|
40
|
+
|
41
|
+
podfile.sub!("%%%targets%%%", items.map(&:entry).join("\n "))
|
42
|
+
|
43
|
+
return podfile
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.write_restorable(updated_pods, podfile_items, analyzer)
|
47
|
+
podfile_items = podfile_items.dup
|
48
|
+
podfile_restore_path = PodBuilder::basepath("Podfile.restore")
|
49
|
+
podfile_path = PodBuilder::basepath("Podfile")
|
50
|
+
|
51
|
+
if File.exist?(podfile_restore_path)
|
52
|
+
podfile_content = File.read(podfile_restore_path)
|
53
|
+
|
54
|
+
restore_podfile_items = podfile_items_at(podfile_restore_path)
|
55
|
+
|
56
|
+
podfile_items.map! { |podfile_item|
|
57
|
+
if updated_pod = updated_pods.detect { |x| x.name == podfile_item.name } then
|
58
|
+
updated_pod
|
59
|
+
elsif restored_pod = restore_podfile_items.detect { |x| x.name == podfile_item.name }
|
60
|
+
restored_pod
|
61
|
+
else
|
62
|
+
podfile_item
|
63
|
+
end
|
64
|
+
}
|
65
|
+
else
|
66
|
+
podfile_content = File.read(podfile_path)
|
67
|
+
end
|
68
|
+
|
69
|
+
current_target = nil
|
70
|
+
destination_lines = []
|
71
|
+
podfile_content.each_line do |line|
|
72
|
+
stripped_line = strip_line(line)
|
73
|
+
if current_target.nil?
|
74
|
+
destination_lines.push(line)
|
75
|
+
|
76
|
+
if current_target = target_definition_in(line, false)
|
77
|
+
target_pods, target_dependencies = analyzer.pods_and_deps_in_target(current_target, podfile_items)
|
78
|
+
|
79
|
+
# dependecies should be listed first
|
80
|
+
current_target_pods = (target_dependencies + target_pods).uniq
|
81
|
+
|
82
|
+
# There should be at most one subspecs per target
|
83
|
+
# Taking just one subspec is enough to pin to the correct version
|
84
|
+
current_target_pods = current_target_pods.sort_by(&:name).uniq(&:root_name)
|
85
|
+
|
86
|
+
current_target_pods.each { |x| destination_lines.push(" #{x.entry}\n") }
|
87
|
+
end
|
88
|
+
else
|
89
|
+
if stripped_line == "end"
|
90
|
+
destination_lines.push(line)
|
91
|
+
current_target = nil
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
podfile_content = destination_lines.join
|
97
|
+
File.write(podfile_restore_path, podfile_content)
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.update_prebuilt(updated_pods, podfile_items, analyzer)
|
101
|
+
project_podfile_path = PodBuilder::xcodepath("Podfile")
|
102
|
+
|
103
|
+
podfile_content = File.read(project_podfile_path)
|
104
|
+
|
105
|
+
stripped_prebuilt_entries = (updated_pods + podfile_items).map(&:prebuilt_entry).map { |x| strip_line(x) }
|
106
|
+
podfile_items_name = podfile_items.map(&:name)
|
107
|
+
|
108
|
+
destination_lines = []
|
109
|
+
podfile_content.each_line do |line|
|
110
|
+
stripped_line = strip_line(line)
|
111
|
+
|
112
|
+
if pod_name = pod_definition_in(line, true)
|
113
|
+
if updated_pod = updated_pods.detect { |x| x.name == pod_name }
|
114
|
+
destination_lines.push(" #{updated_pod.prebuilt_entry}\n")
|
115
|
+
destination_lines.push(" # #{updated_pod.entry(false)}\n")
|
116
|
+
next
|
117
|
+
elsif !podfile_items_name.include?(pod_name) && !stripped_prebuilt_entries.include?(stripped_line)
|
118
|
+
next
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
destination_lines.push(line)
|
123
|
+
end
|
124
|
+
|
125
|
+
# remove adiacent duplicated entries
|
126
|
+
destination_lines = destination_lines.chunk { |x| x }.map(&:first)
|
127
|
+
|
128
|
+
podfile_content = destination_lines.join
|
129
|
+
File.write(project_podfile_path, podfile_content)
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.deintegrate_install
|
133
|
+
current_dir = Dir.pwd
|
134
|
+
|
135
|
+
Dir.chdir(PodBuilder::xcodepath)
|
136
|
+
system("pod deintegrate; pod install;")
|
137
|
+
Dir.chdir(current_dir)
|
138
|
+
end
|
139
|
+
|
140
|
+
def self.strip_line(line)
|
141
|
+
stripped_line = line.dup
|
142
|
+
return stripped_line.gsub("\"", "'").gsub(" ", "").gsub("\n", "")
|
143
|
+
end
|
144
|
+
|
145
|
+
private
|
146
|
+
|
147
|
+
def self.pod_definition_in(line, include_commented)
|
148
|
+
stripped_line = strip_line(line)
|
149
|
+
matches = stripped_line.match(/(pod')(.*?)(')/)
|
150
|
+
|
151
|
+
if matches&.size == 4 && (include_commented || !stripped_line.start_with?("#"))
|
152
|
+
return matches[2]
|
153
|
+
else
|
154
|
+
return nil
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def self.target_definition_in(line, include_commented)
|
159
|
+
stripped_line = strip_line(line)
|
160
|
+
matches = stripped_line.match(/(target')(.*?)(')/)
|
161
|
+
|
162
|
+
if matches&.size == 4 && (include_commented || !stripped_line.start_with?("#"))
|
163
|
+
return matches[2]
|
164
|
+
else
|
165
|
+
return nil
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def self.project_swift_version(analyzer)
|
170
|
+
swift_versions = analyzer.result.target_inspections.values.map { |x| x.target_definition.swift_version }.uniq
|
171
|
+
|
172
|
+
raise "Found different Swift versions in targets. Expecting one, got `#{swift_versions}`" if swift_versions.count != 1
|
173
|
+
|
174
|
+
return swift_versions.first
|
175
|
+
end
|
176
|
+
|
177
|
+
def self.podfile_items_at(podfile_path)
|
178
|
+
raise "Expecting basepath folder!" if !File.exist?(PodBuilder::basepath("Podfile"))
|
179
|
+
|
180
|
+
if File.basename(podfile_path) != "Podfile"
|
181
|
+
File.rename(PodBuilder::basepath("Podfile"), PodBuilder::basepath("Podfile.tmp"))
|
182
|
+
FileUtils.cp(podfile_path, PodBuilder::basepath("Podfile"))
|
183
|
+
end
|
184
|
+
|
185
|
+
current_dir = Dir.pwd
|
186
|
+
Dir.chdir(File.dirname(podfile_path))
|
187
|
+
|
188
|
+
buildable_items = []
|
189
|
+
begin
|
190
|
+
installer, analyzer = Analyze.installer_at(PodBuilder::basepath)
|
191
|
+
|
192
|
+
podfile_items = Analyze.podfile_items(installer, analyzer)
|
193
|
+
buildable_items = podfile_items.select { |item| item.is_prebuilt == false }
|
194
|
+
rescue Exception => e
|
195
|
+
raise e
|
196
|
+
ensure
|
197
|
+
Dir.chdir(current_dir)
|
198
|
+
|
199
|
+
if File.basename(podfile_path) != "Podfile"
|
200
|
+
File.rename(PodBuilder::basepath("Podfile.tmp"), PodBuilder::basepath("Podfile"))
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
return buildable_items
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'colored'
|
2
|
+
require 'xcodeproj'
|
3
|
+
require 'pod_builder/core'
|
4
|
+
|
5
|
+
module PodBuilder
|
6
|
+
class Podfile
|
7
|
+
def self.remove_target_support_duplicate_entries
|
8
|
+
puts "[PodBuilder] Removing target support duplicated entries".yellow
|
9
|
+
# Frameworks and resources
|
10
|
+
find_xcodeproj_targets.map(&:name).each do |target|
|
11
|
+
remove_duplicate_entries("Pods/Target Support Files/Pods-#{target}/Pods-#{target}-frameworks.sh")
|
12
|
+
remove_duplicate_entries("Pods/Target Support Files/Pods-#{target}/Pods-#{target}-resources.sh")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.check_target_support_resource_collisions
|
17
|
+
puts "[PodBuilder] Checking target support resource collisions".yellow
|
18
|
+
|
19
|
+
targets = find_xcodeproj_targets
|
20
|
+
|
21
|
+
targets.map(&:name).each do |target|
|
22
|
+
check_for_colliding_resources("Pods/Target Support Files/Pods-#{target}/Pods-#{target}-resources.sh", target, targets)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def self.remove_duplicate_entries(path)
|
29
|
+
if !File.file?(path)
|
30
|
+
return
|
31
|
+
end
|
32
|
+
|
33
|
+
# Adding the same pod to multiple targets results in duplicate entries in Pods-TARGET-frameworks.sh and Pods-TARGET-resources.sh (Cocoapods 1.4.0)
|
34
|
+
# To avoid conflicts during parallel codesign we manually remove duplicates
|
35
|
+
in_section_to_update = false
|
36
|
+
processed_entries = []
|
37
|
+
lines = []
|
38
|
+
File.read(path).each_line do |line|
|
39
|
+
stripped_line = line.strip()
|
40
|
+
next if stripped_line.empty?
|
41
|
+
|
42
|
+
if stripped_line.include?("if [[ \"$CONFIGURATION\" == ")
|
43
|
+
in_section_to_update = true
|
44
|
+
elsif stripped_line == "fi"
|
45
|
+
in_section_to_update = false
|
46
|
+
processed_entries = []
|
47
|
+
end
|
48
|
+
if in_section_to_update
|
49
|
+
if processed_entries.include?(stripped_line)
|
50
|
+
if !line.include?("#")
|
51
|
+
line = "# #{line}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
processed_entries.push(stripped_line)
|
55
|
+
end
|
56
|
+
|
57
|
+
lines.push(line)
|
58
|
+
end
|
59
|
+
|
60
|
+
File.write(path, lines.join)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.check_for_colliding_resources(path, target_name, targets)
|
64
|
+
if !File.file?(path)
|
65
|
+
return
|
66
|
+
end
|
67
|
+
|
68
|
+
if target = targets.detect { |x| x.name == target_name }
|
69
|
+
resource_files = target.resources_build_phase.files.map { |i| i.file_ref.real_path.to_s }.to_set
|
70
|
+
resource_files = resource_files.map { |i| File.basename(i) }
|
71
|
+
resource_files = resource_files.map { |i| i.gsub(".xib", ".nib") }
|
72
|
+
else
|
73
|
+
raise "#{target} not found!".red
|
74
|
+
end
|
75
|
+
|
76
|
+
# Check that Pods-TARGET-resources.sh doesn't contain colliding entries (Cocoapods 1.4.0)
|
77
|
+
in_section_to_update = false
|
78
|
+
processed_entries = []
|
79
|
+
File.read(path).each_line do |line|
|
80
|
+
stripped_line = line.strip()
|
81
|
+
next if stripped_line.empty?
|
82
|
+
|
83
|
+
if stripped_line.include?("if [[ \"$CONFIGURATION\" == ")
|
84
|
+
in_section_to_update = true
|
85
|
+
next
|
86
|
+
elsif stripped_line == "fi"
|
87
|
+
in_section_to_update = false
|
88
|
+
|
89
|
+
processed_entries.each do |entry|
|
90
|
+
matches_other_framework = processed_entries.select { |t| t[0] == entry[0] }
|
91
|
+
|
92
|
+
# Check for static framework cross-collisions
|
93
|
+
if matches_other_framework.count > 1
|
94
|
+
error = "\n\nCross-framework resource collision detected:\n"
|
95
|
+
error += "#{entry[0]} found in\n"
|
96
|
+
error += matches_other_framework.map { |x| "- #{x[1]}" }.join("\n")
|
97
|
+
error += "\n\n"
|
98
|
+
|
99
|
+
raise error.red
|
100
|
+
end
|
101
|
+
|
102
|
+
# Check for collisions with app's resources
|
103
|
+
matches_app_resources = resource_files.select { |t| t == entry[0] }
|
104
|
+
if matches_app_resources.count > 0
|
105
|
+
error = "\n\nResource collision with app file detected:\n"
|
106
|
+
error += "#{entry[0]} found in app but also in\n"
|
107
|
+
error += matches_app_resources.map { |x| "- #{x[1]}" }.join("\n")
|
108
|
+
error += "\n\n"
|
109
|
+
|
110
|
+
raise error.red
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
processed_entries = []
|
115
|
+
end
|
116
|
+
|
117
|
+
next if stripped_line.start_with?("#") # skip commented lines
|
118
|
+
next if stripped_line.count("/..") > 2 # skip development pods
|
119
|
+
|
120
|
+
line.gsub!("\"", "")
|
121
|
+
line.gsub!("install_resource", "")
|
122
|
+
line.strip!()
|
123
|
+
|
124
|
+
if in_section_to_update
|
125
|
+
filename = File.basename(line)
|
126
|
+
processed_entries.push([filename, line])
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def self.find_xcodeproj_targets
|
132
|
+
xcodeprojects = Dir.glob("#{PodBuilder::home}/**/*.xcodeproj").select { |x| !x.include?("Pods.xcodeproj") && !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)
|
137
|
+
|
138
|
+
return project.targets
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|