cocoapods 0.16.4 → 0.17.0.rc1
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/CHANGELOG.md +108 -0
- data/README.md +3 -3
- data/bin/pod +1 -1
- data/lib/cocoapods.rb +31 -31
- data/lib/cocoapods/command.rb +62 -107
- data/lib/cocoapods/command/inter_process_communication.rb +103 -0
- data/lib/cocoapods/command/list.rb +45 -44
- data/lib/cocoapods/command/outdated.rb +28 -25
- data/lib/cocoapods/command/project.rb +90 -0
- data/lib/cocoapods/command/push.rb +50 -32
- data/lib/cocoapods/command/repo.rb +125 -155
- data/lib/cocoapods/command/search.rb +23 -12
- data/lib/cocoapods/command/setup.rb +103 -64
- data/lib/cocoapods/command/spec.rb +329 -90
- data/lib/cocoapods/config.rb +197 -44
- data/lib/cocoapods/downloader.rb +47 -34
- data/lib/cocoapods/executable.rb +98 -41
- data/lib/cocoapods/external_sources.rb +325 -0
- data/lib/cocoapods/file_list.rb +8 -1
- data/lib/cocoapods/gem_version.rb +7 -0
- data/lib/cocoapods/generator/acknowledgements.rb +71 -7
- data/lib/cocoapods/generator/acknowledgements/markdown.rb +10 -9
- data/lib/cocoapods/generator/acknowledgements/plist.rb +9 -8
- data/lib/cocoapods/generator/copy_resources_script.rb +2 -2
- data/lib/cocoapods/generator/documentation.rb +153 -37
- data/lib/cocoapods/generator/prefix_header.rb +82 -0
- data/lib/cocoapods/generator/target_header.rb +58 -0
- data/lib/cocoapods/generator/xcconfig.rb +130 -0
- data/lib/cocoapods/hooks/installer_representation.rb +123 -0
- data/lib/cocoapods/hooks/library_representation.rb +79 -0
- data/lib/cocoapods/hooks/pod_representation.rb +74 -0
- data/lib/cocoapods/installer.rb +398 -147
- data/lib/cocoapods/installer/analyzer.rb +556 -0
- data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +253 -0
- data/lib/cocoapods/installer/file_references_installer.rb +179 -0
- data/lib/cocoapods/installer/pod_source_installer.rb +289 -0
- data/lib/cocoapods/installer/target_installer.rb +307 -112
- data/lib/cocoapods/installer/user_project_integrator.rb +140 -176
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +193 -0
- data/lib/cocoapods/library.rb +195 -0
- data/lib/cocoapods/open_uri.rb +16 -14
- data/lib/cocoapods/project.rb +175 -52
- data/lib/cocoapods/resolver.rb +151 -164
- data/lib/cocoapods/sandbox.rb +276 -54
- data/lib/cocoapods/sandbox/file_accessor.rb +210 -0
- data/lib/cocoapods/sandbox/headers_store.rb +96 -0
- data/lib/cocoapods/sandbox/path_list.rb +178 -0
- data/lib/cocoapods/sources_manager.rb +218 -0
- data/lib/cocoapods/user_interface.rb +82 -18
- data/lib/cocoapods/{command → user_interface}/error_report.rb +5 -5
- data/lib/cocoapods/validator.rb +379 -0
- metadata +74 -55
- data/lib/cocoapods/command/install.rb +0 -55
- data/lib/cocoapods/command/linter.rb +0 -317
- data/lib/cocoapods/command/update.rb +0 -25
- data/lib/cocoapods/dependency.rb +0 -285
- data/lib/cocoapods/downloader/git.rb +0 -276
- data/lib/cocoapods/downloader/http.rb +0 -99
- data/lib/cocoapods/downloader/mercurial.rb +0 -26
- data/lib/cocoapods/downloader/subversion.rb +0 -42
- data/lib/cocoapods/local_pod.rb +0 -620
- data/lib/cocoapods/lockfile.rb +0 -274
- data/lib/cocoapods/platform.rb +0 -127
- data/lib/cocoapods/podfile.rb +0 -551
- data/lib/cocoapods/source.rb +0 -223
- data/lib/cocoapods/specification.rb +0 -579
- data/lib/cocoapods/specification/set.rb +0 -175
- data/lib/cocoapods/specification/statistics.rb +0 -112
- data/lib/cocoapods/user_interface/ui_pod.rb +0 -130
- data/lib/cocoapods/version.rb +0 -26
data/lib/cocoapods/lockfile.rb
DELETED
@@ -1,274 +0,0 @@
|
|
1
|
-
require 'digest'
|
2
|
-
|
3
|
-
module Pod
|
4
|
-
class Lockfile
|
5
|
-
|
6
|
-
# @return [Lockfile] Returns the Lockfile saved in path.
|
7
|
-
# Returns {nil} If the file can't be loaded.
|
8
|
-
#
|
9
|
-
def self.from_file(path)
|
10
|
-
return nil unless path.exist?
|
11
|
-
begin
|
12
|
-
hash = YAML.load(File.open(path))
|
13
|
-
rescue Exception => e
|
14
|
-
raise Informative, "Podfile.lock syntax error: #{e.inspect}"
|
15
|
-
end
|
16
|
-
lockfile = Lockfile.new(hash)
|
17
|
-
lockfile.defined_in_file = path
|
18
|
-
lockfile
|
19
|
-
end
|
20
|
-
|
21
|
-
# @return [Lockfile] Generates a lockfile from a {Podfile} and the
|
22
|
-
# list of {Specifications} that were installed.
|
23
|
-
#
|
24
|
-
def self.generate(podfile, specs)
|
25
|
-
Lockfile.new(generate_hash_from_podfile(podfile, specs))
|
26
|
-
end
|
27
|
-
|
28
|
-
# @return [String] The file where this Lockfile is defined.
|
29
|
-
#
|
30
|
-
attr_accessor :defined_in_file
|
31
|
-
|
32
|
-
# @return [String] The hash used to initialize the Lockfile.
|
33
|
-
#
|
34
|
-
attr_reader :to_hash
|
35
|
-
|
36
|
-
# @param [Hash] hash A Hash representation of a Lockfile.
|
37
|
-
#
|
38
|
-
def initialize(hash)
|
39
|
-
@to_hash = hash
|
40
|
-
end
|
41
|
-
|
42
|
-
# @return [Array<String, Hash{String => Array[String]}>] The pods installed
|
43
|
-
# and their dependencies.
|
44
|
-
#
|
45
|
-
def pods
|
46
|
-
@pods ||= to_hash['PODS'] || []
|
47
|
-
end
|
48
|
-
|
49
|
-
# @return [Array<Dependency>] The Podfile dependencies used during the last
|
50
|
-
# install.
|
51
|
-
#
|
52
|
-
def dependencies
|
53
|
-
@dependencies ||= to_hash['DEPENDENCIES'].map { |dep| dependency_from_string(dep) } || []
|
54
|
-
end
|
55
|
-
|
56
|
-
# @return [Hash{String => Hash}] A hash where the name of the pods are
|
57
|
-
# the keys and the values are the parameters of an {AbstractExternalSource}
|
58
|
-
# of the dependency that required the pod.
|
59
|
-
#
|
60
|
-
def external_sources
|
61
|
-
@external_sources ||= to_hash["EXTERNAL SOURCES"] || {}
|
62
|
-
end
|
63
|
-
|
64
|
-
# @return [Array<String>] The names of the installed Pods.
|
65
|
-
#
|
66
|
-
def pods_names
|
67
|
-
@pods_names ||= pods.map do |pod|
|
68
|
-
pod = pod.keys.first unless pod.is_a?(String)
|
69
|
-
name_and_version_for_pod(pod)[0]
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
# @return [Hash{String => Version}] A Hash containing the name
|
74
|
-
# of the installed Pods as the keys and their corresponding {Version}
|
75
|
-
# as the values.
|
76
|
-
#
|
77
|
-
def pods_versions
|
78
|
-
unless @pods_versions
|
79
|
-
@pods_versions = {}
|
80
|
-
pods.each do |pod|
|
81
|
-
pod = pod.keys.first unless pod.is_a?(String)
|
82
|
-
name, version = name_and_version_for_pod(pod)
|
83
|
-
@pods_versions[name] = version
|
84
|
-
end
|
85
|
-
end
|
86
|
-
@pods_versions
|
87
|
-
end
|
88
|
-
|
89
|
-
# @return [Dependency] A dependency that describes the exact installed version
|
90
|
-
# of a Pod.
|
91
|
-
#
|
92
|
-
def dependency_for_installed_pod_named(name)
|
93
|
-
version = pods_versions[name]
|
94
|
-
raise Informative, "Attempt to lock a Pod without an known version." unless version
|
95
|
-
dependency = Dependency.new(name, version)
|
96
|
-
if external_source = external_sources[name]
|
97
|
-
dependency.external_source = Dependency::ExternalSources.from_params(dependency.name, external_source)
|
98
|
-
end
|
99
|
-
dependency
|
100
|
-
end
|
101
|
-
|
102
|
-
# @param [String] The string that describes a {Specification} generated
|
103
|
-
# from {Specification#to_s}.
|
104
|
-
#
|
105
|
-
# @example Strings examples
|
106
|
-
# "libPusher"
|
107
|
-
# "libPusher (1.0)"
|
108
|
-
# "libPusher (HEAD based on 1.0)"
|
109
|
-
# "RestKit/JSON"
|
110
|
-
#
|
111
|
-
# @return [String, Version] The name and the version of a
|
112
|
-
# pod.
|
113
|
-
#
|
114
|
-
def name_and_version_for_pod(string)
|
115
|
-
match_data = string.match(/(\S*) \((.*)\)/)
|
116
|
-
name = match_data[1]
|
117
|
-
vers = Version.from_string(match_data[2])
|
118
|
-
[name, vers]
|
119
|
-
end
|
120
|
-
|
121
|
-
# @param [String] The string that describes a {Dependency} generated
|
122
|
-
# from {Dependency#to_s}.
|
123
|
-
#
|
124
|
-
# @example Strings examples
|
125
|
-
# "libPusher"
|
126
|
-
# "libPusher (= 1.0)"
|
127
|
-
# "libPusher (~> 1.0.1)"
|
128
|
-
# "libPusher (> 1.0, < 2.0)"
|
129
|
-
# "libPusher (HEAD)"
|
130
|
-
# "libPusher (from `www.example.com')"
|
131
|
-
# "libPusher (defined in Podfile)"
|
132
|
-
# "RestKit/JSON"
|
133
|
-
#
|
134
|
-
# @return [Dependency] The dependency described by the string.
|
135
|
-
#
|
136
|
-
def dependency_from_string(string)
|
137
|
-
match_data = string.match(/(\S*)( (.*))?/)
|
138
|
-
name = match_data[1]
|
139
|
-
version = match_data[2]
|
140
|
-
version = version.gsub(/[()]/,'') if version
|
141
|
-
case version
|
142
|
-
when nil
|
143
|
-
Dependency.new(name)
|
144
|
-
when /defined in Podfile/
|
145
|
-
# @TODO: store the whole spec?, the version?
|
146
|
-
Dependency.new(name)
|
147
|
-
when /from `(.*)'/
|
148
|
-
external_source_info = external_sources[name]
|
149
|
-
Dependency.new(name, external_source_info)
|
150
|
-
when /HEAD/
|
151
|
-
# @TODO: find a way to serialize from the Downloader the information
|
152
|
-
# necessary to restore a head version.
|
153
|
-
Dependency.new(name, :head)
|
154
|
-
else
|
155
|
-
Dependency.new(name, version)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
# Analyzes the {Lockfile} and detects any changes applied to the {Podfile}
|
160
|
-
# since the last installation.
|
161
|
-
#
|
162
|
-
# For each Pod, it detects one state among the following:
|
163
|
-
#
|
164
|
-
# - added: Pods that weren't present in the Podfile.
|
165
|
-
# - changed: Pods that were present in the Podfile but changed:
|
166
|
-
# - Pods whose version is not compatible anymore with Podfile,
|
167
|
-
# - Pods that changed their head or external options.
|
168
|
-
# - removed: Pods that were removed form the Podfile.
|
169
|
-
# - unchanged: Pods that are still compatible with Podfile.
|
170
|
-
#
|
171
|
-
# @TODO: detect changes for inline dependencies?
|
172
|
-
#
|
173
|
-
# @return [Hash{Symbol=>Array[Strings]}] A hash where pods are grouped
|
174
|
-
# by the state in which they are.
|
175
|
-
#
|
176
|
-
def detect_changes_with_podfile(podfile)
|
177
|
-
previous_podfile_deps = dependencies.map(&:name)
|
178
|
-
user_installed_pods = pods_names.reject { |name| !previous_podfile_deps.include?(name) }
|
179
|
-
deps_to_install = podfile.dependencies.dup
|
180
|
-
|
181
|
-
result = {}
|
182
|
-
result[:added] = []
|
183
|
-
result[:changed] = []
|
184
|
-
result[:removed] = []
|
185
|
-
result[:unchanged] = []
|
186
|
-
|
187
|
-
user_installed_pods.each do |pod_name|
|
188
|
-
dependency = deps_to_install.find { |d| d.name == pod_name }
|
189
|
-
deps_to_install.delete(dependency)
|
190
|
-
version = pods_versions[pod_name]
|
191
|
-
external_source = Dependency::ExternalSources.from_params(pod_name, external_sources[pod_name])
|
192
|
-
|
193
|
-
if dependency.nil?
|
194
|
-
result[:removed] << pod_name
|
195
|
-
elsif dependency.inline? || !dependency.match_version?(version) || dependency.external_source != external_source
|
196
|
-
result[:changed] << pod_name
|
197
|
-
else
|
198
|
-
result[:unchanged] << pod_name
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
deps_to_install.each do |dependency|
|
203
|
-
result[:added] << dependency.name
|
204
|
-
end
|
205
|
-
result
|
206
|
-
end
|
207
|
-
|
208
|
-
# @return [void] Writes the Lockfile to {#path}.
|
209
|
-
#
|
210
|
-
def write_to_disk(path)
|
211
|
-
path.dirname.mkpath unless path.dirname.exist?
|
212
|
-
File.open(path, 'w') {|f| f.write(to_yaml) }
|
213
|
-
defined_in_file = path
|
214
|
-
end
|
215
|
-
|
216
|
-
# @return [String] A string useful to represent the Lockfile in a message
|
217
|
-
# presented to the user.
|
218
|
-
#
|
219
|
-
def to_s
|
220
|
-
"Podfile.lock"
|
221
|
-
end
|
222
|
-
|
223
|
-
# @return [String] The YAML representation of the Lockfile, used for
|
224
|
-
# serialization.
|
225
|
-
#
|
226
|
-
def to_yaml
|
227
|
-
to_hash.to_yaml.gsub(/^--- ?\n/,"").gsub(/^([A-Z])/,"\n\\1")
|
228
|
-
end
|
229
|
-
|
230
|
-
# @return [Hash] The Hash representation of the Lockfile generated from
|
231
|
-
# a given Podfile and the list of resolved Specifications.
|
232
|
-
#
|
233
|
-
def self.generate_hash_from_podfile(podfile, specs)
|
234
|
-
hash = {}
|
235
|
-
|
236
|
-
# Get list of [name, dependencies] pairs.
|
237
|
-
pod_and_deps = specs.map do |spec|
|
238
|
-
[spec.to_s, spec.dependencies.map(&:to_s).sort]
|
239
|
-
end.uniq
|
240
|
-
|
241
|
-
# Merge dependencies of iOS and OS X version of the same pod.
|
242
|
-
tmp = {}
|
243
|
-
pod_and_deps.each do |name, deps|
|
244
|
-
if tmp[name]
|
245
|
-
tmp[name].concat(deps).uniq!
|
246
|
-
else
|
247
|
-
tmp[name] = deps
|
248
|
-
end
|
249
|
-
end
|
250
|
-
pod_and_deps = tmp.sort_by(&:first).map do |name, deps|
|
251
|
-
deps.empty? ? name : { name => deps }
|
252
|
-
end
|
253
|
-
hash["PODS"] = pod_and_deps
|
254
|
-
|
255
|
-
hash["DEPENDENCIES"] = podfile.dependencies.map{ |d| d.to_s }.sort
|
256
|
-
|
257
|
-
external_sources = {}
|
258
|
-
deps = podfile.dependencies.select(&:external?).sort{ |d, other| d.name <=> other.name}
|
259
|
-
deps.each{ |d| external_sources[d.name] = d.external_source.params }
|
260
|
-
hash["EXTERNAL SOURCES"] = external_sources unless external_sources.empty?
|
261
|
-
|
262
|
-
checksums = {}
|
263
|
-
specs.select { |spec| !spec.defined_in_file.nil? }.each do |spec|
|
264
|
-
checksum = Digest::SHA1.hexdigest(File.read(spec.defined_in_file))
|
265
|
-
checksum = checksum.encode('UTF-8') if checksum.respond_to?(:encode)
|
266
|
-
checksums[spec.name] = checksum
|
267
|
-
end
|
268
|
-
hash["SPEC CHECKSUMS"] = checksums unless checksums.empty?
|
269
|
-
hash["COCOAPODS"] = VERSION
|
270
|
-
hash
|
271
|
-
end
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
data/lib/cocoapods/platform.rb
DELETED
@@ -1,127 +0,0 @@
|
|
1
|
-
module Pod
|
2
|
-
|
3
|
-
# A platform describes an SDK name and deployment target.
|
4
|
-
#
|
5
|
-
class Platform
|
6
|
-
|
7
|
-
# @return [Platform] Convenience method to initialize an iOS platform.
|
8
|
-
#
|
9
|
-
def self.ios
|
10
|
-
new :ios
|
11
|
-
end
|
12
|
-
|
13
|
-
# @return [Platform] Convenience method to initialize an OS X platform.
|
14
|
-
#
|
15
|
-
def self.osx
|
16
|
-
new :osx
|
17
|
-
end
|
18
|
-
|
19
|
-
# Constructs a platform from either another platform or by
|
20
|
-
# specifying the symbolic name and optionally the deployment target.
|
21
|
-
#
|
22
|
-
# @overload initialize(name, deployment_target)
|
23
|
-
# @param [Symbol] name The name of platform.
|
24
|
-
# @param [String, Version] deployment_target The optional deployment.
|
25
|
-
# If not provided a default value according to the platform name will
|
26
|
-
# be assigned.
|
27
|
-
#
|
28
|
-
# @note that if the name is not specified a default deployment
|
29
|
-
# target will not be assigned.
|
30
|
-
#
|
31
|
-
# @example
|
32
|
-
#
|
33
|
-
# Platform.new(:ios)
|
34
|
-
# Platform.new(:ios, '4.3')
|
35
|
-
#
|
36
|
-
# @overload initialize(platform)
|
37
|
-
# @param [Platform] platform Another {Platform}.
|
38
|
-
#
|
39
|
-
# @example
|
40
|
-
#
|
41
|
-
# platform = Platform.new(:ios)
|
42
|
-
# Platform.new(platform)
|
43
|
-
#
|
44
|
-
def initialize(input, target = nil)
|
45
|
-
if input.is_a? Platform
|
46
|
-
@symbolic_name = input.name
|
47
|
-
@deployment_target = input.deployment_target
|
48
|
-
else
|
49
|
-
@symbolic_name = input
|
50
|
-
target = target[:deployment_target] if target.is_a?(Hash)
|
51
|
-
@deployment_target = Version.create(target)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# @return [Symbol] The name of the SDK represented by the platform.
|
56
|
-
#
|
57
|
-
def name
|
58
|
-
@symbolic_name
|
59
|
-
end
|
60
|
-
|
61
|
-
# @return [Version] The deployment target of the platform.
|
62
|
-
#
|
63
|
-
attr_reader :deployment_target
|
64
|
-
|
65
|
-
# @param [Platform, Symbol] other The other platform to check.
|
66
|
-
#
|
67
|
-
# @note If a symbol is passed the comparison does not take into account
|
68
|
-
# the deployment target.
|
69
|
-
#
|
70
|
-
# @return [Boolean] Whether two platforms are the equivalent.
|
71
|
-
#
|
72
|
-
def ==(other)
|
73
|
-
if other.is_a?(Symbol)
|
74
|
-
@symbolic_name == other
|
75
|
-
else
|
76
|
-
(name == other.name) && (deployment_target == other.deployment_target)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# In the context of operating system SDKs, a platform supports another
|
81
|
-
# one if they have the same name and the other platform has a minor or
|
82
|
-
# equal deployment target.
|
83
|
-
#
|
84
|
-
# @return Whether the platform supports another platform.
|
85
|
-
#
|
86
|
-
def supports?(other)
|
87
|
-
other = Platform.new(other)
|
88
|
-
if other.deployment_target && deployment_target
|
89
|
-
(other.name == name) && (other.deployment_target <= deployment_target)
|
90
|
-
else
|
91
|
-
other.name == name
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
# @return [String] A string representation including the deployment target.
|
96
|
-
#
|
97
|
-
def to_s
|
98
|
-
case @symbolic_name
|
99
|
-
when :ios
|
100
|
-
s = 'iOS'
|
101
|
-
when :osx
|
102
|
-
s = 'OS X'
|
103
|
-
end
|
104
|
-
s << " #{deployment_target}" if deployment_target
|
105
|
-
s
|
106
|
-
end
|
107
|
-
|
108
|
-
# @return [Symbol] A Symbol representation of the name.
|
109
|
-
#
|
110
|
-
def to_sym
|
111
|
-
name
|
112
|
-
end
|
113
|
-
|
114
|
-
# @return Whether the platform requires legacy architectures for iOS.
|
115
|
-
#
|
116
|
-
def requires_legacy_ios_archs?
|
117
|
-
(name == :ios) && deployment_target && (deployment_target < Version.new("4.3"))
|
118
|
-
end
|
119
|
-
|
120
|
-
def deployment_target_setting_name
|
121
|
-
case @symbolic_name
|
122
|
-
when :ios then 'IPHONEOS_DEPLOYMENT_TARGET'
|
123
|
-
when :osx then 'MACOSX_DEPLOYMENT_TARGET'
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
data/lib/cocoapods/podfile.rb
DELETED
@@ -1,551 +0,0 @@
|
|
1
|
-
module Pod
|
2
|
-
class Podfile
|
3
|
-
class Informative < ::Pod::Informative
|
4
|
-
def podfile_line
|
5
|
-
@podfile_line ||= self.backtrace.find {|t| t =~ /Podfile/}
|
6
|
-
end
|
7
|
-
|
8
|
-
def message
|
9
|
-
if podfile_line
|
10
|
-
super + " (#{podfile_line})\n".red
|
11
|
-
else
|
12
|
-
super
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
class UserProject
|
18
|
-
include Config::Mixin
|
19
|
-
|
20
|
-
DEFAULT_BUILD_CONFIGURATIONS = { 'Debug' => :debug, 'Release' => :release }.freeze
|
21
|
-
|
22
|
-
def initialize(path = nil, build_configurations = {})
|
23
|
-
self.path = path if path
|
24
|
-
@build_configurations = build_configurations.merge(DEFAULT_BUILD_CONFIGURATIONS)
|
25
|
-
end
|
26
|
-
|
27
|
-
def path=(path)
|
28
|
-
path = path.to_s
|
29
|
-
@path = Pathname.new(File.extname(path) == '.xcodeproj' ? path : "#{path}.xcodeproj")
|
30
|
-
@path = config.project_root + @path unless @path.absolute?
|
31
|
-
@path
|
32
|
-
end
|
33
|
-
|
34
|
-
def path
|
35
|
-
if @path
|
36
|
-
@path
|
37
|
-
else
|
38
|
-
xcodeprojs = Pathname.glob(config.project_root + '*.xcodeproj')
|
39
|
-
if xcodeprojs.size == 1
|
40
|
-
@path = xcodeprojs.first
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def project
|
46
|
-
Xcodeproj::Project.new(path) if path && path.exist?
|
47
|
-
end
|
48
|
-
|
49
|
-
def build_configurations
|
50
|
-
if project
|
51
|
-
project.build_configurations.map(&:name).inject({}) do |hash, name|
|
52
|
-
hash[name] = :release; hash
|
53
|
-
end.merge(@build_configurations)
|
54
|
-
else
|
55
|
-
@build_configurations
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
class TargetDefinition
|
61
|
-
include Config::Mixin
|
62
|
-
|
63
|
-
attr_reader :name, :target_dependencies
|
64
|
-
|
65
|
-
attr_accessor :user_project, :link_with, :platform, :parent, :exclusive, :inhibit_all_warnings
|
66
|
-
|
67
|
-
def initialize(name, options = {})
|
68
|
-
@name, @target_dependencies = name, []
|
69
|
-
@parent, @exclusive = options.values_at(:parent, :exclusive)
|
70
|
-
end
|
71
|
-
|
72
|
-
# A target is automatically `exclusive` if the `platform` does not match
|
73
|
-
# the parent's `platform`.
|
74
|
-
def exclusive
|
75
|
-
if @exclusive.nil?
|
76
|
-
if @platform.nil?
|
77
|
-
false
|
78
|
-
else
|
79
|
-
@parent.platform != @platform
|
80
|
-
end
|
81
|
-
else
|
82
|
-
@exclusive
|
83
|
-
end
|
84
|
-
end
|
85
|
-
alias_method :exclusive?, :exclusive
|
86
|
-
|
87
|
-
def user_project
|
88
|
-
@user_project || @parent.user_project
|
89
|
-
end
|
90
|
-
|
91
|
-
def link_with=(targets)
|
92
|
-
@link_with = targets.is_a?(Array) ? targets : [targets]
|
93
|
-
end
|
94
|
-
|
95
|
-
def platform
|
96
|
-
@platform || (@parent.platform if @parent)
|
97
|
-
end
|
98
|
-
|
99
|
-
def inhibit_all_warnings
|
100
|
-
@inhibit_all_warnings.nil? ? (@parent.inhibit_all_warnings? if @parent) : @inhibit_all_warnings
|
101
|
-
end
|
102
|
-
alias_method :inhibit_all_warnings?, :inhibit_all_warnings
|
103
|
-
|
104
|
-
def label
|
105
|
-
if name == :default
|
106
|
-
"Pods"
|
107
|
-
elsif exclusive?
|
108
|
-
"Pods-#{name}"
|
109
|
-
else
|
110
|
-
"#{@parent.label}-#{name}"
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def acknowledgements_path
|
115
|
-
config.project_pods_root + "#{label}-Acknowledgements"
|
116
|
-
end
|
117
|
-
|
118
|
-
# Returns a path, which is relative to the project_root, relative to the
|
119
|
-
# `$(SRCROOT)` of the user's project.
|
120
|
-
def relative_to_srcroot(path)
|
121
|
-
if user_project.path.nil?
|
122
|
-
# TODO this is not in the right place
|
123
|
-
raise Informative, "[!] Unable to find an Xcode project to integrate".red if config.integrate_targets
|
124
|
-
path
|
125
|
-
else
|
126
|
-
(config.project_root + path).relative_path_from(user_project.path.dirname)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
def relative_pods_root
|
131
|
-
"${SRCROOT}/#{relative_to_srcroot "Pods"}"
|
132
|
-
end
|
133
|
-
|
134
|
-
def lib_name
|
135
|
-
"lib#{label}.a"
|
136
|
-
end
|
137
|
-
|
138
|
-
def xcconfig_name
|
139
|
-
"#{label}.xcconfig"
|
140
|
-
end
|
141
|
-
|
142
|
-
def xcconfig_relative_path
|
143
|
-
relative_to_srcroot("Pods/#{xcconfig_name}").to_s
|
144
|
-
end
|
145
|
-
|
146
|
-
attr_accessor :xcconfig
|
147
|
-
|
148
|
-
def copy_resources_script_name
|
149
|
-
"#{label}-resources.sh"
|
150
|
-
end
|
151
|
-
|
152
|
-
def copy_resources_script_relative_path
|
153
|
-
"${SRCROOT}/#{relative_to_srcroot("Pods/#{copy_resources_script_name}")}"
|
154
|
-
end
|
155
|
-
|
156
|
-
def prefix_header_name
|
157
|
-
"#{label}-prefix.pch"
|
158
|
-
end
|
159
|
-
|
160
|
-
def bridge_support_name
|
161
|
-
"#{label}.bridgesupport"
|
162
|
-
end
|
163
|
-
|
164
|
-
# Returns *all* dependencies of this target, not only the target specific
|
165
|
-
# ones in `target_dependencies`.
|
166
|
-
def dependencies
|
167
|
-
@target_dependencies + (exclusive? ? [] : @parent.dependencies)
|
168
|
-
end
|
169
|
-
|
170
|
-
def empty?
|
171
|
-
target_dependencies.empty?
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
def self.from_file(path)
|
176
|
-
podfile = Podfile.new do
|
177
|
-
string = File.open(path, 'r:utf-8') { |f| f.read }
|
178
|
-
# TODO: work around for Rubinius incomplete encoding in 1.9 mode
|
179
|
-
string.encode!('UTF-8') if string.respond_to?(:encoding) && string.encoding.name != "UTF-8"
|
180
|
-
begin
|
181
|
-
eval(string, nil, path.to_s)
|
182
|
-
rescue Exception => e
|
183
|
-
raise Informative, "Podfile syntax error: #{e.inspect}"
|
184
|
-
end
|
185
|
-
end
|
186
|
-
podfile.defined_in_file = path
|
187
|
-
podfile.validate!
|
188
|
-
podfile
|
189
|
-
end
|
190
|
-
|
191
|
-
include Config::Mixin
|
192
|
-
|
193
|
-
def initialize(&block)
|
194
|
-
@target_definition = TargetDefinition.new(:default, :exclusive => true)
|
195
|
-
@target_definition.user_project = UserProject.new
|
196
|
-
@target_definitions = { :default => @target_definition }
|
197
|
-
instance_eval(&block)
|
198
|
-
end
|
199
|
-
|
200
|
-
# Specifies the platform for which a static library should be build.
|
201
|
-
# This can be either `:osx` for Mac OS X applications, or `:ios` for iOS
|
202
|
-
# applications.
|
203
|
-
#
|
204
|
-
# @param [Symbol] name The name of platform.
|
205
|
-
# @param [String, Version] target The optional deployment.
|
206
|
-
# If not provided a default value according to the platform name will
|
207
|
-
# be assigned.
|
208
|
-
#
|
209
|
-
# @example
|
210
|
-
#
|
211
|
-
# platform :ios, "4.0"
|
212
|
-
# platform :ios
|
213
|
-
#
|
214
|
-
# @note If the deployment target requires it (< 4.3), armv6 will be added
|
215
|
-
# to ARCHS.
|
216
|
-
#
|
217
|
-
def platform(name, target = nil)
|
218
|
-
# Support for deprecated options parameter
|
219
|
-
target = target[:deployment_target] if target.is_a?(Hash)
|
220
|
-
|
221
|
-
unless target
|
222
|
-
case name
|
223
|
-
when :ios
|
224
|
-
target = '4.3'
|
225
|
-
when :osx
|
226
|
-
target = '10.6'
|
227
|
-
else
|
228
|
-
raise ::Pod::Podfile::Informative, "Unsupported platform: platform must be one of [:ios, :osx]"
|
229
|
-
end
|
230
|
-
end
|
231
|
-
@target_definition.platform = Platform.new(name, target)
|
232
|
-
end
|
233
|
-
|
234
|
-
# Specifies the Xcode workspace that should contain all the projects.
|
235
|
-
#
|
236
|
-
# If no explicit Xcode workspace is specified and only **one** project exists
|
237
|
-
# in the same directory as the Podfile, then the name of that project is used
|
238
|
-
# as the workspace’s name.
|
239
|
-
#
|
240
|
-
# @example
|
241
|
-
#
|
242
|
-
# workspace 'MyWorkspace'
|
243
|
-
#
|
244
|
-
def workspace(path = nil)
|
245
|
-
if path
|
246
|
-
@workspace = config.project_root + (File.extname(path) == '.xcworkspace' ? path : "#{path}.xcworkspace")
|
247
|
-
elsif @workspace
|
248
|
-
@workspace
|
249
|
-
else
|
250
|
-
projects = @target_definitions.map { |_, td| td.user_project.path }.uniq
|
251
|
-
if projects.size == 1 && (xcodeproj = @target_definitions[:default].user_project.path)
|
252
|
-
config.project_root + "#{xcodeproj.basename('.xcodeproj')}.xcworkspace"
|
253
|
-
end
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
# Specifies the Xcode project that contains the target that the Pods library
|
258
|
-
# should be linked with.
|
259
|
-
#
|
260
|
-
# If no explicit project is specified, it will use the Xcode project of the
|
261
|
-
# parent target. If none of the target definitions specify an explicit project
|
262
|
-
# and there is only **one** project in the same directory as the Podfile then
|
263
|
-
# that project will be used.
|
264
|
-
#
|
265
|
-
# @example
|
266
|
-
#
|
267
|
-
# # Look for target to link with in an Xcode project called ‘MyProject.xcodeproj’.
|
268
|
-
# xcodeproj 'MyProject'
|
269
|
-
#
|
270
|
-
# target :test do
|
271
|
-
# # This Pods library links with a target in another project.
|
272
|
-
# xcodeproj 'TestProject'
|
273
|
-
# end
|
274
|
-
#
|
275
|
-
def xcodeproj(path, build_configurations = {})
|
276
|
-
@target_definition.user_project = UserProject.new(path, build_configurations)
|
277
|
-
end
|
278
|
-
|
279
|
-
# Specifies the target(s) in the user’s project that this Pods library
|
280
|
-
# should be linked in.
|
281
|
-
#
|
282
|
-
# If no explicit target is specified, then the Pods target will be linked
|
283
|
-
# with the first target in your project. So if you only have one target you
|
284
|
-
# do not need to specify the target to link with.
|
285
|
-
#
|
286
|
-
# @example
|
287
|
-
#
|
288
|
-
# # Link with a target called ‘MyApp’ (in the user's project).
|
289
|
-
# link_with 'MyApp'
|
290
|
-
#
|
291
|
-
# # Link with the targets in the user’s project called ‘MyApp’ and ‘MyOtherApp’.
|
292
|
-
# link_with ['MyApp', 'MyOtherApp']
|
293
|
-
#
|
294
|
-
def link_with(targets)
|
295
|
-
@target_definition.link_with = targets
|
296
|
-
end
|
297
|
-
|
298
|
-
# Inhibits **all** warnings from the Pods library.
|
299
|
-
#
|
300
|
-
# When used, this is applied to all targets inheriting from the current one.
|
301
|
-
def inhibit_all_warnings!
|
302
|
-
@target_definition.inhibit_all_warnings = true
|
303
|
-
end
|
304
|
-
|
305
|
-
# Specifies a dependency of the project.
|
306
|
-
#
|
307
|
-
# A dependency requirement is defined by the name of the Pod and _optionally_
|
308
|
-
# a list of version requirements.
|
309
|
-
#
|
310
|
-
#
|
311
|
-
# When starting out with a project it is likely that you will want to use the
|
312
|
-
# latest version of a Pod. If this is the case, simply omit the version
|
313
|
-
# requirements.
|
314
|
-
#
|
315
|
-
# pod 'SSZipArchive'
|
316
|
-
#
|
317
|
-
#
|
318
|
-
# Later on in the project you may want to freeze to a specific version of a
|
319
|
-
# Pod, in which case you can specify that version number.
|
320
|
-
#
|
321
|
-
# pod 'Objection', '0.9'
|
322
|
-
#
|
323
|
-
#
|
324
|
-
# Besides no version, or a specific one, it is also possible to use operators:
|
325
|
-
#
|
326
|
-
# * `> 0.1` Any version higher than 0.1
|
327
|
-
# * `>= 0.1` Version 0.1 and any higher version
|
328
|
-
# * `< 0.1` Any version lower than 0.1
|
329
|
-
# * `<= 0.1` Version 0.1 and any lower version
|
330
|
-
# * `~> 0.1.2` Version 0.1.2 and the versions upto 0.2, not including 0.2
|
331
|
-
#
|
332
|
-
# A list of version requirements can be specified for even more fine
|
333
|
-
# grained control.
|
334
|
-
#
|
335
|
-
#
|
336
|
-
# For more information, regarding versioning policy, see:
|
337
|
-
#
|
338
|
-
# * http://semver.org
|
339
|
-
# * http://docs.rubygems.org/read/chapter/7
|
340
|
-
#
|
341
|
-
#
|
342
|
-
# Finally, instead of a version, you can specify the `:head` flag. This will
|
343
|
-
# use the pod’s latest version spec version, but force the download of the
|
344
|
-
# ‘bleeding edge’ version. Use this with caution, as the spec might not be
|
345
|
-
# compatible anymore.
|
346
|
-
#
|
347
|
-
#
|
348
|
-
# ## Dependency on a library, outside those available in a spec repo.
|
349
|
-
#
|
350
|
-
# ### From a podspec in the root of a library repo.
|
351
|
-
#
|
352
|
-
# Sometimes you may want to use the bleeding edge version of a Pod. Or a
|
353
|
-
# specific revision. If this is the case, you can specify that with your
|
354
|
-
# pod declaration.
|
355
|
-
#
|
356
|
-
#
|
357
|
-
# To use the `master` branch of the repo:
|
358
|
-
#
|
359
|
-
# pod 'TTTFormatterKit', :git => 'https://github.com/gowalla/AFNetworking.git'
|
360
|
-
#
|
361
|
-
#
|
362
|
-
# Or specify a commit:
|
363
|
-
#
|
364
|
-
# pod 'TTTFormatterKit', :git => 'https://github.com/gowalla/AFNetworking.git', :commit => '082f8319af'
|
365
|
-
#
|
366
|
-
#
|
367
|
-
# It is important to note, though, that this means that the version will
|
368
|
-
# have to satisfy any other dependencies on the Pod by other Pods.
|
369
|
-
#
|
370
|
-
#
|
371
|
-
# The `podspec` file is expected to be in the root of the repo, if this
|
372
|
-
# library does not have a `podspec` file in its repo yet, you will have to
|
373
|
-
# use one of the approaches outlined in the sections below.
|
374
|
-
#
|
375
|
-
#
|
376
|
-
# ### From a podspec outside a spec repo, for a library without podspec.
|
377
|
-
#
|
378
|
-
# If a podspec is available from another source outside of the library’s
|
379
|
-
# repo. Consider, for instance, a podpsec available via HTTP:
|
380
|
-
#
|
381
|
-
# pod 'JSONKit', :podspec => 'https://raw.github.com/gist/1346394/1d26570f68ca27377a27430c65841a0880395d72/JSONKit.podspec'
|
382
|
-
#
|
383
|
-
# Or, if no living soul has created a podspec for the library that you want
|
384
|
-
# to use yet, you will have to specify the library yourself. In which case
|
385
|
-
# you can specify a file path with the `:podspec` option as well.
|
386
|
-
#
|
387
|
-
#
|
388
|
-
#
|
389
|
-
# For more info on the definition of a Pod::Specification see:
|
390
|
-
# https://github.com/CocoaPods/CocoaPods/wiki/A-pod-specification
|
391
|
-
def pod(*name_and_version_requirements, &block)
|
392
|
-
warn "[DEPRECATED] Inline specs are deprecated, use the `:podspec` option." if block_given?
|
393
|
-
@target_definition.target_dependencies << Dependency.new(*name_and_version_requirements, &block)
|
394
|
-
end
|
395
|
-
|
396
|
-
# Use the dependencies of a podspec file.
|
397
|
-
#
|
398
|
-
def podspec(options = nil)
|
399
|
-
if options && path = options[:path]
|
400
|
-
path = File.extname(path) == '.podspec' ? path : "#{path}.podspec"
|
401
|
-
file = Pathname.new(File.expand_path(path))
|
402
|
-
elsif options && name = options[:name]
|
403
|
-
name = File.extname(name) == '.podspec' ? name : "#{name}.podspec"
|
404
|
-
file = config.project_root + name
|
405
|
-
else
|
406
|
-
file = Pathname.glob(config.project_root + '*.podspec').first
|
407
|
-
end
|
408
|
-
|
409
|
-
spec = Specification.from_file(file)
|
410
|
-
spec.activate_platform(@target_definition.platform)
|
411
|
-
deps = spec.recursive_subspecs.push(spec).map {|specification| specification.external_dependencies }
|
412
|
-
deps = deps.flatten.uniq
|
413
|
-
@target_definition.target_dependencies.concat(deps)
|
414
|
-
end
|
415
|
-
|
416
|
-
def dependency(*name_and_version_requirements, &block)
|
417
|
-
warn "[DEPRECATED] `dependency' is deprecated (use `pod')"
|
418
|
-
pod(*name_and_version_requirements, &block)
|
419
|
-
end
|
420
|
-
|
421
|
-
# Specifies that a BridgeSupport metadata document should be generated from
|
422
|
-
# the headers of all installed Pods.
|
423
|
-
#
|
424
|
-
# This is for scripting languages such as MacRuby, Nu, and JSCocoa, which use
|
425
|
-
# it to bridge types, functions, etc better.
|
426
|
-
def generate_bridge_support!
|
427
|
-
@generate_bridge_support = true
|
428
|
-
end
|
429
|
-
|
430
|
-
# Defines a new static library target and scopes dependencies defined from
|
431
|
-
# the given block. The target will by default include the dependencies
|
432
|
-
# defined outside of the block, unless the `:exclusive => true` option is
|
433
|
-
# given.
|
434
|
-
#
|
435
|
-
# Consider the following Podfile:
|
436
|
-
#
|
437
|
-
# pod 'ASIHTTPRequest'
|
438
|
-
#
|
439
|
-
# target :debug do
|
440
|
-
# pod 'SSZipArchive'
|
441
|
-
# end
|
442
|
-
#
|
443
|
-
# target :test, :exclusive => true do
|
444
|
-
# pod 'JSONKit'
|
445
|
-
# end
|
446
|
-
#
|
447
|
-
# This Podfile defines three targets. The first one is the `:default` target,
|
448
|
-
# which produces the `libPods.a` file. The second and third are the `:debug`
|
449
|
-
# and `:test` ones, which produce the `libPods-debug.a` and `libPods-test.a`
|
450
|
-
# files.
|
451
|
-
#
|
452
|
-
# The `:default` target has only one dependency (ASIHTTPRequest), whereas the
|
453
|
-
# `:debug` target has two (ASIHTTPRequest, SSZipArchive). The `:test` target,
|
454
|
-
# however, is an exclusive target which means it will only have one
|
455
|
-
# dependency (JSONKit).
|
456
|
-
def target(name, options = {})
|
457
|
-
parent = @target_definition
|
458
|
-
options[:parent] = parent
|
459
|
-
@target_definitions[name] = @target_definition = TargetDefinition.new(name, options)
|
460
|
-
yield
|
461
|
-
ensure
|
462
|
-
@target_definition = parent
|
463
|
-
end
|
464
|
-
|
465
|
-
# This hook allows you to make any changes to the downloaded Pods and to
|
466
|
-
# their targets before they are installed.
|
467
|
-
#
|
468
|
-
# pre_install do |installer|
|
469
|
-
# # Do something fancy!
|
470
|
-
# end
|
471
|
-
#
|
472
|
-
def pre_install(&block)
|
473
|
-
@pre_install_callback = block
|
474
|
-
end
|
475
|
-
|
476
|
-
# This hook allows you to make any last changes to the generated Xcode project
|
477
|
-
# before it is written to disk, or any other tasks you might want to perform.
|
478
|
-
#
|
479
|
-
# For instance, say you'd want to customize the `OTHER_LDFLAGS` of all targets:
|
480
|
-
#
|
481
|
-
# post_install do |installer|
|
482
|
-
# installer.project.targets.each do |target|
|
483
|
-
# target.build_configurations.each do |config|
|
484
|
-
# config.build_settings['GCC_ENABLE_OBJC_GC'] = 'supported'
|
485
|
-
# end
|
486
|
-
# end
|
487
|
-
# end
|
488
|
-
def post_install(&block)
|
489
|
-
@post_install_callback = block
|
490
|
-
end
|
491
|
-
|
492
|
-
# Specifies that the -fobjc-arc flag should be added to the OTHER_LD_FLAGS.
|
493
|
-
#
|
494
|
-
# This is used as a workaround for a compiler bug with non-ARC projects.
|
495
|
-
# (see https://github.com/CocoaPods/CocoaPods/issues/142)
|
496
|
-
#
|
497
|
-
# This was originally done automatically but libtool as of Xcode 4.3.2 no
|
498
|
-
# longer seems to support the -fobjc-arc flag. Therefore it now has to be
|
499
|
-
# enabled explicitly using this method.
|
500
|
-
#
|
501
|
-
# This may be removed in a future release.
|
502
|
-
def set_arc_compatibility_flag!
|
503
|
-
@set_arc_compatibility_flag = true
|
504
|
-
end
|
505
|
-
|
506
|
-
# Not attributes
|
507
|
-
|
508
|
-
def podfile?
|
509
|
-
true
|
510
|
-
end
|
511
|
-
|
512
|
-
attr_accessor :defined_in_file
|
513
|
-
attr_reader :target_definitions
|
514
|
-
|
515
|
-
def dependencies
|
516
|
-
@target_definitions.values.map(&:target_dependencies).flatten.uniq
|
517
|
-
end
|
518
|
-
|
519
|
-
def dependency_by_top_level_spec_name(name)
|
520
|
-
dependencies.find { |d| d.top_level_spec_name == name }
|
521
|
-
end
|
522
|
-
|
523
|
-
def generate_bridge_support?
|
524
|
-
@generate_bridge_support
|
525
|
-
end
|
526
|
-
|
527
|
-
def set_arc_compatibility_flag?
|
528
|
-
@set_arc_compatibility_flag
|
529
|
-
end
|
530
|
-
|
531
|
-
def user_build_configurations
|
532
|
-
configs_array = @target_definitions.values.map { |td| td.user_project.build_configurations }
|
533
|
-
configs_array.inject({}) { |hash, config| hash.merge(config) }
|
534
|
-
end
|
535
|
-
|
536
|
-
def pre_install!(installer)
|
537
|
-
@pre_install_callback.call(installer) if @pre_install_callback
|
538
|
-
end
|
539
|
-
|
540
|
-
def post_install!(installer)
|
541
|
-
@post_install_callback.call(installer) if @post_install_callback
|
542
|
-
end
|
543
|
-
|
544
|
-
def validate!
|
545
|
-
end
|
546
|
-
|
547
|
-
def to_s
|
548
|
-
"Podfile"
|
549
|
-
end
|
550
|
-
end
|
551
|
-
end
|