cocoapods 0.6.0.rc2 → 0.6.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -50,13 +50,17 @@ Now that you've got CocoaPods installed you can easily add it to your project.
50
50
  Search for Pods by name or description.
51
51
 
52
52
  ```
53
- $ pod search asi
54
- ==> ASIHTTPRequest (1.8.1)
55
- Easy to use CFNetwork wrapper for HTTP requests, Objective-C, Mac OS X and iPhone
53
+ $ pod search json
56
54
 
57
- ==> ASIWebPageRequest (1.8.1)
58
- The ASIWebPageRequest class included with ASIHTTPRequest lets you download
59
- complete webpages, including external resources like images and stylesheets.
55
+ --> JSONKit (1.4, 1.5pre)
56
+ A Very High Performance Objective-C JSON Library.
57
+ - Homepage: https://github.com/johnezang/JSONKit
58
+ - Source: https://github.com/johnezang/JSONKit.git
59
+
60
+ --> SBJson (2.2.3, 3.0.4, 3.1)
61
+ This library implements strict JSON parsing and generation in Objective-C.
62
+ - Homepage: http://stig.github.com/json-framework/
63
+ - Source: https://github.com/stig/json-framework.git
60
64
  ```
61
65
 
62
66
  After you've found your favorite dependencies you add them to your [Podfile](https://github.com/CocoaPods/CocoaPods/wiki/A-Podfile).
@@ -1,7 +1,5 @@
1
- Encoding.default_external = Encoding::UTF_8 if RUBY_VERSION > '1.8.7'
2
-
3
1
  module Pod
4
- VERSION = '0.6.0.rc2'
2
+ VERSION = '0.6.0.rc3'
5
3
 
6
4
  class PlainInformative < StandardError
7
5
  end
@@ -241,13 +241,14 @@ module Pod
241
241
  end
242
242
 
243
243
  def podfile_from_spec
244
- name = spec.name
245
- podspec = file.realpath.to_s
246
- platform_sym = @platform.to_sym
247
- podfile = Pod::Podfile.new do
248
- platform(platform_sym)
244
+ name = spec.name
245
+ podspec = file.realpath.to_s
246
+ platform = @platform
247
+ podfile = Pod::Podfile.new do
248
+ platform(platform)
249
249
  dependency name, :podspec => podspec
250
250
  end
251
+ podfile
251
252
  end
252
253
 
253
254
  def set_up_lint_environment
@@ -337,7 +338,7 @@ module Pod
337
338
  messages << "The description should end with a dot" if @spec.description !~ /.*\./ && @spec.description != @spec.summary
338
339
  messages << "Git sources should specify either a tag or a commit" if source[:git] && !source[:commit] && !source[:tag]
339
340
  messages << "Github repositories should end in `.git'" if github_source? && source[:git] !~ /.*\.git/
340
- messages << "Github repositories should use `https' link" if github_source? && source[:git] !~ /https:\/\/github.com/
341
+ # messages << "Github repositories should use `https' link" if github_source? && source[:git] !~ /https:\/\/github.com/
341
342
  messages << "Comments must be deleted" if text =~ /^\w*#\n\w*#/ # allow a single line comment as it is generally used in subspecs
342
343
  messages
343
344
  end
@@ -405,7 +406,7 @@ module Pod
405
406
  def file_patterns_errors
406
407
  messages = []
407
408
  messages << "The sources did not match any file" if !@spec.source_files.empty? && @pod.source_files.empty?
408
- messages << "The resources did not match any file" if !@spec.resources.empty? && @pod.resources.empty?
409
+ messages << "The resources did not match any file" if !@spec.resources.empty? && @pod.resource_files.empty?
409
410
  messages << "The preserve_paths did not match any file" if !@spec.preserve_paths.empty? && @pod.preserve_paths.empty?
410
411
  messages << "The exclude_header_search_paths did not match any file" if !@spec.exclude_header_search_paths.empty? && @pod.headers_excluded_from_search_paths.empty?
411
412
  messages
@@ -29,7 +29,7 @@ module Pod
29
29
  pods.each do |pod|
30
30
  # Add all source files to the project grouped by pod
31
31
  group = @project.add_pod_group(pod.name)
32
- pod.source_files.each do |path|
32
+ pod.relative_source_files.each do |path|
33
33
  group.files.new('path' => path.to_s)
34
34
  end
35
35
  end
@@ -20,12 +20,12 @@ module Pod
20
20
  end
21
21
 
22
22
  def copy_resources_script_for(pods)
23
- @copy_resources_script ||= Generator::CopyResourcesScript.new(pods.map { |p| p.resources }.flatten)
23
+ @copy_resources_script ||= Generator::CopyResourcesScript.new(pods.map { |p| p.relative_resource_files }.flatten)
24
24
  end
25
25
 
26
26
  def bridge_support_generator_for(pods, sandbox)
27
27
  Generator::BridgeSupport.new(pods.map do |pod|
28
- pod.header_files.map { |header| sandbox.root + header }
28
+ pod.relative_header_files.map { |header| sandbox.root + header }
29
29
  end.flatten)
30
30
  end
31
31
 
@@ -62,13 +62,15 @@ module Pod
62
62
 
63
63
  @target = @project.add_pod_target(@target_definition.label, @target_definition.platform)
64
64
 
65
+ source_file_descriptions = []
65
66
  pods.each do |pod|
66
67
  xcconfig.merge!(pod.xcconfig)
