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