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
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require 'pod_builder/core'
|
5
|
+
require 'pod_builder/version'
|
6
|
+
require 'pod_builder/command'
|
7
|
+
|
8
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
9
|
+
# with your gem easier. You can also use a different console, if you like.
|
10
|
+
|
11
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
12
|
+
# require "pry"
|
13
|
+
# Pry.start
|
14
|
+
|
15
|
+
require "irb"
|
16
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/exe/pod_builder
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
if ENV['RUBYLIB']
|
4
|
+
puts "Running in debug, injecting $LOAD_PATH"
|
5
|
+
libdir = File.expand_path("#{File.dirname(__FILE__)}/../lib")
|
6
|
+
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'optparse'
|
10
|
+
require 'pod_builder/core'
|
11
|
+
require 'pod_builder/version'
|
12
|
+
require 'pod_builder/command'
|
13
|
+
|
14
|
+
OPTIONS = {}
|
15
|
+
|
16
|
+
def parse_commandline()
|
17
|
+
subcommands = {
|
18
|
+
"none" => {
|
19
|
+
:opts => OptionParser.new do |opts|
|
20
|
+
opts.banner = "
|
21
|
+
Usage:
|
22
|
+
|
23
|
+
$ pod_builder COMMAND
|
24
|
+
|
25
|
+
Prebuild CocoaPods pods
|
26
|
+
|
27
|
+
Command:
|
28
|
+
+ init Initialize prebuild folders
|
29
|
+
+ deintegrate Deintegrate prebuild folders
|
30
|
+
+ build Build a specific pod declared in your Frameworks/Podfile
|
31
|
+
+ build_all Build all pods declared in your Frameworks/Podfile
|
32
|
+
+ restore_all Rebuild all pods declared in the Frameworks/Podfile.restore
|
33
|
+
+ install_sources Install sources of pods to debug into prebuild frameworks
|
34
|
+
+ clean Remove prebuild frameworks, dSYMs and source files added by install_sources no longer in Frameworks/Podfile
|
35
|
+
|
36
|
+
Options:
|
37
|
+
"
|
38
|
+
opts.on("-v", "--version", "Show the version of the tool") do |o|
|
39
|
+
OPTIONS[:version] = o
|
40
|
+
end
|
41
|
+
end,
|
42
|
+
:call => [
|
43
|
+
PodBuilder::Command::None
|
44
|
+
]
|
45
|
+
},
|
46
|
+
|
47
|
+
"build" => {
|
48
|
+
:opts => OptionParser.new do |opts|
|
49
|
+
opts.banner = "
|
50
|
+
Usage:
|
51
|
+
|
52
|
+
$ pod_builder build <PODNAME...>
|
53
|
+
|
54
|
+
Prebuild the specified CocoaPods pods
|
55
|
+
|
56
|
+
Options:
|
57
|
+
"
|
58
|
+
opts.on("-u", "--update", "Update CocoaPods repos") do |o|
|
59
|
+
OPTIONS[:update_repos] = o
|
60
|
+
end
|
61
|
+
opts.on("-d", "--debug", "Don't clean build folder") do |o|
|
62
|
+
OPTIONS[:debug] = o
|
63
|
+
end
|
64
|
+
end,
|
65
|
+
:call => [
|
66
|
+
PodBuilder::Command::Build
|
67
|
+
]
|
68
|
+
},
|
69
|
+
|
70
|
+
"build_all" => {
|
71
|
+
:opts => OptionParser.new do |opts|
|
72
|
+
opts.on("-u", "--update", "Update CocoaPods repos") do |o|
|
73
|
+
OPTIONS[:update_repos] = o
|
74
|
+
end
|
75
|
+
opts.on("-d", "--debug", "Don't clean build folder") do |o|
|
76
|
+
OPTIONS[:debug] = o
|
77
|
+
end
|
78
|
+
end,
|
79
|
+
:call => [
|
80
|
+
PodBuilder::Command::BuildAll
|
81
|
+
]
|
82
|
+
},
|
83
|
+
|
84
|
+
"restore_all" => {
|
85
|
+
:opts => OptionParser.new do |opts|
|
86
|
+
opts.on("-u", "--update", "Update CocoaPods repos") do |o|
|
87
|
+
OPTIONS[:update_repos] = o
|
88
|
+
end
|
89
|
+
opts.on("-d", "--debug", "Don't clean build folder") do |o|
|
90
|
+
OPTIONS[:debug] = o
|
91
|
+
end
|
92
|
+
end,
|
93
|
+
:call => [
|
94
|
+
PodBuilder::Command::RestoreAll
|
95
|
+
]
|
96
|
+
},
|
97
|
+
|
98
|
+
"init" => {
|
99
|
+
:opts => OptionParser.new do |opts|
|
100
|
+
default_destination = PodBuilder::xcodepath(PodBuilder::Configuration.base_path)
|
101
|
+
|
102
|
+
opts.on("-d", "--destination path", "Prebuilt destination path (defaul: #{default_destination})") do |o|
|
103
|
+
OPTIONS[:prebuild_path] = o
|
104
|
+
end
|
105
|
+
end,
|
106
|
+
:call => [
|
107
|
+
PodBuilder::Command::Init
|
108
|
+
]
|
109
|
+
},
|
110
|
+
|
111
|
+
"generate_podspec" => {
|
112
|
+
:opts => OptionParser.new do |opts|
|
113
|
+
end,
|
114
|
+
:call => [
|
115
|
+
PodBuilder::Command::GeneratePodspec
|
116
|
+
]
|
117
|
+
},
|
118
|
+
|
119
|
+
"deintegrate" => {
|
120
|
+
:opts => OptionParser.new do |opts|
|
121
|
+
end,
|
122
|
+
:call => [
|
123
|
+
PodBuilder::Command::Deintegrate
|
124
|
+
]
|
125
|
+
},
|
126
|
+
|
127
|
+
"clean" => {
|
128
|
+
:opts => OptionParser.new do |opts|
|
129
|
+
end,
|
130
|
+
:call => [
|
131
|
+
PodBuilder::Command::Clean
|
132
|
+
]
|
133
|
+
},
|
134
|
+
|
135
|
+
"install_sources" => {
|
136
|
+
:opts => OptionParser.new do |opts|
|
137
|
+
end,
|
138
|
+
:call => [
|
139
|
+
PodBuilder::Command::InstallSources
|
140
|
+
]
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
subcommands["none"][:opts].order!
|
145
|
+
|
146
|
+
subcommand = subcommands[ARGV.shift]
|
147
|
+
|
148
|
+
if subcommand
|
149
|
+
subcommand[:opts].order!
|
150
|
+
subcommand[:call].each do |k|
|
151
|
+
if !k.call(OPTIONS)
|
152
|
+
puts subcommand[:opts].help
|
153
|
+
end
|
154
|
+
end
|
155
|
+
else
|
156
|
+
if !subcommands["none"][:call].first&.call(OPTIONS)
|
157
|
+
puts subcommands["none"][:opts].help
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
begin
|
163
|
+
unless ENV['USER'] != "root"
|
164
|
+
raise "\n\nFor safety do not run this as root\n".red
|
165
|
+
end
|
166
|
+
|
167
|
+
PodBuilder::Configuration.load
|
168
|
+
parse_commandline
|
169
|
+
ensure
|
170
|
+
PodBuilder::clean_basepath
|
171
|
+
if !OPTIONS.has_key?(:debug)
|
172
|
+
PodBuilder::safe_rm_rf(PodBuilder::Configuration.build_path)
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'pod_builder/cocoapods/specification'
|
2
|
+
|
3
|
+
module PodBuilder
|
4
|
+
class Analyze
|
5
|
+
# @return [Pod::Installer] The Pod::Installer instance created by processing the Podfile
|
6
|
+
#
|
7
|
+
def self.installer_at(path, repo_update = false)
|
8
|
+
CLAide::Command::PluginManager.load_plugins("cocoapods")
|
9
|
+
|
10
|
+
current_dir = Dir.pwd
|
11
|
+
Dir.chdir(path)
|
12
|
+
|
13
|
+
config = Pod::Config.new()
|
14
|
+
installer = Pod::Installer.new(config.sandbox, config.podfile, config.lockfile)
|
15
|
+
installer.repo_update = repo_update
|
16
|
+
installer.update = false
|
17
|
+
|
18
|
+
analyzer = installer.resolve_dependencies
|
19
|
+
|
20
|
+
Dir.chdir(current_dir)
|
21
|
+
|
22
|
+
return installer, analyzer
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Array<PodfileItem>] The PodfileItem in the Podfile (including subspecs) and dependencies
|
26
|
+
#
|
27
|
+
def self.podfile_items(installer, analyzer)
|
28
|
+
sandbox = installer.sandbox
|
29
|
+
analysis_result = installer.analysis_result
|
30
|
+
|
31
|
+
all_podfile_pods = analysis_result.podfile_dependency_cache.podfile_dependencies
|
32
|
+
|
33
|
+
external_source_pods = all_podfile_pods.select(&:external_source)
|
34
|
+
checkout_options = external_source_pods.map { |x| [x.name, x.external_source] }.to_h
|
35
|
+
|
36
|
+
# this adds the :commit which might be missing in checkout_options
|
37
|
+
# will also overwrite :branch with :commit which is desired
|
38
|
+
checkout_options.merge!(analyzer.sandbox.checkout_sources)
|
39
|
+
|
40
|
+
all_specs = analysis_result.specifications
|
41
|
+
|
42
|
+
all_podfile_specs = all_specs.select { |x| all_podfile_pods.map(&:name).include?(x.name) }
|
43
|
+
|
44
|
+
deps_names = all_podfile_specs.map { |x| x.recursive_dep_names(all_specs) }.flatten.uniq
|
45
|
+
|
46
|
+
all_podfile_specs += all_specs.select { |x| deps_names.include?(x.name) }
|
47
|
+
all_podfile_specs.uniq!
|
48
|
+
|
49
|
+
return all_podfile_specs.map { |spec| PodfileItem.new(spec, all_specs, checkout_options) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Pod
|
2
|
+
class Installer
|
3
|
+
class Analyzer
|
4
|
+
def pods_and_deps_in_target(target_name, podfile_items)
|
5
|
+
target_name = "Pods-#{target_name}"
|
6
|
+
|
7
|
+
specs = result.specs_by_target.select { |key, value| key.label == target_name }.values.first
|
8
|
+
specs.select! { |x| podfile_items.map(&:name).include?(x.name) }
|
9
|
+
|
10
|
+
target_pods = []
|
11
|
+
specs.each do |spec|
|
12
|
+
pod = podfile_items.detect { |x| x.name == spec.name }
|
13
|
+
raise "Pod #{spec.name} not found while trying to build Podfile.restore!" if pod.nil?
|
14
|
+
target_pods.push(pod)
|
15
|
+
end
|
16
|
+
|
17
|
+
target_dependencies = target_pods.map { |x| x.dependencies(podfile_items) }.flatten.uniq
|
18
|
+
target_pods -= target_dependencies
|
19
|
+
|
20
|
+
return target_pods.uniq, target_dependencies.uniq
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Pod
|
2
|
+
class Specification
|
3
|
+
def recursive_dep_names(all_specs)
|
4
|
+
base_deps = all_dependencies.map(&:name)
|
5
|
+
|
6
|
+
loop do
|
7
|
+
last_deps_count = base_deps.count
|
8
|
+
|
9
|
+
all_specs.each do |s|
|
10
|
+
unless s != self
|
11
|
+
next
|
12
|
+
end
|
13
|
+
|
14
|
+
specs_deps = s.all_dependencies.map(&:name)
|
15
|
+
if base_deps.include?(s.name)
|
16
|
+
base_deps += specs_deps
|
17
|
+
base_deps.uniq!
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
break unless last_deps_count != base_deps.count
|
22
|
+
end
|
23
|
+
|
24
|
+
return base_deps
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'pod_builder/command/none'
|
2
|
+
require 'pod_builder/command/build'
|
3
|
+
require 'pod_builder/command/build_all'
|
4
|
+
require 'pod_builder/command/restore_all'
|
5
|
+
require 'pod_builder/command/init'
|
6
|
+
require 'pod_builder/command/clean'
|
7
|
+
require 'pod_builder/command/deintegrate'
|
8
|
+
require 'pod_builder/command/generate_podspec'
|
9
|
+
require 'pod_builder/command/install_sources'
|
@@ -0,0 +1,240 @@
|
|
1
|
+
require 'pod_builder/core'
|
2
|
+
require 'cfpropertylist'
|
3
|
+
|
4
|
+
module PodBuilder
|
5
|
+
module Command
|
6
|
+
class Build
|
7
|
+
def self.call(options)
|
8
|
+
Configuration.check_inited
|
9
|
+
PodBuilder::prepare_basepath
|
10
|
+
|
11
|
+
argument_pods = ARGV.dup
|
12
|
+
|
13
|
+
unless argument_pods.count > 0
|
14
|
+
return false
|
15
|
+
end
|
16
|
+
|
17
|
+
update_repo = options[:update_repos] || false
|
18
|
+
installer, analyzer = Analyze.installer_at(PodBuilder::basepath, update_repo)
|
19
|
+
|
20
|
+
all_buildable_items = Analyze.podfile_items(installer, analyzer)
|
21
|
+
prebuilt_items = all_buildable_items.select { |x| x.is_prebuilt }
|
22
|
+
buildable_items = all_buildable_items - prebuilt_items
|
23
|
+
|
24
|
+
if argument_pods.first == "*"
|
25
|
+
argument_pods = buildable_items.map(&:name)
|
26
|
+
end
|
27
|
+
|
28
|
+
argument_pods.select! { |x| buildable_items.map(&:name).include?(x) }
|
29
|
+
|
30
|
+
unless argument_pods.count > 0
|
31
|
+
puts "\n\nNo pods to build found, `#{ARGV.join(" ")}` is/are prebuilt\n".yellow
|
32
|
+
puts "\n\n🎉 done!\n".green
|
33
|
+
|
34
|
+
return true
|
35
|
+
end
|
36
|
+
|
37
|
+
check_pods_exists(argument_pods, buildable_items)
|
38
|
+
|
39
|
+
pods_to_build = buildable_items.select { |x| argument_pods.include?(x.name) }
|
40
|
+
pods_to_build += other_subspecs(pods_to_build, buildable_items)
|
41
|
+
|
42
|
+
buildable_items -= pods_to_build
|
43
|
+
|
44
|
+
check_no_common_dependencies(pods_to_build, buildable_items)
|
45
|
+
check_not_building_dependency(pods_to_build, buildable_items)
|
46
|
+
|
47
|
+
# Remove dependencies from pods to build
|
48
|
+
all_dependencies_name = pods_to_build.map(&:dependency_names).flatten.uniq
|
49
|
+
pods_to_build.select! { |x| !all_dependencies_name.include?(x.name) }
|
50
|
+
|
51
|
+
# We need to split pods to build in 3 groups
|
52
|
+
# 1. subspecs: because the resulting .framework path is treated differently
|
53
|
+
# 2. pods to build in release
|
54
|
+
# 3. pods to build in debug
|
55
|
+
|
56
|
+
pods_to_build_subspecs = pods_to_build.select { |x| x.is_subspec }
|
57
|
+
pods_to_build -= pods_to_build_subspecs
|
58
|
+
pods_to_build_debug = pods_to_build.select { |x| x.build_configuration == "debug" }
|
59
|
+
pods_to_build_release = pods_to_build - pods_to_build_debug
|
60
|
+
|
61
|
+
check_dependencies_build_configurations(all_buildable_items)
|
62
|
+
|
63
|
+
podfiles_items = pods_to_build_subspecs.map { |x| [x] }
|
64
|
+
podfiles_items.push(pods_to_build_debug)
|
65
|
+
podfiles_items.push(pods_to_build_release)
|
66
|
+
|
67
|
+
licenses = []
|
68
|
+
|
69
|
+
podfiles_items.select { |x| x.count > 0 }.each do |podfile_items|
|
70
|
+
podfile_items = add_dependencies(podfile_items, all_buildable_items)
|
71
|
+
podfile_content = Podfile.from_podfile_items(podfile_items, analyzer)
|
72
|
+
|
73
|
+
Install.podfile(podfile_content, podfile_items, podfile_items.first.build_configuration)
|
74
|
+
|
75
|
+
licenses += license_specifiers
|
76
|
+
|
77
|
+
# remove lockfile which gets unexplicably created
|
78
|
+
FileUtils.rm_f(PodBuilder::basepath("Podfile.lock"))
|
79
|
+
end
|
80
|
+
|
81
|
+
write_license_files(licenses, all_buildable_items)
|
82
|
+
|
83
|
+
Podspec::generate
|
84
|
+
|
85
|
+
builded_pods = podfiles_items.flatten
|
86
|
+
builded_pods_and_deps = add_dependencies(builded_pods, all_buildable_items).select { |x| !x.is_prebuilt }
|
87
|
+
Podfile::write_restorable(builded_pods, all_buildable_items, analyzer)
|
88
|
+
if !options.has_key?(:skip_prebuild_update)
|
89
|
+
Podfile::update_prebuilt(builded_pods_and_deps, all_buildable_items, analyzer)
|
90
|
+
end
|
91
|
+
|
92
|
+
Podfile::deintegrate_install
|
93
|
+
|
94
|
+
puts "\n\n🎉 done!\n".green
|
95
|
+
return true
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def self.license_specifiers
|
101
|
+
acknowledge_files = Dir.glob("#{PodBuilder::Configuration.build_path}/Pods/**/*acknowledgements.plist")
|
102
|
+
raise "Too many acknoledge file found" if acknowledge_files.count > 1
|
103
|
+
|
104
|
+
if acknowledge_file = acknowledge_files.first
|
105
|
+
plist = CFPropertyList::List.new(:file => acknowledge_file)
|
106
|
+
data = CFPropertyList.native_types(plist.value)
|
107
|
+
|
108
|
+
return data["PreferenceSpecifiers"]
|
109
|
+
end
|
110
|
+
|
111
|
+
return []
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.write_license_files(licenses, all_buildable_items)
|
115
|
+
license_file_path = PodBuilder::xcodepath(Configuration.license_file_name) + ".plist"
|
116
|
+
|
117
|
+
current_licenses = []
|
118
|
+
if File.exist?(license_file_path)
|
119
|
+
plist = CFPropertyList::List.new(:file => license_file_path)
|
120
|
+
dict = CFPropertyList.native_types(plist.value)
|
121
|
+
current_licenses = dict["PreferenceSpecifiers"]
|
122
|
+
current_licenses.shift
|
123
|
+
current_licenses.pop
|
124
|
+
end
|
125
|
+
|
126
|
+
licenses_header = licenses.shift
|
127
|
+
raise "Unexpected license found in header" if licenses_header.has_key?("License")
|
128
|
+
license_footer = licenses.pop
|
129
|
+
raise "Unexpected license found in footer" if license_footer.has_key?("License")
|
130
|
+
|
131
|
+
lincenses_titles = licenses.map { |x| x["Title"] }
|
132
|
+
current_licenses.select! { |x| !lincenses_titles.include?(x["Title"]) }
|
133
|
+
|
134
|
+
licenses += current_licenses # merge with existing license
|
135
|
+
licenses.uniq! { |x| x["Title"] }
|
136
|
+
licenses.sort_by! { |x| x["Title"] }
|
137
|
+
licenses.select! { |x| !Configuration.skip_licenses.include?(x["Title"]) }
|
138
|
+
licenses.select! { |x| all_buildable_items.map(&:root_name).include?(x["Title"]) } # Remove items that are no longer included
|
139
|
+
|
140
|
+
license_dict = {}
|
141
|
+
license_dict["PreferenceSpecifiers"] = [licenses_header, licenses, license_footer].flatten
|
142
|
+
license_dict["StringsTable"] = "Acknowledgements"
|
143
|
+
license_dict["Title"] = license_dict["StringsTable"]
|
144
|
+
|
145
|
+
plist = CFPropertyList::List.new
|
146
|
+
plist.value = CFPropertyList.guess(license_dict)
|
147
|
+
plist.save(license_file_path, CFPropertyList::List::FORMAT_BINARY)
|
148
|
+
|
149
|
+
write_markdown_licenses(license_file_path)
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.write_markdown_licenses(plist_path)
|
153
|
+
plist = CFPropertyList::List.new(:file => plist_path)
|
154
|
+
dict = CFPropertyList.native_types(plist.value)
|
155
|
+
licenses = dict["PreferenceSpecifiers"]
|
156
|
+
header = licenses.shift
|
157
|
+
|
158
|
+
markdown = []
|
159
|
+
markdown += ["# #{header["Title"]}", header["FooterText"], ""]
|
160
|
+
markdown += licenses.map { |x| ["## #{x["Title"]}", x["FooterText"], ""] }
|
161
|
+
|
162
|
+
markdown.flatten!
|
163
|
+
|
164
|
+
markdown_path = plist_path.chomp(File.extname(plist_path)) + ".md"
|
165
|
+
|
166
|
+
File.write(markdown_path, markdown.join("\n"))
|
167
|
+
end
|
168
|
+
|
169
|
+
def self.add_dependencies(pods, buildable_items)
|
170
|
+
pods.dup.each do |pod|
|
171
|
+
build_configuration = pods.first.build_configuration
|
172
|
+
|
173
|
+
dependencies = pod.dependencies(buildable_items).select { |x| !pods.include?(x) && !pod.has_common_spec(x.name) }
|
174
|
+
dependencies.each { |x| x.build_configuration = build_configuration }
|
175
|
+
pods = dependencies + pods # dependencies should come first
|
176
|
+
end
|
177
|
+
|
178
|
+
return pods
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.check_no_common_dependencies(pods_to_build, buildable_items)
|
182
|
+
pods_to_build.each do |pod_to_build|
|
183
|
+
pod_to_build.dependency_names.each do |dependency|
|
184
|
+
buildable_items.each do |buildable_pod|
|
185
|
+
unless !pod_to_build.dependency_names.include?(buildable_pod.name)
|
186
|
+
next
|
187
|
+
end
|
188
|
+
|
189
|
+
if buildable_pod.dependency_names.include?(dependency) && !buildable_pod.has_subspec(dependency) && !buildable_pod.has_common_spec(dependency) then
|
190
|
+
raise "\nCan't build #{pod_to_build.name} because it has common dependencies (#{dependency}) with #{buildable_pod.name}.\n\nUse `pod_builder build #{pods_to_build.map(&:name).join(" ")} #{buildable_pod.name}` instead\n\n".red
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def self.check_not_building_dependency(pods_to_build, buildable_items)
|
198
|
+
buildable_items_dependencies = buildable_items.map(&:dependency_names).flatten.uniq
|
199
|
+
pods_to_build.each do |pod_to_build|
|
200
|
+
if buildable_items_dependencies.include?(pod_to_build.name)
|
201
|
+
parent = buildable_items.detect { |x| x.dependency_names.include?(pod_to_build.name) }
|
202
|
+
raise "\nCan't build #{pod_to_build.name} because it is a dependency of #{parent.name}.\n\nUse `pod_builder build #{parent.name}` instead\n\n".red
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def self.check_pods_exists(pods, buildable_items)
|
208
|
+
raise "Empty Podfile?" if buildable_items.nil?
|
209
|
+
|
210
|
+
buildable_items = buildable_items.map(&:name)
|
211
|
+
pods.each do |pod|
|
212
|
+
raise "\nPod `#{pod}` wasn't found in Podfile.\n\nFound:\n#{buildable_items.join("\n")}\n\n".red if !buildable_items.include?(pod)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def self.check_dependencies_build_configurations(pods)
|
217
|
+
pods.each do |pod|
|
218
|
+
pod_dependency_names = pod.dependency_names.select { |x| !pod.has_common_spec(x) }
|
219
|
+
|
220
|
+
remaining_pods = pods - [pod]
|
221
|
+
pods_with_common_deps = remaining_pods.select { |x| x.dependency_names.any? { |y| pod_dependency_names.include?(y) && !x.has_common_spec(y) } }
|
222
|
+
|
223
|
+
pods_with_unaligned_build_configuration = pods_with_common_deps.select { |x| x.build_configuration != pod.build_configuration }
|
224
|
+
pods_with_unaligned_build_configuration.map!(&:name)
|
225
|
+
|
226
|
+
raise "Dependencies of `#{pod.name}` don't have the same build configuration (#{pod.build_configuration}) of `#{pods_with_unaligned_build_configuration.join(",")}`'s dependencies" if pods_with_unaligned_build_configuration.count > 0
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def self.other_subspecs(pods_to_build, buildable_items)
|
231
|
+
buildable_subspecs = buildable_items.select { |x| x.is_subspec }
|
232
|
+
pods_to_build_subspecs = pods_to_build.select { |x| x.is_subspec }.map(&:root_name)
|
233
|
+
|
234
|
+
buildable_subspecs.select! { |x| pods_to_build_subspecs.include?(x.root_name) }
|
235
|
+
|
236
|
+
return buildable_subspecs - pods_to_build
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|