67
- pod.add_to_target(@target)
68
+ source_file_descriptions += pod.source_file_descriptions
68
69
 
69
70
  # TODO: this doesn't need to be done here, it has nothing to do with the target
70
71
  pod.link_headers
71
72
  end
73
+ @target.add_source_files(source_file_descriptions)
72
74
 
73
75
  xcconfig.merge!('HEADER_SEARCH_PATHS' => quoted(sandbox.header_search_paths).join(" "))
74
76
 
@@ -1,125 +1,266 @@
1
1
  module Pod
2
+
3
+ # A {LocalPod} interfaces one or more specifications belonging to one pod
4
+ # (a library) and their concrete instance in the file system.
5
+ #
6
+ # The {LocalPod} is responsible for orchestrating the activated
7
+ # specifications of a single pod. Specifically, it keeps track of the
8
+ # activated specifications and handles issues related to duplicates
9
+ # files.
10
+ # Inheritance logic belongs to the {Specification} class.
11
+ #
12
+ # The activated specifications are used to compute the paths that can be
13
+ # safely cleaned by the pod.
14
+ #
15
+ # @example
16
+ # pod = LocalPod.new 'RestKit/Networking'
17
+ # pod.add_specification 'RestKit/UI'
18
+ #
19
+ # @note
20
+ # Unless otherwise specified in the name of the method the {LocalPod}
21
+ # returns absolute paths.
22
+ #
2
23
  class LocalPod
3
- attr_reader :top_specification, :specifications
24
+
25
+ # @return [Specification] The specification that describes the pod.
26
+ #
27
+ attr_reader :top_specification
28
+
29
+ # @return [Specification] The activated specifications of the pod.
30
+ #
31
+ attr_reader :specifications
32
+
33
+ # @return [Sandbox] The sandbox where the pod is installed.
34
+ #
4
35
  attr_reader :sandbox
5
36
 
37
+ # @return [Platform] The platform that will be used to build the pod.
38
+ #
39
+ attr_reader :platform
40
+
41
+ # @param [Specification] specification
42
+ # The first activated specification of the pod.
43
+ # @param [Sandbox] sandbox
44
+ # The sandbox where the files of the pod will be located.
45
+ # @param [Platform] platform
46
+ # The platform that will be used to build the pod.
47
+ #
48
+ # @todo The local pod should be initialized with all the activated
49
+ # specifications passed as an array, in order to be able to cache the
50
+ # computed values. In other words, it should be immutable.
51
+ #
6
52
  def initialize(specification, sandbox, platform)
7
- @top_specification, @sandbox = specification.top_level_parent, sandbox
53
+ @top_specification, @sandbox, @platform = specification.top_level_parent, sandbox, platform
8
54
  @top_specification.activate_platform(platform)
9
55
  @specifications = [] << specification
10
56
  end
11
57
 
58
+ # Initializes a local pod from the top specification of a podspec file.
59
+ #
60
+ # @return [LocalPod] A new local pod.
61
+ #
12
62
  def self.from_podspec(podspec, sandbox, platform)
13
63
  new(Specification.from_file(podspec), sandbox, platform)
14
64
  end
15
65
 
16
- # Method to add the specifications sharing the same top level
17
- # parent. With this information the local pod can determine the
18
- # paths to clean and avoid duplication in file processing.
66
+ # Activates a specification or subspecs for the pod.
19
67
  # Adding specifications is idempotent.
68
+ #
69
+ # @param {Specification} spec The specification to add to the pod.
70
+ #
71
+ # @raise {Informative} If the specification is not part of the same pod.
72
+ #
20
73
  def add_specification(spec)
21
- raise Informative, "[Local Pod] Attempt to add a specification from another pod" unless spec.top_level_parent == top_specification
74
+ unless spec.top_level_parent == top_specification
75
+ raise Informative,
76
+ "[Local Pod] Attempt to add a specification from another pod"
77
+ end
22
78
  spec.activate_platform(platform)
23
79
  @specifications << spec unless @specifications.include?(spec)
24
80
  end
25
81
 
82
+ # @return [Pathname] The root directory of the pod
83
+ #
26
84
  def root
27
85
  @sandbox.root + top_specification.name
28
86
  end
29
87
 
30
- def subspecs
31
- specifications.reject{|s| s.parent.nil? }
32
- end
33
-
88
+ # @return [String] A string representation of the pod which indicates if
89
+ # the pods comes from a local source.
90
+ #
34
91
  def to_s
35
92
  result = top_specification.to_s
36
93
  result << " [LOCAL]" if top_specification.local?
37
94
  result
38
95
  end
39
96
 
97
+ # @return [String] The name of the Pod.
98
+ #
40
99
  def name
41
100
  top_specification.name
42
101
  end
43
102
 
44
- def platform
45
- top_specification.active_platform
46
- end
47
-
48
- # Installation methods
103
+ # @!group Installation
49
104
 
105
+ # Creates the root path of the pod.
106
+ #
107
+ # @return [void]
108
+ #
50
109
  def create
51
110
  root.mkpath unless exists?
52
111
  end
53
112
 
113
+ # Whether the root path of the pod exists.
114
+ #
54
115
  def exists?
55
116
  root.exist?
56
117
  end
57
118
 
119
+ # Executes a block in the root directory of the Pod.
120
+ #
121
+ # @return [void]
122
+ #
58
123
  def chdir(&block)
59
124
  create
60
125
  Dir.chdir(root, &block)
