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.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +108 -0
  3. data/README.md +3 -3
  4. data/bin/pod +1 -1
  5. data/lib/cocoapods.rb +31 -31
  6. data/lib/cocoapods/command.rb +62 -107
  7. data/lib/cocoapods/command/inter_process_communication.rb +103 -0
  8. data/lib/cocoapods/command/list.rb +45 -44
  9. data/lib/cocoapods/command/outdated.rb +28 -25
  10. data/lib/cocoapods/command/project.rb +90 -0
  11. data/lib/cocoapods/command/push.rb +50 -32
  12. data/lib/cocoapods/command/repo.rb +125 -155
  13. data/lib/cocoapods/command/search.rb +23 -12
  14. data/lib/cocoapods/command/setup.rb +103 -64
  15. data/lib/cocoapods/command/spec.rb +329 -90
  16. data/lib/cocoapods/config.rb +197 -44
  17. data/lib/cocoapods/downloader.rb +47 -34
  18. data/lib/cocoapods/executable.rb +98 -41
  19. data/lib/cocoapods/external_sources.rb +325 -0
  20. data/lib/cocoapods/file_list.rb +8 -1
  21. data/lib/cocoapods/gem_version.rb +7 -0
  22. data/lib/cocoapods/generator/acknowledgements.rb +71 -7
  23. data/lib/cocoapods/generator/acknowledgements/markdown.rb +10 -9
  24. data/lib/cocoapods/generator/acknowledgements/plist.rb +9 -8
  25. data/lib/cocoapods/generator/copy_resources_script.rb +2 -2
  26. data/lib/cocoapods/generator/documentation.rb +153 -37
  27. data/lib/cocoapods/generator/prefix_header.rb +82 -0
  28. data/lib/cocoapods/generator/target_header.rb +58 -0
  29. data/lib/cocoapods/generator/xcconfig.rb +130 -0
  30. data/lib/cocoapods/hooks/installer_representation.rb +123 -0
  31. data/lib/cocoapods/hooks/library_representation.rb +79 -0
  32. data/lib/cocoapods/hooks/pod_representation.rb +74 -0
  33. data/lib/cocoapods/installer.rb +398 -147
  34. data/lib/cocoapods/installer/analyzer.rb +556 -0
  35. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +253 -0
  36. data/lib/cocoapods/installer/file_references_installer.rb +179 -0
  37. data/lib/cocoapods/installer/pod_source_installer.rb +289 -0
  38. data/lib/cocoapods/installer/target_installer.rb +307 -112
  39. data/lib/cocoapods/installer/user_project_integrator.rb +140 -176
  40. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +193 -0
  41. data/lib/cocoapods/library.rb +195 -0
  42. data/lib/cocoapods/open_uri.rb +16 -14
  43. data/lib/cocoapods/project.rb +175 -52
  44. data/lib/cocoapods/resolver.rb +151 -164
  45. data/lib/cocoapods/sandbox.rb +276 -54
  46. data/lib/cocoapods/sandbox/file_accessor.rb +210 -0
  47. data/lib/cocoapods/sandbox/headers_store.rb +96 -0
  48. data/lib/cocoapods/sandbox/path_list.rb +178 -0
  49. data/lib/cocoapods/sources_manager.rb +218 -0
  50. data/lib/cocoapods/user_interface.rb +82 -18
  51. data/lib/cocoapods/{command → user_interface}/error_report.rb +5 -5
  52. data/lib/cocoapods/validator.rb +379 -0
  53. metadata +74 -55
  54. data/lib/cocoapods/command/install.rb +0 -55
  55. data/lib/cocoapods/command/linter.rb +0 -317
  56. data/lib/cocoapods/command/update.rb +0 -25
  57. data/lib/cocoapods/dependency.rb +0 -285
  58. data/lib/cocoapods/downloader/git.rb +0 -276
  59. data/lib/cocoapods/downloader/http.rb +0 -99
  60. data/lib/cocoapods/downloader/mercurial.rb +0 -26
  61. data/lib/cocoapods/downloader/subversion.rb +0 -42
  62. data/lib/cocoapods/local_pod.rb +0 -620
  63. data/lib/cocoapods/lockfile.rb +0 -274
  64. data/lib/cocoapods/platform.rb +0 -127
  65. data/lib/cocoapods/podfile.rb +0 -551
  66. data/lib/cocoapods/source.rb +0 -223
  67. data/lib/cocoapods/specification.rb +0 -579
  68. data/lib/cocoapods/specification/set.rb +0 -175
  69. data/lib/cocoapods/specification/statistics.rb +0 -112
  70. data/lib/cocoapods/user_interface/ui_pod.rb +0 -130
  71. data/lib/cocoapods/version.rb +0 -26
@@ -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