cocoapods 0.16.4 → 0.17.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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/source.rb
DELETED
@@ -1,223 +0,0 @@
|
|
1
|
-
module Pod
|
2
|
-
|
3
|
-
# The {Source} class is responsible to manage a collection of podspecs.
|
4
|
-
#
|
5
|
-
# @note The backing store of the podspecs collection is an implementation detail
|
6
|
-
# abstraced from the rest of CocoaPods.
|
7
|
-
#
|
8
|
-
# @note The default implementation uses a git repo as a backing store, where the
|
9
|
-
# podspecs are namespaces as:
|
10
|
-
#
|
11
|
-
# #{POD_NAME}/#{VERSION}/#{POD_NAME}.podspec
|
12
|
-
#
|
13
|
-
# @todo For better abstranction the sources should be responsible to update themselves.
|
14
|
-
#
|
15
|
-
class Source
|
16
|
-
|
17
|
-
# @return [Pathname] The location of the repo.
|
18
|
-
#
|
19
|
-
attr_reader :repo
|
20
|
-
|
21
|
-
# @param [Pathname] repo @see repo.
|
22
|
-
#
|
23
|
-
def initialize(repo)
|
24
|
-
@repo = repo
|
25
|
-
end
|
26
|
-
|
27
|
-
# @return [String] the name of the repo.
|
28
|
-
#
|
29
|
-
def name
|
30
|
-
@repo.basename.to_s
|
31
|
-
end
|
32
|
-
|
33
|
-
# @!group Quering the source
|
34
|
-
|
35
|
-
# @return [Array<String>] The name of all the Pods.
|
36
|
-
#
|
37
|
-
def pods
|
38
|
-
@repo.children.map do |child|
|
39
|
-
child.basename.to_s if child.directory? && child.basename.to_s != '.git'
|
40
|
-
end.compact
|
41
|
-
end
|
42
|
-
|
43
|
-
# @return [Array<Sets>] The sets of all the Pods.
|
44
|
-
#
|
45
|
-
def pod_sets
|
46
|
-
pods.map { |pod| Specification::Set.new(pod, self) }
|
47
|
-
end
|
48
|
-
|
49
|
-
# @return [Array<Version>] All the available versions for the Pod, sorted
|
50
|
-
# from highest to lowest.
|
51
|
-
#
|
52
|
-
# @param [String] name The name of the Pod.
|
53
|
-
#
|
54
|
-
def versions(name)
|
55
|
-
pod_dir = repo + name
|
56
|
-
pod_dir.children.map do |v|
|
57
|
-
basename = v.basename.to_s
|
58
|
-
Version.new(basename) if v.directory? && basename[0,1] != '.'
|
59
|
-
end.compact.sort.reverse
|
60
|
-
end
|
61
|
-
|
62
|
-
# @return [Specification] The specification for a given version of Pod.
|
63
|
-
#
|
64
|
-
# @param [String] name The name of the Pod.
|
65
|
-
#
|
66
|
-
# @param [Version,String] version
|
67
|
-
# The version for the specification.
|
68
|
-
#
|
69
|
-
def specification(name, version)
|
70
|
-
specification_path = repo + name + version.to_s + "#{name}.podspec"
|
71
|
-
Specification.from_file(specification_path)
|
72
|
-
end
|
73
|
-
|
74
|
-
# @!group Searching the source
|
75
|
-
|
76
|
-
# @return [Set] A set for a given dependency. The set is identified by the
|
77
|
-
# name of the dependency and takes into account subspecs.
|
78
|
-
#
|
79
|
-
def search(dependency)
|
80
|
-
pod_sets.find do |set|
|
81
|
-
# First match the (top level) name, which does not yet load the spec from disk
|
82
|
-
set.name == dependency.top_level_spec_name &&
|
83
|
-
# Now either check if it's a dependency on the top level spec, or if it's not
|
84
|
-
# check if the requested subspec exists in the top level spec.
|
85
|
-
set.specification.subspec_by_name(dependency.name)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
# @return [Array<Set>] The sets that contain the search term.
|
90
|
-
#
|
91
|
-
# @param [String] query The search term.
|
92
|
-
#
|
93
|
-
# @param [Bool] full_text_search Whether the search should be limited to
|
94
|
-
# the name of the Pod or should include
|
95
|
-
# also the author, the summary, and the
|
96
|
-
# description.
|
97
|
-
#
|
98
|
-
# @note Full text search requires to load the specification for each pod,
|
99
|
-
# hence is considerably slower.
|
100
|
-
#
|
101
|
-
def search_by_name(query, full_text_search = false)
|
102
|
-
pod_sets.map do |set|
|
103
|
-
text = if full_text_search
|
104
|
-
s = set.specification
|
105
|
-
"#{s.name} #{s.authors} #{s.summary} #{s.description}"
|
106
|
-
else
|
107
|
-
set.name
|
108
|
-
end
|
109
|
-
set if text.downcase.include?(query.downcase)
|
110
|
-
end.compact
|
111
|
-
end
|
112
|
-
|
113
|
-
# The {Source::Aggregate} manages all the sources available to CocoaPods.
|
114
|
-
#
|
115
|
-
class Aggregate
|
116
|
-
|
117
|
-
# @return [Array<Source>] All the sources.
|
118
|
-
#
|
119
|
-
def all
|
120
|
-
@sources ||= dirs.map { |repo| Source.new(repo) }.sort_by(&:name)
|
121
|
-
end
|
122
|
-
|
123
|
-
# @return [Array<String>] The names of all the pods available.
|
124
|
-
#
|
125
|
-
def all_pods
|
126
|
-
all.map(&:pods).flatten.uniq
|
127
|
-
end
|
128
|
-
|
129
|
-
# @return [Array<Set>] The sets for all the pods available.
|
130
|
-
#
|
131
|
-
# @note Implementation detail: The sources don't cache their values
|
132
|
-
# because they might change in response to an update. Therefore
|
133
|
-
# this method to prevent slowness caches the values before
|
134
|
-
# processing them.
|
135
|
-
#
|
136
|
-
def all_sets
|
137
|
-
pods_by_source = {}
|
138
|
-
all.each do |source|
|
139
|
-
pods_by_source[source] = source.pods
|
140
|
-
end
|
141
|
-
sources = pods_by_source.keys
|
142
|
-
pods = pods_by_source.values.flatten.uniq
|
143
|
-
|
144
|
-
pods.map do |pod|
|
145
|
-
pod_sources = sources.select{ |s| pods_by_source[s].include?(pod) }.compact
|
146
|
-
Specification::Set.new(pod, pod_sources)
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
# @return [Set] A set for a given dependency including all the Sources
|
151
|
-
# that countain the Pod.
|
152
|
-
#
|
153
|
-
# @raises If no source including the set can be foud.
|
154
|
-
#
|
155
|
-
# @see Source#search
|
156
|
-
#
|
157
|
-
def search(dependency)
|
158
|
-
sources = all.select { |s| !s.search(dependency).nil? }
|
159
|
-
raise(Informative, "[!] Unable to find a pod named `#{dependency.name}'".red) if sources.empty?
|
160
|
-
Specification::Set.new(dependency.top_level_spec_name, sources)
|
161
|
-
end
|
162
|
-
|
163
|
-
# @return [Array<Set>] The sets that contain the search term.
|
164
|
-
#
|
165
|
-
# @raises If no source including the set can be foud.
|
166
|
-
#
|
167
|
-
# @see Source#search_by_name
|
168
|
-
#
|
169
|
-
def search_by_name(query, full_text_search = false)
|
170
|
-
pods_by_source = {}
|
171
|
-
result = []
|
172
|
-
all.each { |s| pods_by_source[s] = s.search_by_name(query, full_text_search).map(&:name) }
|
173
|
-
pod_names = pods_by_source.values.flatten.uniq
|
174
|
-
pod_names.each do |pod|
|
175
|
-
sources = []
|
176
|
-
pods_by_source.each{ |source, pods| sources << source if pods.include?(pod) }
|
177
|
-
result << Specification::Set.new(pod, sources)
|
178
|
-
end
|
179
|
-
if result.empty?
|
180
|
-
extra = ", author, summary, or description" if full_text_search
|
181
|
-
raise(Informative, "Unable to find a pod with name" \
|
182
|
-
"#{extra} matching `#{query}'")
|
183
|
-
end
|
184
|
-
result
|
185
|
-
end
|
186
|
-
|
187
|
-
# @return [Array<Pathname>] The directories where the sources are stored.
|
188
|
-
#
|
189
|
-
# @raises If the repos dir doesn't exits.
|
190
|
-
#
|
191
|
-
def dirs
|
192
|
-
if ENV['CP_MASTER_REPO_DIR']
|
193
|
-
[Pathname.new(ENV['CP_MASTER_REPO_DIR'])]
|
194
|
-
else
|
195
|
-
repos_dir = Config.instance.repos_dir
|
196
|
-
unless repos_dir.exist?
|
197
|
-
raise Informative, "No spec repos found in `#{repos_dir}'. " \
|
198
|
-
"To fetch the `master' repo run: $ pod setup"
|
199
|
-
end
|
200
|
-
repos_dir.children.select(&:directory?)
|
201
|
-
end
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
# @!group Shortcuts
|
206
|
-
|
207
|
-
def self.all
|
208
|
-
Aggregate.new.all
|
209
|
-
end
|
210
|
-
|
211
|
-
def self.all_sets
|
212
|
-
Aggregate.new.all_sets
|
213
|
-
end
|
214
|
-
|
215
|
-
def self.search(dependency)
|
216
|
-
Aggregate.new.search(dependency)
|
217
|
-
end
|
218
|
-
|
219
|
-
def self.search_by_name(name, full_text_search = false)
|
220
|
-
Aggregate.new.search_by_name(name, full_text_search)
|
221
|
-
end
|
222
|
-
end
|
223
|
-
end
|
@@ -1,579 +0,0 @@
|
|
1
|
-
require 'xcodeproj/config'
|
2
|
-
require 'active_support/core_ext/string/strip.rb'
|
3
|
-
|
4
|
-
module Pod
|
5
|
-
extend Config::Mixin
|
6
|
-
|
7
|
-
def self._eval_podspec(path)
|
8
|
-
string = File.open(path, 'r:utf-8') { |f| f.read }
|
9
|
-
# TODO: work around for Rubinius incomplete encoding in 1.9 mode
|
10
|
-
string.encode!('UTF-8') if string.respond_to?(:encoding) && string.encoding.name != "UTF-8"
|
11
|
-
eval(string, nil, path.to_s)
|
12
|
-
end
|
13
|
-
|
14
|
-
class Specification
|
15
|
-
autoload :Set, 'cocoapods/specification/set'
|
16
|
-
autoload :Statistics, 'cocoapods/specification/statistics'
|
17
|
-
|
18
|
-
### Initalization
|
19
|
-
|
20
|
-
# The file is expected to define and return a Pods::Specification.
|
21
|
-
# If name is equal to nil it returns the top level Specification,
|
22
|
-
# otherwise it returns the specification with matching name
|
23
|
-
def self.from_file(path, subspec_name = nil)
|
24
|
-
unless path.exist?
|
25
|
-
raise Informative, "No podspec exists at path `#{path}'."
|
26
|
-
end
|
27
|
-
spec = ::Pod._eval_podspec(path)
|
28
|
-
spec.defined_in_file = path
|
29
|
-
spec.subspec_by_name(subspec_name)
|
30
|
-
end
|
31
|
-
|
32
|
-
def initialize(parent = nil, name = nil)
|
33
|
-
@parent, @name = parent, name
|
34
|
-
@define_for_platforms = [:osx, :ios]
|
35
|
-
@clean_paths, @subspecs = [], []
|
36
|
-
@deployment_target = {}
|
37
|
-
unless parent
|
38
|
-
@source = {:git => ''}
|
39
|
-
end
|
40
|
-
|
41
|
-
# multi-platform attributes
|
42
|
-
%w[ source_files
|
43
|
-
public_header_files
|
44
|
-
resources
|
45
|
-
preserve_paths
|
46
|
-
exclude_header_search_paths
|
47
|
-
frameworks
|
48
|
-
weak_frameworks
|
49
|
-
libraries
|
50
|
-
dependencies
|
51
|
-
compiler_flags ].each do |attr|
|
52
|
-
instance_variable_set( "@#{attr}", { :ios => [], :osx => [] } )
|
53
|
-
end
|
54
|
-
@xcconfig = { :ios => Xcodeproj::Config.new, :osx => Xcodeproj::Config.new }
|
55
|
-
@header_dir = { :ios => nil, :osx => nil }
|
56
|
-
@requires_arc = { :ios => nil, :osx => nil }
|
57
|
-
@header_mappings_dir = { :ios => nil, :osx => nil }
|
58
|
-
|
59
|
-
yield self if block_given?
|
60
|
-
end
|
61
|
-
|
62
|
-
### Meta programming
|
63
|
-
|
64
|
-
# Creates a top level attribute reader. A lambda can
|
65
|
-
# be passed to process the ivar before returning it
|
66
|
-
def self.top_attr_reader(attr, read_lambda = nil)
|
67
|
-
define_method(attr) do
|
68
|
-
ivar = instance_variable_get("@#{attr}")
|
69
|
-
@parent ? top_level_parent.send(attr) : ( read_lambda ? read_lambda.call(self, ivar) : ivar )
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
# Creates a top level attribute writer. A lambda can
|
74
|
-
# be passed to initalize the value
|
75
|
-
def self.top_attr_writer(attr, init_lambda = nil)
|
76
|
-
define_method("#{attr}=") do |value|
|
77
|
-
raise Informative, "#{self.inspect} Can't set `#{attr}' for subspecs." if @parent
|
78
|
-
instance_variable_set("@#{attr}", init_lambda ? init_lambda.call(value) : value);
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
# Creates a top level attribute accessor. A lambda can
|
83
|
-
# be passed to initialize the value in the attribute writer.
|
84
|
-
def self.top_attr_accessor(attr, writer_labmda = nil)
|
85
|
-
top_attr_reader attr
|
86
|
-
top_attr_writer attr, writer_labmda
|
87
|
-
end
|
88
|
-
|
89
|
-
# Returns the value of the attribute for the active platform
|
90
|
-
# chained with the upstream specifications. The ivar must store
|
91
|
-
# the platform specific values as an array.
|
92
|
-
#
|
93
|
-
def self.pltf_chained_attr_reader(attr)
|
94
|
-
define_method(attr) do
|
95
|
-
active_plaform_check
|
96
|
-
ivar_value = instance_variable_get("@#{attr}")[active_platform]
|
97
|
-
@parent ? @parent.send(attr) + ivar_value : ( ivar_value )
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
# Returns the first value defined of the attribute traversing the chain
|
102
|
-
# upwards.
|
103
|
-
#
|
104
|
-
def self.pltf_first_defined_attr_reader(attr)
|
105
|
-
define_method(attr) do
|
106
|
-
active_plaform_check
|
107
|
-
ivar_value = instance_variable_get("@#{attr}")[active_platform]
|
108
|
-
ivar_value.nil? ? (@parent.send(attr) if @parent) : ivar_value
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def active_plaform_check
|
113
|
-
raise Informative, "#{self.inspect} not activated for a platform before consumption." unless active_platform
|
114
|
-
end
|
115
|
-
|
116
|
-
# Attribute writer that works in conjuction with the PlatformProxy.
|
117
|
-
def self.platform_attr_writer(attr, block = nil)
|
118
|
-
define_method("#{attr}=") do |value|
|
119
|
-
current = instance_variable_get("@#{attr}")
|
120
|
-
@define_for_platforms.each do |platform|
|
121
|
-
block ? current[platform] = block.call(value, current[platform]) : current[platform] = value
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def self.pltf_chained_attr_accessor(attr, block = nil)
|
127
|
-
pltf_chained_attr_reader(attr)
|
128
|
-
platform_attr_writer(attr, block)
|
129
|
-
end
|
130
|
-
|
131
|
-
# The PlatformProxy works in conjuction with Specification#_on_platform.
|
132
|
-
# It allows a syntax like `spec.ios.source_files = file`
|
133
|
-
class PlatformProxy
|
134
|
-
def initialize(specification, platform)
|
135
|
-
@specification, @platform = specification, platform
|
136
|
-
end
|
137
|
-
|
138
|
-
%w{ source_files=
|
139
|
-
public_header_files=
|
140
|
-
resource=
|
141
|
-
resources=
|
142
|
-
preserve_paths=
|
143
|
-
preserve_path=
|
144
|
-
xcconfig=
|
145
|
-
framework=
|
146
|
-
frameworks=
|
147
|
-
weak_framework=
|
148
|
-
weak_frameworks=
|
149
|
-
library=
|
150
|
-
libraries=
|
151
|
-
compiler_flags=
|
152
|
-
deployment_target=
|
153
|
-
header_dir=
|
154
|
-
requires_arc
|
155
|
-
dependency }.each do |method|
|
156
|
-
define_method(method) do |args|
|
157
|
-
@specification._on_platform(@platform) do
|
158
|
-
@specification.send(method, args)
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
def ios
|
165
|
-
PlatformProxy.new(self, :ios)
|
166
|
-
end
|
167
|
-
|
168
|
-
def osx
|
169
|
-
PlatformProxy.new(self, :osx)
|
170
|
-
end
|
171
|
-
|
172
|
-
### Deprecated attributes - TODO: remove once master repo and fixtures have been updated
|
173
|
-
|
174
|
-
attr_writer :part_of_dependency
|
175
|
-
attr_writer :part_of
|
176
|
-
|
177
|
-
top_attr_accessor :clean_paths, lambda { |patterns| pattern_list(patterns) }
|
178
|
-
alias_method :clean_path=, :clean_paths=
|
179
|
-
|
180
|
-
### Regular attributes
|
181
|
-
|
182
|
-
attr_accessor :parent
|
183
|
-
attr_accessor :preferred_dependency
|
184
|
-
|
185
|
-
def name
|
186
|
-
@parent ? "#{@parent.name}/#{@name}" : @name
|
187
|
-
end
|
188
|
-
attr_writer :name
|
189
|
-
|
190
|
-
# @return [String] The name of the pod.
|
191
|
-
#
|
192
|
-
def pod_name
|
193
|
-
top_level_parent.name
|
194
|
-
end
|
195
|
-
|
196
|
-
### Attributes that return the first value defined in the chain
|
197
|
-
|
198
|
-
def platform
|
199
|
-
@platform || ( @parent ? @parent.platform : nil )
|
200
|
-
end
|
201
|
-
|
202
|
-
def platform=(platform)
|
203
|
-
@platform = Platform.new(*platform)
|
204
|
-
end
|
205
|
-
|
206
|
-
# If not platform is specified all the platforms are returned.
|
207
|
-
def available_platforms
|
208
|
-
platform.nil? ? @define_for_platforms.map { |platform| Platform.new(platform, deployment_target(platform)) } : [ platform ]
|
209
|
-
end
|
210
|
-
|
211
|
-
### Top level attributes. These attributes represent the unique features of pod and can't be specified by subspecs.
|
212
|
-
|
213
|
-
top_attr_accessor :defined_in_file
|
214
|
-
top_attr_accessor :source
|
215
|
-
top_attr_accessor :homepage
|
216
|
-
top_attr_accessor :summary
|
217
|
-
top_attr_accessor :documentation
|
218
|
-
top_attr_accessor :version, lambda { |v| Version.new(v) }
|
219
|
-
|
220
|
-
top_attr_reader :description, lambda { |instance, ivar| ivar || instance.summary }
|
221
|
-
top_attr_writer :description, lambda { |d| d.strip_heredoc }
|
222
|
-
|
223
|
-
# @!method license
|
224
|
-
#
|
225
|
-
# @abstract
|
226
|
-
# The license of the pod.
|
227
|
-
#
|
228
|
-
# @example
|
229
|
-
# s.license = 'MIT'
|
230
|
-
# s.license = { :type => 'MIT', :file => 'license.txt', :text => 'Permission is granted to...' }
|
231
|
-
#
|
232
|
-
top_attr_accessor :license, lambda { |license|
|
233
|
-
license = ( license.kind_of? String ) ? { :type => license } : license
|
234
|
-
license[:text] = license[:text].strip_heredoc if license[:text]
|
235
|
-
license
|
236
|
-
}
|
237
|
-
|
238
|
-
# @!method authors
|
239
|
-
#
|
240
|
-
# @abstract
|
241
|
-
# The list of the authors (with email) of the pod.
|
242
|
-
#
|
243
|
-
top_attr_accessor :authors, lambda { |*names_and_email_addresses|
|
244
|
-
list = names_and_email_addresses.flatten
|
245
|
-
unless list.first.is_a?(Hash)
|
246
|
-
authors = list.last.is_a?(Hash) ? list.pop : {}
|
247
|
-
list.each { |name| authors[name] = nil }
|
248
|
-
end
|
249
|
-
authors || list.first
|
250
|
-
}
|
251
|
-
|
252
|
-
alias_method :author=, :authors=
|
253
|
-
|
254
|
-
### Attributes **with** multiple platform support
|
255
|
-
|
256
|
-
# @todo allow for subspecs?
|
257
|
-
#
|
258
|
-
top_attr_accessor :prefix_header_file, lambda { |file| Pathname.new(file) }
|
259
|
-
top_attr_accessor :prefix_header_contents
|
260
|
-
|
261
|
-
pltf_chained_attr_accessor :source_files, lambda {|value, current| pattern_list(value) }
|
262
|
-
pltf_chained_attr_accessor :public_header_files, lambda {|value, current| pattern_list(value) }
|
263
|
-
pltf_chained_attr_accessor :resources, lambda {|value, current| pattern_list(value) }
|
264
|
-
pltf_chained_attr_accessor :preserve_paths, lambda {|value, current| pattern_list(value) } # Paths that should not be cleaned
|
265
|
-
pltf_chained_attr_accessor :exclude_header_search_paths, lambda {|value, current| pattern_list(value) } # Headers to be excluded from being added to search paths (RestKit)
|
266
|
-
pltf_chained_attr_accessor :frameworks, lambda {|value, current| (current << value).flatten }
|
267
|
-
pltf_chained_attr_accessor :weak_frameworks, lambda {|value, current| (current << value).flatten }
|
268
|
-
pltf_chained_attr_accessor :libraries, lambda {|value, current| (current << value).flatten }
|
269
|
-
|
270
|
-
alias_method :resource=, :resources=
|
271
|
-
alias_method :preserve_path=, :preserve_paths=
|
272
|
-
alias_method :framework=, :frameworks=
|
273
|
-
alias_method :weak_framework=, :weak_frameworks=
|
274
|
-
alias_method :library=, :libraries=
|
275
|
-
|
276
|
-
# @!method requires_arc=
|
277
|
-
#
|
278
|
-
# @abstract Wether the `-fobjc-arc' flag should be added to the compiler
|
279
|
-
# flags.
|
280
|
-
#
|
281
|
-
# @param [Bool] Wether the source files require ARC.
|
282
|
-
#
|
283
|
-
platform_attr_writer :requires_arc
|
284
|
-
pltf_first_defined_attr_reader :requires_arc
|
285
|
-
|
286
|
-
# @!method header_dir=
|
287
|
-
#
|
288
|
-
# @abstract The directory where to name space the headers files of
|
289
|
-
# the specification.
|
290
|
-
#
|
291
|
-
# @param [String] The headers directory.
|
292
|
-
#
|
293
|
-
platform_attr_writer :header_dir, lambda { |dir, _| Pathname.new(dir) }
|
294
|
-
pltf_first_defined_attr_reader :header_dir
|
295
|
-
|
296
|
-
# If not provided the headers files are flattened
|
297
|
-
#
|
298
|
-
platform_attr_writer :header_mappings_dir, lambda { |file, _| Pathname.new(file) }
|
299
|
-
pltf_first_defined_attr_reader :header_mappings_dir
|
300
|
-
|
301
|
-
# @!method xcconfig=
|
302
|
-
#
|
303
|
-
platform_attr_writer :xcconfig, lambda {|value, current| current.tap { |c| c.merge!(value) } }
|
304
|
-
|
305
|
-
def xcconfig
|
306
|
-
result = raw_xconfig.dup
|
307
|
-
result.libraries.merge(libraries)
|
308
|
-
result.frameworks.merge(frameworks)
|
309
|
-
result.weak_frameworks.merge(weak_frameworks)
|
310
|
-
result
|
311
|
-
end
|
312
|
-
|
313
|
-
def raw_xconfig
|
314
|
-
@parent ? @parent.raw_xconfig.merge(@xcconfig[active_platform]) : @xcconfig[active_platform]
|
315
|
-
end
|
316
|
-
|
317
|
-
|
318
|
-
def recursive_compiler_flags
|
319
|
-
@parent ? @parent.recursive_compiler_flags | @compiler_flags[active_platform] : @compiler_flags[active_platform]
|
320
|
-
end
|
321
|
-
|
322
|
-
ENABLE_OBJECT_USE_OBJC_FROM = {
|
323
|
-
:ios => Version.new('6'),
|
324
|
-
:osx => Version.new('10.8')
|
325
|
-
}
|
326
|
-
|
327
|
-
# The following behavior is regarding the `OS_OBJECT_USE_OBJC` flag. When
|
328
|
-
# set to `0`, it will allow code to use `dispatch_release()` on >= iOS 6.0
|
329
|
-
# and OS X 10.8.
|
330
|
-
#
|
331
|
-
# * New libraries that do *not* require ARC don’t need to care about this
|
332
|
-
# issue at all.
|
333
|
-
#
|
334
|
-
# * New libraries that *do* require ARC _and_ have a deployment target of
|
335
|
-
# >= iOS 6.0 or OS X 10.8:
|
336
|
-
#
|
337
|
-
# These no longer use `dispatch_release()` and should *not* have the
|
338
|
-
# `OS_OBJECT_USE_OBJC` flag set to `0`.
|
339
|
-
#
|
340
|
-
# **Note:** this means that these libraries *have* to specify the
|
341
|
-
# deployment target in order to function well.
|
342
|
-
#
|
343
|
-
# * New libraries that *do* require ARC, but have a deployment target of
|
344
|
-
# < iOS 6.0 or OS X 10.8:
|
345
|
-
#
|
346
|
-
# These contain `dispatch_release()` calls and as such need the
|
347
|
-
# `OS_OBJECT_USE_OBJC` flag set to `1`.
|
348
|
-
#
|
349
|
-
# **Note:** libraries that do *not* specify a platform version are
|
350
|
-
# assumed to have a deployment target of < iOS 6.0 or OS X 10.8.
|
351
|
-
#
|
352
|
-
# For more information, see: http://opensource.apple.com/source/libdispatch/libdispatch-228.18/os/object.h
|
353
|
-
#
|
354
|
-
def compiler_flags
|
355
|
-
flags = recursive_compiler_flags.dup
|
356
|
-
if requires_arc
|
357
|
-
flags << '-fobjc-arc'
|
358
|
-
ios_target, osx_target = deployment_target(:ios), deployment_target(:osx)
|
359
|
-
if (ios_target.nil? && osx_target.nil?) ||
|
360
|
-
(ios_target && Version.new(ios_target) < ENABLE_OBJECT_USE_OBJC_FROM[:ios]) ||
|
361
|
-
(osx_target && Version.new(osx_target) < ENABLE_OBJECT_USE_OBJC_FROM[:osx])
|
362
|
-
flags << '-DOS_OBJECT_USE_OBJC=0'
|
363
|
-
end
|
364
|
-
end
|
365
|
-
flags.join(' ')
|
366
|
-
end
|
367
|
-
|
368
|
-
platform_attr_writer :compiler_flags, lambda {|value, current| current << value }
|
369
|
-
|
370
|
-
def dependency(*name_and_version_requirements)
|
371
|
-
name, *version_requirements = name_and_version_requirements.flatten
|
372
|
-
raise Informative, "A specification can't require self as a subspec" if name == self.name
|
373
|
-
raise Informative, "A subspec can't require one of its parents specifications" if @parent && @parent.name.include?(name)
|
374
|
-
dep = Dependency.new(name, *version_requirements)
|
375
|
-
@define_for_platforms.each do |platform|
|
376
|
-
@dependencies[platform] << dep
|
377
|
-
end
|
378
|
-
dep
|
379
|
-
end
|
380
|
-
|
381
|
-
# External dependencies are inherited by subspecs
|
382
|
-
def external_dependencies(all_platforms = false)
|
383
|
-
active_plaform_check unless all_platforms
|
384
|
-
result = all_platforms ? @dependencies.values.flatten : @dependencies[active_platform]
|
385
|
-
result += parent.external_dependencies if parent
|
386
|
-
result
|
387
|
-
end
|
388
|
-
|
389
|
-
# A specification inherits the preferred_dependency or
|
390
|
-
# all the compatible subspecs as dependencies
|
391
|
-
def subspec_dependencies
|
392
|
-
active_plaform_check
|
393
|
-
specs = preferred_dependency ? [subspec_by_name("#{name}/#{preferred_dependency}")] : subspecs
|
394
|
-
specs.compact \
|
395
|
-
.select { |s| s.supports_platform?(active_platform) } \
|
396
|
-
.map { |s| Dependency.new(s.name, version) }
|
397
|
-
end
|
398
|
-
|
399
|
-
def dependencies
|
400
|
-
external_dependencies + subspec_dependencies
|
401
|
-
end
|
402
|
-
|
403
|
-
include Config::Mixin
|
404
|
-
|
405
|
-
def top_level_parent
|
406
|
-
@parent ? @parent.top_level_parent : self
|
407
|
-
end
|
408
|
-
|
409
|
-
def subspec?
|
410
|
-
!@parent.nil?
|
411
|
-
end
|
412
|
-
|
413
|
-
def subspec(name, &block)
|
414
|
-
subspec = Specification.new(self, name, &block)
|
415
|
-
@subspecs << subspec
|
416
|
-
subspec
|
417
|
-
end
|
418
|
-
attr_reader :subspecs
|
419
|
-
|
420
|
-
def recursive_subspecs
|
421
|
-
@recursive_subspecs ||= begin
|
422
|
-
mapper = lambda do |spec|
|
423
|
-
spec.subspecs.map do |subspec|
|
424
|
-
[subspec, *mapper.call(subspec)]
|
425
|
-
end.flatten
|
426
|
-
end
|
427
|
-
mapper.call(self)
|
428
|
-
end
|
429
|
-
end
|
430
|
-
|
431
|
-
def subspec_by_name(name)
|
432
|
-
return self if name.nil? || name == self.name
|
433
|
-
# Remove this spec's name from the beginning of the name we’re looking for
|
434
|
-
# and take the first component from the remainder, which is the spec we need
|
435
|
-
# to find now.
|
436
|
-
remainder = name[self.name.size+1..-1]
|
437
|
-
raise Informative, "Unable to find a specification named `#{name}' in `#{pod_name}'." unless remainder
|
438
|
-
subspec_name = remainder.split('/').shift
|
439
|
-
subspec = subspecs.find { |s| s.name == "#{self.name}/#{subspec_name}" }
|
440
|
-
raise Informative, "Unable to find a specification named `#{name}' in `#{pod_name}'." unless subspec
|
441
|
-
# If this was the last component in the name, then return the subspec,
|
442
|
-
# otherwise we recursively keep calling subspec_by_name until we reach the
|
443
|
-
# last one and return that
|
444
|
-
remainder.empty? ? subspec : subspec.subspec_by_name(name)
|
445
|
-
end
|
446
|
-
|
447
|
-
def local?
|
448
|
-
!source.nil? && !source[:local].nil?
|
449
|
-
end
|
450
|
-
|
451
|
-
def pod_destroot
|
452
|
-
config.project_pods_root + top_level_parent.name
|
453
|
-
end
|
454
|
-
|
455
|
-
def self.pattern_list(patterns)
|
456
|
-
if patterns.is_a?(Array) && (!defined?(Rake) || !patterns.is_a?(Rake::FileList))
|
457
|
-
patterns
|
458
|
-
else
|
459
|
-
[patterns]
|
460
|
-
end
|
461
|
-
end
|
462
|
-
|
463
|
-
# This method takes a header path and returns the location it should have
|
464
|
-
# in the pod's header dir.
|
465
|
-
#
|
466
|
-
# By default all headers are copied to the pod's header dir without any
|
467
|
-
# namespacing. However if the top level attribute accessor header_mappings_dir
|
468
|
-
# is specified the namespacing will be preserved from that directory.
|
469
|
-
def copy_header_mapping(from)
|
470
|
-
header_mappings_dir ? from.relative_path_from(header_mappings_dir) : from.basename
|
471
|
-
end
|
472
|
-
|
473
|
-
# This is a convenience method which gets called after all pods have been
|
474
|
-
# downloaded but before they have been installed, and the Xcode project and
|
475
|
-
# related files have been generated. (It receives the Pod::LocalPod
|
476
|
-
# instance generated form the specification and the #
|
477
|
-
# Pod::Podfile::TargetDefinition instance for the current target.) Override
|
478
|
-
# this to, for instance, to run any build script:
|
479
|
-
#
|
480
|
-
# Pod::Spec.new do |s|
|
481
|
-
# def s.pre_install(pod, target_definition)
|
482
|
-
# Dir.chdir(pod.root){ `sh make.sh` }
|
483
|
-
# end
|
484
|
-
# end
|
485
|
-
def pre_install(pod, target_definition)
|
486
|
-
FALSE
|
487
|
-
end
|
488
|
-
|
489
|
-
# This is a convenience method which gets called after all pods have been
|
490
|
-
# downloaded, installed, and the Xcode project and related files have been
|
491
|
-
# generated. (It receives the Pod::Installer::TargetInstaller instance for
|
492
|
-
# the current target.) Override this to, for instance, add to the prefix
|
493
|
-
# header:
|
494
|
-
#
|
495
|
-
# Pod::Spec.new do |s|
|
496
|
-
# def s.post_install(target_installer)
|
497
|
-
# prefix_header = config.project_pods_root + target_installer.prefix_header_filename
|
498
|
-
# prefix_header.open('a') do |file|
|
499
|
-
# file.puts(%{#ifdef __OBJC__\n#import "SSToolkitDefines.h"\n#endif})
|
500
|
-
# end
|
501
|
-
# end
|
502
|
-
# end
|
503
|
-
def post_install(target_installer)
|
504
|
-
FALSE
|
505
|
-
end
|
506
|
-
|
507
|
-
def podfile?
|
508
|
-
false
|
509
|
-
end
|
510
|
-
|
511
|
-
# This is used by the specification set
|
512
|
-
def dependency_by_top_level_spec_name(name)
|
513
|
-
external_dependencies(true).each do |dep|
|
514
|
-
return dep if dep.top_level_spec_name == name
|
515
|
-
end
|
516
|
-
end
|
517
|
-
|
518
|
-
def to_s
|
519
|
-
"#{name} (#{version})"
|
520
|
-
end
|
521
|
-
|
522
|
-
def inspect
|
523
|
-
"#<#{self.class.name} for #{to_s}>"
|
524
|
-
end
|
525
|
-
|
526
|
-
def ==(other)
|
527
|
-
object_id == other.object_id ||
|
528
|
-
(self.class === other &&
|
529
|
-
name && name == other.name &&
|
530
|
-
version && version == other.version)
|
531
|
-
end
|
532
|
-
|
533
|
-
# Returns whether the specification is supported in a given platform
|
534
|
-
def supports_platform?(*platform)
|
535
|
-
platform = platform[0].is_a?(Platform) ? platform[0] : Platform.new(*platform)
|
536
|
-
available_platforms.any? { |p| platform.supports?(p) }
|
537
|
-
end
|
538
|
-
|
539
|
-
# Defines the active platform for comsumption of the specification and
|
540
|
-
# returns self for method chainability.
|
541
|
-
# The active platform must the the same accross the chain so attributes
|
542
|
-
# that are inherited can be correctly resolved.
|
543
|
-
def activate_platform(*platform)
|
544
|
-
platform = platform[0].is_a?(Platform) ? platform[0] : Platform.new(*platform)
|
545
|
-
raise Informative, "#{to_s} is not compatible with #{platform}." unless supports_platform?(platform)
|
546
|
-
top_level_parent.active_platform = platform.to_sym
|
547
|
-
self
|
548
|
-
end
|
549
|
-
|
550
|
-
top_attr_accessor :active_platform
|
551
|
-
|
552
|
-
### Not attributes
|
553
|
-
|
554
|
-
# @visibility private
|
555
|
-
#
|
556
|
-
# This is used by PlatformProxy to assign attributes for the scoped platform.
|
557
|
-
def _on_platform(platform)
|
558
|
-
before, @define_for_platforms = @define_for_platforms, [platform]
|
559
|
-
yield
|
560
|
-
ensure
|
561
|
-
@define_for_platforms = before
|
562
|
-
end
|
563
|
-
|
564
|
-
# @visibility private
|
565
|
-
#
|
566
|
-
# This is multi-platform and to support
|
567
|
-
# subspecs with different platforms is is resolved as the
|
568
|
-
# first non nil value accross the chain.
|
569
|
-
def deployment_target=(version)
|
570
|
-
raise Informative, "The deployment target must be defined per platform like `s.ios.deployment_target = '5.0'`." unless @define_for_platforms.count == 1
|
571
|
-
@deployment_target[@define_for_platforms.first] = version
|
572
|
-
end
|
573
|
-
|
574
|
-
def deployment_target(platform)
|
575
|
-
@deployment_target[platform] || ( @parent ? @parent.deployment_target(platform) : nil )
|
576
|
-
end
|
577
|
-
end
|
578
|
-
Spec = Specification
|
579
|
-
end
|