61
126
  end
62
127
 
128
+ # Deletes the pod from the file system.
129
+ #
130
+ # @return [void]
131
+ #
63
132
  def implode
64
133
  root.rmtree if exists?
65
134
  end
66
135
 
67
- ### Cleaning
136
+ # @!group Cleaning
68
137
 
69
- # Public: Deletes any path that is not used by the pod.
138
+ # Deletes any path that is not used by the pod.
139
+ #
140
+ # @return [void]
141
+ #
70
142
  def clean
71
143
  clean_paths.each { |path| FileUtils.rm_rf(path) }
144
+ @cleaned = true
72
145
  end
73
146
 
74
- # Public: Finds the absolute paths, including hidden ones, of the files
75
- # that are not used by the pod and can be safely deleted.
147
+ # Finds the absolute paths, including hidden ones, of the files
148
+ # that are not used by the pod and thus can be safely deleted.
149
+ #
150
+ # @return [Array<Strings>] The paths that can be deleted.
76
151
  #
77
- # Returns an Array of Strings containing the absolute paths.
78
152
  def clean_paths
79
- cached_used_paths = used_paths.map{ |path| path.to_s }
153
+ cached_used_paths = used_files
80
154
  files = Dir.glob(root + "**/*", File::FNM_DOTMATCH)
155
+
81
156
  files.reject! do |candidate|
82
- candidate.end_with?('.', '..') ||
83
- cached_used_paths.any? { |path| path.include?(candidate) || candidate.include?(path) }
157
+ candidate.end_with?('.', '..') || cached_used_paths.any? do |path|
158
+ path.include?(candidate) || candidate.include?(path)
159
+ end
84
160
  end
85
161
  files
86
162
  end
87
163
 
88
- # Public: Finds all the absolute paths used by pod.
164
+ # @return [Array<String>] The absolute path of the files used by the pod.
89
165
  #
90
- # Returns an Array of Pathnames containing the absolute paths.
91
- def used_paths
92
- files = source_files(false) + resources(false) + preserve_paths + [ readme_file, license_file, prefix_header_file ]
93
- files.compact
166
+ def used_files
167
+ files = [ source_files, resource_files, preserve_files, readme_file, license_file, prefix_header_file ]
168
+ files.compact!
169
+ files.flatten!
170
+ files.map!{ |path| path.to_s }
171
+ files
94
172
  end
95
173
 
96
- ### File attributes
174
+ # @!group Files
97
175
 
98
- def prefix_header_file
99
- root + top_specification.prefix_header_file if top_specification.prefix_header_file
176
+ # @return [Array<Pathname>] The paths of the source files.
177
+ #
178
+ def source_files
179
+ source_files_by_spec.values.flatten
180
+ end
181
+
182
+ # @return [Array<Pathname>] The *relative* paths of the source files.
183
+ #
184
+ def relative_source_files
185
+ source_files.map{ |p| p.relative_path_from(@sandbox.root) }
100
186
  end
101
187
 
102
- def source_files(relative = true)
103
- chained_expanded_paths(:source_files, :glob => '*.{h,m,mm,c,cpp}', :relative_to_sandbox => relative)
188
+ # Finds the source files that every activated {Specification} requires.
189
+ #
190
+ # @note If the same file is required by two specifications the one at the
191
+ # higher level in the inheritance chain wins.
192
+ #
193
+ # @return [Hash{Specification => Array<Pathname>}] The files grouped by
194
+ # {Specification}.
195
+ #
196
+ def source_files_by_spec
197
+ options = {:glob => '*.{h,m,mm,c,cpp}'}
198
+ paths_by_spec(:source_files, options)
104
199
  end
105
200
 
201
+ # @return [Array<Pathname>] The paths of the header files.
202
+ #
106
203
  def header_files
107
- source_files.select { |f| f.extname == '.h' }
204
+ header_files_by_spec.values.flatten
108
205
  end
109
206
 
110
- def resources(relative = true)
111
- chained_expanded_paths(:resources, :relative_to_sandbox => relative)
207
+ # @return [Array<Pathname>] The *relative* paths of the source files.
208
+ #
209
+ def relative_header_files
210
+ header_files.map{ |p| p.relative_path_from(@sandbox.root) }
112
211
  end
113
212
 
114
- # TODO: implement case insensitive search
115
- def preserve_paths
116
- chained_expanded_paths(:preserve_paths) + expanded_paths(%w[ *.podspec notice* NOTICE* CREDITS* ])
213
+ # @return [Hash{Specification => Array<Pathname>}] The paths of the header
214
+ # files grouped by {Specification}.
215
+ #
216
+ def header_files_by_spec
217
+ result = {}
218
+ source_files_by_spec.each do |spec, paths|
219
+ headers = paths.select { |f| f.extname == '.h' }
220
+ result[spec] = headers unless headers.empty?
221
+ end
222
+ result
223
+ end
224
+
225
+ # @return [Array<Pathname>] The paths of the resources.
226
+ #
227
+ def resource_files
228
+ paths_by_spec(:resources).values.flatten
229
+ end
230
+
231
+ # @return [Array<Pathname>] The *relative* paths of the resources.
232
+ #
233
+ def relative_resource_files
234
+ resource_files.map{ |p| p.relative_path_from(@sandbox.root) }
235
+ end
236
+
237
+ # @return [Pathname] The absolute path of the prefix header file
238
+ #
239
+ def prefix_header_file
240
+ root + top_specification.prefix_header_file if top_specification.prefix_header_file
117
241
  end
