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/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
|