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.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.vscode/launch.json +102 -0
  4. data/Example/PodBuilderExample.xcodeproj/project.pbxproj +416 -0
  5. data/Example/PodBuilderExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  6. data/Example/PodBuilderExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  7. data/Example/PodBuilderExample.xcodeproj/project.xcworkspace/xcuserdata/tomas.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  8. data/Example/PodBuilderExample.xcodeproj/xcuserdata/tomas.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
  9. data/Example/PodBuilderExample.xcworkspace/contents.xcworkspacedata +10 -0
  10. data/Example/PodBuilderExample/AppDelegate.swift +47 -0
  11. data/Example/PodBuilderExample/Assets.xcassets/AppIcon.appiconset/Contents.json +98 -0
  12. data/Example/PodBuilderExample/Assets.xcassets/Contents.json +6 -0
  13. data/Example/PodBuilderExample/Base.lproj/LaunchScreen.storyboard +25 -0
  14. data/Example/PodBuilderExample/Base.lproj/Main.storyboard +24 -0
  15. data/Example/PodBuilderExample/Info.plist +45 -0
  16. data/Example/PodBuilderExample/ViewController.swift +25 -0
  17. data/Example/Podfile +8 -0
  18. data/Example/Podfile.lock +16 -0
  19. data/Example/Pods/Alamofire/LICENSE +19 -0
  20. data/Example/Pods/Alamofire/README.md +242 -0
  21. data/Example/Pods/Alamofire/Source/AFError.swift +460 -0
  22. data/Example/Pods/Alamofire/Source/Alamofire.swift +465 -0
  23. data/Example/Pods/Alamofire/Source/DispatchQueue+Alamofire.swift +37 -0
  24. data/Example/Pods/Alamofire/Source/MultipartFormData.swift +580 -0
  25. data/Example/Pods/Alamofire/Source/NetworkReachabilityManager.swift +233 -0
  26. data/Example/Pods/Alamofire/Source/Notifications.swift +55 -0
  27. data/Example/Pods/Alamofire/Source/ParameterEncoding.swift +483 -0
  28. data/Example/Pods/Alamofire/Source/Request.swift +654 -0
  29. data/Example/Pods/Alamofire/Source/Response.swift +567 -0
  30. data/Example/Pods/Alamofire/Source/ResponseSerialization.swift +715 -0
  31. data/Example/Pods/Alamofire/Source/Result.swift +300 -0
  32. data/Example/Pods/Alamofire/Source/ServerTrustPolicy.swift +307 -0
  33. data/Example/Pods/Alamofire/Source/SessionDelegate.swift +725 -0
  34. data/Example/Pods/Alamofire/Source/SessionManager.swift +896 -0
  35. data/Example/Pods/Alamofire/Source/TaskDelegate.swift +466 -0
  36. data/Example/Pods/Alamofire/Source/Timeline.swift +136 -0
  37. data/Example/Pods/Alamofire/Source/Validation.swift +315 -0
  38. data/Example/Pods/Manifest.lock +16 -0
  39. data/Example/Pods/Pods.xcodeproj/project.pbxproj +673 -0
  40. data/Example/Pods/Pods.xcodeproj/xcuserdata/tomas.xcuserdatad/xcschemes/Alamofire.xcscheme +60 -0
  41. data/Example/Pods/Pods.xcodeproj/xcuserdata/tomas.xcuserdatad/xcschemes/Pods-PodBuilderExample.xcscheme +60 -0
  42. data/Example/Pods/Pods.xcodeproj/xcuserdata/tomas.xcuserdatad/xcschemes/xcschememanagement.plist +21 -0
  43. data/Example/Pods/Target Support Files/Alamofire/Alamofire-dummy.m +5 -0
  44. data/Example/Pods/Target Support Files/Alamofire/Alamofire-prefix.pch +12 -0
  45. data/Example/Pods/Target Support Files/Alamofire/Alamofire-umbrella.h +16 -0
  46. data/Example/Pods/Target Support Files/Alamofire/Alamofire.modulemap +6 -0
  47. data/Example/Pods/Target Support Files/Alamofire/Alamofire.xcconfig +9 -0
  48. data/Example/Pods/Target Support Files/Alamofire/Info.plist +26 -0
  49. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Info.plist +26 -0
  50. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-acknowledgements.markdown +26 -0
  51. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-acknowledgements.plist +58 -0
  52. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-dummy.m +5 -0
  53. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-frameworks.sh +153 -0
  54. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-resources.sh +118 -0
  55. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample-umbrella.h +16 -0
  56. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample.debug.xcconfig +11 -0
  57. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample.modulemap +6 -0
  58. data/Example/Pods/Target Support Files/Pods-PodBuilderExample/Pods-PodBuilderExample.release.xcconfig +11 -0
  59. data/Gemfile +6 -0
  60. data/Gemfile.lock +100 -0
  61. data/LICENSE.txt +13 -0
  62. data/README.md +192 -0
  63. data/Rakefile +2 -0
  64. data/bin/console +16 -0
  65. data/bin/setup +8 -0
  66. data/exe/pod_builder +174 -0
  67. data/lib/pod_builder/analyze.rb +52 -0
  68. data/lib/pod_builder/cocoapods/analyzer.rb +24 -0
  69. data/lib/pod_builder/cocoapods/specification.rb +27 -0
  70. data/lib/pod_builder/command.rb +9 -0
  71. data/lib/pod_builder/command/build.rb +240 -0
  72. data/lib/pod_builder/command/build_all.rb +15 -0
  73. data/lib/pod_builder/command/clean.rb +80 -0
  74. data/lib/pod_builder/command/deintegrate.rb +51 -0
  75. data/lib/pod_builder/command/generate_podspec.rb +17 -0
  76. data/lib/pod_builder/command/init.rb +86 -0
  77. data/lib/pod_builder/command/install_sources.rb +82 -0
  78. data/lib/pod_builder/command/none.rb +16 -0
  79. data/lib/pod_builder/command/restore_all.rb +30 -0
  80. data/lib/pod_builder/configuration.rb +91 -0
  81. data/lib/pod_builder/core.rb +74 -0
  82. data/lib/pod_builder/install.rb +105 -0
  83. data/lib/pod_builder/podfile.rb +207 -0
  84. data/lib/pod_builder/podfile/post_actions.rb +141 -0
  85. data/lib/pod_builder/podfile_item.rb +216 -0
  86. data/lib/pod_builder/podspec.rb +71 -0
  87. data/lib/pod_builder/templates/build_podfile.template +78 -0
  88. data/lib/pod_builder/templates/build_podspec.template +19 -0
  89. data/lib/pod_builder/version.rb +4 -0
  90. data/pod-builder.gemspec +36 -0
  91. 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