118
242
 
243
+ # @return [Array<Pathname>] The absolute paths of the files of the pod
244
+ # that should be preserved.
245
+ #
246
+ def preserve_files
247
+ paths = paths_by_spec(:preserve_paths).values
248
+ paths += expanded_paths(%w[ *.podspec notice* NOTICE* CREDITS* ])
249
+ paths.compact!
250
+ paths.uniq!
251
+ paths
252
+ end
253
+
254
+ # @return [Pathname] The automatically detected absolute path of the README
255
+ # file.
256
+ #
119
257
  def readme_file
120
258
  expanded_paths(%w[ README{*,.*} readme{*,.*} ]).first
121
259
  end
122
260
 
261
+ # @return [Pathname] The absolute path of the license file from the
262
+ # specification or automatically detected.
263
+ #
123
264
  def license_file
124
265
  if top_specification.license && top_specification.license[:file]
125
266
  root + top_specification.license[:file]
@@ -128,6 +269,9 @@ module Pod
128
269
  end
129
270
  end
130
271
 
272
+ # @return [String] The text of the license of the pod from the
273
+ # specification or from the license file.
274
+ #
131
275
  def license_text
132
276
  if (license_hash = top_specification.license)
133
277
  if (result = license_hash[:text])
@@ -142,88 +286,162 @@ module Pod
142
286
  specifications.map { |s| s.xcconfig }.reduce(:merge)
143
287
  end
144
288
 
145
- # Method used by documentation generator. It return the source files
146
- # of all the specs.
289
+ # Computes the paths of all the public headers of the pod including every
290
+ # subspec. For this reason the pod must not be cleaned before calling it.
291
+ #
292
+ # This method is used by {Generator::Documentation}.
293
+ #
294
+ # @raise [Informative] If the pod was cleaned.
295
+ #
296
+ # @todo Merge with #221
297
+ #
298
+ # @return [Array<Pathname>] The path of all the public headers of the pod.
299
+ #
147
300
  def all_specs_public_header_files
148
- #TODO: merge with #221
149
- specs = top_specification.recursive_subspecs << top_specification
150
- specs.map { |s| expanded_paths(s.source_files, :glob => '*.{h}') }.compact.flatten.select { |f| f.extname == '.h' }.uniq
301
+ if @cleaned
302
+ raise Informative, "The pod is cleaned and cannot compute the all the "\
303
+ "header files as they might be deleted."
304
+ end
305
+
306
+ all_specs = [ top_specification ] + top_specification.subspecs
307
+ options = {:glob => '*.{h}'}
308
+ files = paths_by_spec(:source_files, options, all_specs).values.flatten!
309
+ headers = files.select { |f| f.extname == '.h' }
310
+ headers
151
311
  end
152
312
 
153
- # Integration methods
313
+ # @!group Target integration
154
314
 
315
+ # @return [void] Copies the pods headers to the sandbox.
316
+ #
155
317
  def link_headers
156
- copy_header_mappings.each do |namespaced_path, files|
318
+ @sandbox.add_header_search_path(headers_sandbox)
319
+ header_mappings.each do |namespaced_path, files|
157
320
  @sandbox.add_header_files(namespaced_path, files)
158
321
  end
159
322
  end
160
323
 
161
- def add_to_target(target)
162
- sources_files_by_specification.each do | spec, files |
324
+ # @param [Xcodeproj::Project::Object::PBXNativeTarget] target
325
+ # The target to integrate.
326
+ #
327
+ # @return [void] Adds the pods source files to a given target.
328
+ #
329
+ def source_file_descriptions
330
+ result = []
331
+ source_files_by_spec.each do | spec, files |
332
+ compiler_flags = spec.compiler_flags.strip
163
333
  files.each do |file|
164
- # TODO: Xcodeproj::Project::Object::PBXNativeTarget#add_source_file is quite slow
165
- # The issus appears to be related to the find call in line 107.
166
- target.add_source_file(file, nil, spec.compiler_flags.strip)
334
+ file = file.relative_path_from(@sandbox.root)
335
+ desc = Xcodeproj::Project::PBXNativeTarget::SourceFileDescription.new(file, compiler_flags, nil)
336
+ result << desc
167
337
  end
168
338
  end
339
+ result
169
340
  end
170
341
 
342
+ # @return Whether the pod requires ARC.
343
+ #
171
344
  def requires_arc?
172
345
  top_specification.requires_arc
173
346
  end
174
347
 
175
348
  private
176
349
 
350
+ # @return [Array<Pathname>] The implementation files
351
+ # (the files the need to compiled) of the pod.
352
+ #
177
353
  def implementation_files
178
- source_files.select { |f| f.extname != '.h' }
354
+ relative_source_files.select { |f| f.extname != '.h' }
179
355
  end
180
356
 
357
+ # @return [Pathname] The path of the pod relative from the sandbox.
358
+ #
181
359
  def relative_root
182
360
  root.relative_path_from(@sandbox.root)
183
361
  end
184
362
 
185
- # TODO this is being overriden in the RestKit 0.9.4 spec, need to do
363
+ # @return Hash{Pathname => [Array<Pathname>]} A hash containing the headers
364
+ # folders as the keys and the the absolute paths of the header files
365
+ # as the values.
366
+ #
367
+ # @todo this is being overridden in the RestKit 0.9.4 spec, need to do
186
368
  # something with that, and this method also still exists in Specification.
187
369
  #
188
- # This is not overriden anymore in specification refactor and the code
189
- # Pod::Specification#copy_header_mapping can be moved here.
190
- def copy_header_mappings
191
- search_path_headers = header_files - headers_excluded_from_search_paths
192
- search_path_headers.inject({}) do |mappings, from|
193
- from_without_prefix = from.relative_path_from(relative_root)
194
- to = top_specification.header_dir + top_specification.copy_header_mapping(from_without_prefix)
195
- (mappings[to.dirname] ||= []) << from
196
- mappings
370
+ # @todo This is not overridden anymore in specification refactor and the
371
+ # code Pod::Specification#copy_header_mapping can be moved here.
372
+ def header_mappings
373
+ mappings = {}
374
+ header_files_by_spec.each do |spec, paths|
375
+ paths = paths - headers_excluded_from_search_paths
376
+ paths.each do |from|
377
+ from_relative = from.relative_path_from(root)
378
+ to = headers_sandbox + (spec.header_dir) + spec.copy_header_mapping(from_relative)
379
+ (mappings[to.dirname] ||= []) << from
380
+ end
197
381
  end
382
+ mappings
198
383
  end
199
384
 
200
- # returns an hash where the source_files are groupped by specification.
201
- # If the same file is required by two specifications the one at the
202
- # higher level in the inheritance chain wins.
203
- def sources_files_by_specification
204
- files_by_spec = {}
205
- processed_files = []
206
- specifications.sort_by { |s| s.name.length }.each do |spec|
207
- files = []
208
- expanded_paths(spec.source_files, :glob => '*.{h,m,mm,c,cpp}', :relative_to_sandbox => true).each do | file |
209
- files << file unless processed_files.include?(file)
210
- end
211
- files_by_spec[spec] = files
212
- processed_files += files
213
- end
214
- files_by_spec
385
+ def headers_sandbox
386
+ @headers_sandbox ||= Pathname.new(top_specification.name)
215
387
  end
216
388
 
389
+ # @return [<Pathname>] The relative path of the headers that should not be
390
+ # included in the linker search paths.
391
+ #
217
392
  def headers_excluded_from_search_paths
218
- chained_expanded_paths(:exclude_header_search_paths, :glob => '*.h', :relative_to_sandbox => true)
393
+ options = { :glob => '*.h' }
394
+ paths = paths_by_spec(:exclude_header_search_paths, options)
395
+ paths.values.compact.uniq
219
396
  end
220
397
 
221
- def chained_expanded_paths(accessor, options = {})
222
- specifications.map { |s| expanded_paths(s.send(accessor), options) }.compact.flatten.uniq
398
+ # @!group Paths Patterns
399
+
400
+ # The paths obtained by resolving the patterns of an attribute
401
+ # groupped by spec.
402
+ #
403
+ # @param [Symbol] accessor The accessor to use to obtain the paths patterns.
404
+ # @param [Hash] options (see #expanded_paths)
405
+ #
406
+ def paths_by_spec(accessor, options = {}, specs = nil)
407
+ specs ||= specifications
408
+ paths_by_spec = {}
409
+ processed_paths = []
410
+
411
+ specs = specs.sort_by { |s| s.name.length }
412
+ specs.each do |spec|
413
+ paths = expanded_paths(spec.send(accessor), options)
414
+ unless paths.empty?
415
+ paths_by_spec[spec] = paths - processed_paths
416
+ processed_paths += paths
417
+ end
418
+ end
419
+ paths_by_spec
223
420
  end
224
421
 
422
+ # Converts patterns of paths to the {Pathname} of the files present in the
423
+ # pod.
424
+ #
425
+ # @param [String, FileList, Array<String, Pathname>] patterns
426
+ # The patterns to expand.
427
+ # @param [Hash] options
428
+ # The options to used for expanding the paths patterns.
429
+ # @option options [String] :glob
430
+ # The pattern to use for globing directories.
431
+ #
432
+ # @raise [Informative] If the pod does not exists.
433
+ #
434
+ # @todo implement case insensitive search
435
+ #
436
+ # @return [Array<Pathname>] A list of the paths.
437
+ #
225
438
  def expanded_paths(patterns, options = {})
226
- raise Informative, "[Local Pod] Attempt to resolve paths for non existent pod." unless exists?
439
+ unless exists?
440
+ raise Informative, "[Local Pod] Attempt to resolve paths for nonexistent pod.\n" \
441
+ "\tSpecifications: #{@specifications.inspect}\n" \
442
+ "\t Patterns: #{patterns.inspect}\n" \
443
+ "\t Options: #{options.inspect}"
444
+ end
227
445
 
228
446
  patterns = [ patterns ] if patterns.is_a? String
229
447
  patterns.map do |pattern|
@@ -234,11 +452,7 @@ module Pod
234
452
  end
235
453
 
236
454
  pattern.glob.map do |file|
237
- if options[:relative_to_sandbox]
238
- file.relative_path_from(@sandbox.root)
239
- else
240
- file
241
- end
455
+ file
242
456
  end
243
457
  end.flatten
244
458
  end
@@ -1,68 +1,140 @@
1
1
  module Pod
2
+
3
+ # A platform describes an SDK name and deployment target.
4
+ #
2
5
  class Platform
6
+
7
+ # @return [Platform] Convenience method to initialize an iOS platform.
8
+ #
3
9
  def self.ios
4
10
  new :ios
5
11
  end
6
12
 
13
+ # @return [Platform] Convenience method to initialize an OS X platform.
14
+ #
7
15
  def self.osx
8
16
  new :osx
9
17
  end
10
18
 
11
- attr_reader :deployment_target
19
+ # Constructs a platform from either another platform or by
20
+ # specifying the symbolic name and optionally the deployment target.
21
+ #
22
+ # @overload initialize(name, deployment_target)
23
+ # @param [Symbol] name The name of platform.
24
+ # @param [String, Version] deployment_target The optional deployment.
25
+ # If not provided a default value according to the platform name will
26
+ # be assigned.
27
+ #
28
+ # @note that if the name is not specified a default deployment
29
+ # target will not be assigned.
30
+ #
31
+ # @example
32
+ #
33
+ # Platform.new(:ios)
34
+ # Platform.new(:ios, '4.3')
35
+ #
36
+ # @overload initialize(name, opts)
37
+ # @deprecated Remove after adding a warning to {Podfile} class.
38
+ # @param [Symbol] name The name of platform.
39
+ # @param [Hash] opts The options to create a platform with.
40
+ # @option opts [String, Version] :deployment_target The deployment target.
41
+ #
42
+ # @overload initialize(platform)
43
+ # @param [Platform] platform Another {Platform}.
44
+ #
45
+ # @example
46
+ #
47
+ # platform = Platform.new(:ios)
48
+ # Platform.new(platform)
49
+ #
50
+ def initialize(input, target = nil)
51
+ if input.is_a? Platform
52
+ @symbolic_name = input.name
53
+ @deployment_target = input.deployment_target
54
+ @declared_deployment_target = input.declared_deployment_target
55
+ else
56
+ @symbolic_name = input
57
+
58
+ target = target[:deployment_target] if target.is_a?(Hash)
59
+ @declared_deployment_target = target
12
60
 
13
- def initialize(symbolic_name = nil, deployment_target = nil)
14
- @symbolic_name = symbolic_name
15
- if deployment_target
16
- version = deployment_target.is_a?(Hash) ? deployment_target[:deployment_target] : deployment_target # backwards compatibility from 0.6
17
- @deployment_target = Pod::Version.create(version)
61
+ unless target
62
+ case @symbolic_name
63
+ when :ios
64
+ target = '4.3'
65
+ when :osx
66
+ target = '10.6'
67
+ else
68
+ target = ''
69
+ end
70
+ end
71
+ @deployment_target = Version.create(target)
18
72
  end
19
73
  end
20
74
 
75
+ # @return [Symbol] The name of the SDK represented by the platform.
76
+ #
21
77
  def name
22
78
  @symbolic_name
23
79
  end
24
80
 
25
- def deployment_target= (version)
26
- @deployment_target = Pod::Version.create(version)
27
- end
81
+ # @return [Version] The deployment target of the platform.
82
+ #
83
+ attr_reader :deployment_target
84
+
85
+ # @return [Version] The deployment target declared on initialization.
86
+ #
87
+ attr_reader :declared_deployment_target
28
88
 
29
- def ==(other_platform_or_symbolic_name)
30
- if other_platform_or_symbolic_name.is_a?(Symbol)
31
- @symbolic_name == other_platform_or_symbolic_name
89
+ # @param [Platform, Symbol] other The other platform to check.
90
+ #
91
+ # @note If a symbol is passed the comparison does not take into account
92
+ # the deployment target.
93
+ #
94
+ # @return [Boolean] Whether two platforms are the equivalent.
95
+ #
96
+ def ==(other)
97
+ if other.is_a?(Symbol)
98
+ @symbolic_name == other
32
99
  else
33
- self.name == (other_platform_or_symbolic_name.name) && self.deployment_target == other_platform_or_symbolic_name.deployment_target
100
+ (name == other.name) && (deployment_target == other.deployment_target)
34
101
  end
35
102
  end
36
103
 
104
+ # In the context of operating system SDKs, a platform supports another
105
+ # one if they have the same name and the other platform has a minor or
106
+ # equal deployment target.
107
+ #
108
+ # @return Whether the platform supports another platform.
109
+ #
37
110
  def supports?(other)
38
- return true if @symbolic_name.nil? || other.nil?
39
- os_check = @symbolic_name == other.name
40
- version_check = (deployment_target.nil? || other.deployment_target.nil? || deployment_target >= other.deployment_target)
41
- os_check && version_check
111
+ other = Platform.new(other)
112
+ (other.name == name) && (other.deployment_target <= deployment_target)
42
113
  end
43
114
 
115
+ # @return [String] A string representation including the deployment target.
116
+ #
44
117
  def to_s
45
118
  case @symbolic_name
46
119
  when :ios
47
- 'iOS' + (deployment_target ? " #{deployment_target}" : '')
120
+ s = 'iOS'
48
121
  when :osx
49
- 'OS X' + (deployment_target ? " #{deployment_target}" : '')
50
- else
51
- 'iOS - OS X'
122
+ s = 'OS X'
52
123
  end
124
+ s << " #{declared_deployment_target}" if declared_deployment_target
125
+ s
53
126
  end
54
127
 
128
+ # @return [Symbol] A Symbol representation of the name.
129
+ #
55
130
  def to_sym
56
131
  name
57
132
  end
58
133
 
59
- def nil?
60
- name.nil?
61
- end
62
-
134
+ # @return Whether the platform requires legacy architectures for iOS.
135
+ #
63
136
  def requires_legacy_ios_archs?
64
- return unless deployment_target
65
- (name == :ios) && (deployment_target < Pod::Version.new("4.3"))
137
+ (name == :ios) && (deployment_target < Version.new("4.3"))
66
138
  end
67
139
  end
68
140
  end
@@ -153,7 +153,10 @@ module Pod
153
153
 
154
154
  def self.from_file(path)
155
155
  podfile = Podfile.new do
156
- eval(path.read, nil, path.to_s)
156
+ string = File.open(path, 'r:utf-8') { |f| f.read }
157
+ # TODO: work around for Rubinius incomplete encoding in 1.9 mode
158
+ string.encode!('UTF-8') if string.respond_to?(:encoding) && string.encoding.name != "UTF-8"
159
+ eval(string, nil, path.to_s)
157
160
  end
158
161
  podfile.defined_in_file = path
159
162
  podfile.validate!
@@ -332,12 +335,14 @@ module Pod
332
335
  # Pod::Specification is yielded to the block. This is the same class which
333
336
  # is normally used to specify a Pod.
334
337
  #
338
+ # ```
335
339
  # dependency do |spec|
336
340
  # spec.name = 'JSONKit'
337
341
  # spec.version = '1.4'
338
342
  # spec.source = { :git => 'https://github.com/johnezang/JSONKit.git', :tag => 'v1.4' }
339
343
  # spec.source_files = 'JSONKit.*'
340
344
  # end
345
+ # ```
341
346
  #
342
347
  #
343
348
  # For more info on the definition of a Pod::Specification see:
@@ -455,10 +460,6 @@ module Pod
455
460
  end
456
461
 
457
462
  def validate!
458
- #lines = []
459
- #lines << "* the `platform` attribute should be either `:osx` or `:ios`" unless @platform && [:osx, :ios].include?(@platform.name)
460
- #lines << "* no dependencies were specified, which is, well, kinda pointless" if dependencies.empty?
461
- #raise(Informative, (["The Podfile at `#{@defined_in_file}' is invalid:"] + lines).join("\n")) unless lines.empty?
462
463
  end
463
464
  end
464
465
  end
@@ -42,6 +42,16 @@ module Pod
42
42
  @header_search_paths.uniq.map { |path| "${PODS_ROOT}/#{path}" }
43
43
  end
44
44
 
45
+ # Adds an header search path to the sandbox.
46
+ #
47
+ # @param path [Pathname] The path tho add.
48
+ #
49
+ # @return [void]
50
+ #
51
+ def add_header_search_path(path)
52
+ @header_search_paths << Pathname.new(HEADERS_DIR) + path
53
+ end
54
+
45
55
  def prepare_for_install
46
56
  headers_root.rmtree if headers_root.exist?
47
57
  end
@@ -4,7 +4,10 @@ module Pod
4
4
  extend Config::Mixin
5
5
 
6
6
  def self._eval_podspec(path)
7
- eval(path.read, nil, path.to_s)
7
+ string = File.open(path, 'r:utf-8') { |f| f.read }
8
+ # TODO: work around for Rubinius incomplete encoding in 1.9 mode
9
+ string.encode!('UTF-8') if string.respond_to?(:encoding) && string.encoding.name != "UTF-8"
10
+ eval(string, nil, path.to_s)
8
11
  end
9
12
 
10
13
  class Specification
@@ -35,10 +38,18 @@ module Pod
35
38
  end
36
39
 
37
40
  # multi-platform attributes
38
- %w[ source_files resources preserve_paths exclude_header_search_paths frameworks libraries dependencies compiler_flags].each do |attr|
41
+ %w[ source_files
42
+ resources
43
+ preserve_paths
44
+ exclude_header_search_paths
45
+ frameworks
46
+ libraries
47
+ dependencies
48
+ compiler_flags ].each do |attr|
39
49
  instance_variable_set( "@#{attr}", { :ios => [], :osx => [] } )
40
50
  end
41
51
  @xcconfig = { :ios => Xcodeproj::Config.new, :osx => Xcodeproj::Config.new }
52
+ @header_dir = { :ios => nil, :osx => nil }
42
53
 
43
54
  yield self if block_given?
44
55
  end
@@ -58,7 +69,7 @@ module Pod
58
69
  # be passed to initalize the value
59
70
  def self.top_attr_writer(attr, init_lambda = nil)
60
71
  define_method("#{attr}=") do |value|
61
- raise Informative, "Can't set `#{attr}' for subspecs." if @parent
72
+ raise Informative, "#{self.inspect} Can't set `#{attr}' for subspecs." if @parent
62
73
  instance_variable_set("@#{attr}", init_lambda ? init_lambda.call(value) : value);
63
74
  end
64
75
  end
@@ -119,6 +130,7 @@ module Pod
119
130
  libraries=
120
131
  compiler_flags=
121
132
  deployment_target=
133
+ header_dir=
122
134
  dependency }.each do |method|
123
135
  define_method(method) do |args|
124
136
  @specification._on_platform(@platform) do
@@ -180,16 +192,10 @@ module Pod
180
192
  top_attr_accessor :license, lambda { |l| ( l.kind_of? String ) ? { :type => l } : l }
181
193
  top_attr_accessor :version, lambda { |v| Version.new(v) }
182
194
  top_attr_accessor :authors, lambda { |a| parse_authors(a) }
183
- top_attr_accessor :header_mappings_dir, lambda { |file| Pathname.new(file) } # If not provided the headers files are flattened
184
- top_attr_accessor :prefix_header_file, lambda { |file| Pathname.new(file) }
185
- top_attr_accessor :prefix_header_contents
186
195
 
187
196
  top_attr_reader :description, lambda {|instance, ivar| ivar || instance.summary }
188
197
  top_attr_writer :description
189
198
 
190
- top_attr_reader :header_dir, lambda {|instance, ivar| ivar || instance.pod_destroot_name }
191
- top_attr_writer :header_dir, lambda {|dir| Pathname.new(dir) }
192
-
193
199
  alias_method :author=, :authors=
194
200
 
195
201
  def self.parse_authors(*names_and_email_addresses)
@@ -203,6 +209,13 @@ module Pod
203
209
 
204
210
  ### Attributes **with** multiple platform support
205
211
 
212
+ # @todo allow for subspecs
213
+ #
214
+ top_attr_accessor :header_mappings_dir, lambda { |file| Pathname.new(file) } # If not provided the headers files are flattened
215
+ top_attr_accessor :prefix_header_file, lambda { |file| Pathname.new(file) }
216
+ top_attr_accessor :prefix_header_contents
217
+
218
+
206
219
  pltf_chained_attr_accessor :source_files, lambda {|value, current| pattern_list(value) }
207
220
  pltf_chained_attr_accessor :resources, lambda {|value, current| pattern_list(value) }
208
221
  pltf_chained_attr_accessor :preserve_paths, lambda {|value, current| pattern_list(value) } # Paths that should not be cleaned
@@ -215,7 +228,28 @@ module Pod
215
228
  alias_method :framework=, :frameworks=
216
229
  alias_method :library=, :libraries=
217
230
 
218
- platform_attr_writer :xcconfig, lambda {|value, current| current.tap { |c| c.merge!(value) } }
231
+ # @!method header_dir=
232
+ #
233
+ # @abstract The directory where to name space the headers files of
234
+ # the specification.
235
+ #
236
+ # @param [String] The headers directory.
237
+ #
238
+ platform_attr_writer :header_dir, lambda { |dir, _| Pathname.new(dir) }
239
+
240
+ # @abstract (see #header_dir=)
241
+ #
242
+ # @return [Pathname] The headers directory.
243
+ #
244
+ # @note If no value is provided it returns an empty {Pathname}.
245
+ #
246
+ def header_dir
247
+ @header_dir[active_platform] || (@parent.header_dir if @parent) || Pathname.new('')
248
+ end
249
+
250
+ # @!method xcconfig=
251
+ #
252
+ platform_attr_writer :xcconfig, lambda {|value, current| current.tap { |c| c.merge!(value) } }
219
253
 
220
254
  def xcconfig
221
255
  raw_xconfig.dup.
@@ -338,12 +372,6 @@ module Pod
338
372
  end
339
373
  end
340
374
 
341
- def pod_destroot_name
342
- if root = pod_destroot
343
- root.basename
344
- end
345
- end
346
-
347
375
  def self.pattern_list(patterns)
348
376
  if patterns.is_a?(Array) && (!defined?(Rake) || !patterns.is_a?(Rake::FileList))
349
377
  patterns
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocoapods
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0.rc2
4
+ version: 0.6.0.rc3
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-06 00:00:00.000000000 Z
12
+ date: 2012-06-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
@@ -34,7 +34,7 @@ dependencies:
34
34
  requirements:
35
35
  - - ~>
36
36
  - !ruby/object:Gem::Version
37
- version: 1.3.0
37
+ version: 1.7.0
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,7 +42,7 @@ dependencies:
42
42
  requirements:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
- version: 1.3.0
45
+ version: 1.7.0
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: colored
48
48
  requirement: !ruby/object:Gem::Requirement
@@ -130,7 +130,7 @@ dependencies:
130
130
  requirements:
131
131
  - - ~>
132
132
  - !ruby/object:Gem::Version
133
- version: 0.2.0.rc1
133
+ version: 0.2.0.rc3
134
134
  type: :runtime
135
135
  prerelease: false
136
136
  version_requirements: !ruby/object:Gem::Requirement
@@ -138,7 +138,7 @@ dependencies:
138
138
  requirements:
139
139
  - - ~>
140
140
  - !ruby/object:Gem::Version
141
- version: 0.2.0.rc1
141
+ version: 0.2.0.rc3
142
142
  - !ruby/object:Gem::Dependency
143
143
  name: bacon
144
144
  requirement: !ruby/object:Gem::Requirement
@@ -220,8 +220,7 @@ files:
220
220
  homepage: https://github.com/CocoaPods/CocoaPods
221
221
  licenses:
222
222
  - MIT
223
- post_install_message: ! '[!] If this is your first time install of CocoaPods, or if
224
- you are upgrading, first run: $ pod setup'
223
+ post_install_message:
225
224
  rdoc_options: []
226
225
  require_paths:
227
226
  - lib
@@ -233,7 +232,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
233
232
  version: '0'
234
233
  segments:
235
234
  - 0
236
- hash: -4185987676698712042
235
+ hash: -4255808977828615188
237
236
  required_rubygems_version: !ruby/object:Gem::Requirement
238
237
  none: false
239
238
  requirements:
@@ -247,3 +246,4 @@ signing_key:
247
246
  specification_version: 3
248
247
  summary: An Objective-C library package manager.
249
248
  test_files: []
249
+ has_rdoc: