cocoapods 0.3.6 → 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  module Pod
2
- VERSION = '0.3.6'
2
+ VERSION = '0.3.7'
3
3
 
4
4
  class Informative < StandardError
5
5
  end
@@ -19,11 +19,13 @@ module Pod
19
19
 
20
20
  def self.options
21
21
  " --no-clean Leave SCM dirs like `.git' and `.svn' in tact after downloading\n" +
22
+ " --no-update Skip running `pod repo update` before install\n" +
22
23
  super
23
24
  end
24
25
 
25
26
  def initialize(argv)
26
27
  config.clean = !argv.option('--no-clean')
28
+ @update_repo = !argv.option('--no-update')
27
29
  @projpath = argv.shift_argument
28
30
  super unless argv.empty?
29
31
  end
@@ -35,6 +37,9 @@ module Pod
35
37
  if @projpath && !File.exist?(@projpath)
36
38
  raise Informative, "The specified project `#{@projpath}' does not exist."
37
39
  end
40
+ if @update_repo
41
+ Repo.new(ARGV.new(["update"])).run
42
+ end
38
43
  installer = Installer.new(podfile)
39
44
  installer.install!
40
45
  installer.configure_project(@projpath) if @projpath
@@ -36,6 +36,26 @@ module Pod
36
36
  (@specification ? @specification == other.specification : @external_spec_source == other.external_spec_source)
37
37
  end
38
38
 
39
+ def subspec_dependency?
40
+ @name.include?('/')
41
+ end
42
+
43
+ # In case this is a dependency for a subspec, e.g. 'RestKit/Networking',
44
+ # this returns 'RestKit', which is what the Pod::Source needs to know to
45
+ # retrieve the correct Set from disk.
46
+ def top_level_spec_name
47
+ subspec_dependency? ? @name.split('/').first : @name
48
+ end
49
+
50
+ # Returns a copy of the dependency, but with the name of the top level
51
+ # spec. This is used by Pod::Specification::Set to merge dependencies on
52
+ # the complete set, irrespective of what spec in the set wil be used.
53
+ def to_top_level_spec_dependency
54
+ dep = dup
55
+ dep.name = top_level_spec_name
56
+ dep
57
+ end
58
+
39
59
  def to_s
40
60
  version = ''
41
61
  if source = @external_spec_source
@@ -1,16 +1,18 @@
1
1
  module Pod
2
2
  class Installer
3
3
  module Shared
4
- def dependent_specification_sets
5
- @dependent_specification_sets ||= Resolver.new(@podfile, @definition ? @definition.dependencies : nil).resolve
4
+ def dependent_specifications
5
+ @dependent_specifications ||= Resolver.new(@podfile, @definition ? @definition.dependencies : nil).resolve
6
6
  end
7
7
 
8
8
  def build_specifications
9
- dependent_specification_sets.reject(&:only_part_of_other_pod?).map(&:specification)
9
+ dependent_specifications.reject do |spec|
10
+ spec.wrapper? || spec.defined_in_set.only_part_of_other_pod?
11
+ end
10
12
  end
11
13
 
12
14
  def download_only_specifications
13
- dependent_specification_sets.select(&:only_part_of_other_pod?).map(&:specification)
15
+ dependent_specifications - build_specifications
14
16
  end
15
17
  end
16
18
 
@@ -222,8 +222,8 @@ module Pod
222
222
  @target_definitions.values.map(&:target_dependencies).flatten
223
223
  end
224
224
 
225
- def dependency_by_name(name)
226
- dependencies.find { |d| d.name == name }
225
+ def dependency_by_top_level_spec_name(name)
226
+ dependencies.find { |d| d.top_level_spec_name == name }
227
227
  end
228
228
 
229
229
  def generate_bridge_support?
@@ -5,19 +5,31 @@ module Pod
5
5
  end
6
6
 
7
7
  def resolve
8
- @sets = []
8
+ @sets, @loaded_spec_names, @specs = [], [], []
9
9
  find_dependency_sets(@specification, @dependencies)
10
- @sets
10
+ @specs
11
11
  end
12
12
 
13
13
  def find_dependency_sets(specification, dependencies = nil)
14
14
  (dependencies || specification.dependencies).each do |dependency|
15
15
  set = find_dependency_set(dependency)
16
16
  set.required_by(specification)
17
- unless @sets.include?(set)
18
- validate_platform!(set)
19
- @sets << set
20
- find_dependency_sets(set.specification)
17
+ unless @loaded_spec_names.include?(dependency.name)
18
+ # Get a reference to the spec that’s actually being loaded.
19
+ # If it’s a subspec dependency, e.g. 'RestKit/Network', then
20
+ # find that subspec.
21
+ spec = set.specification
22
+ if dependency.subspec_dependency?
23
+ spec = spec.subspec_by_name(dependency.name)
24
+ end
25
+ validate_platform!(spec)
26
+
27
+ # Ensure we don't resolve the same spec twice
28
+ @loaded_spec_names << spec.name
29
+ @specs << spec
30
+ @sets << set unless @sets.include?(set)
31
+
32
+ find_dependency_sets(spec)
21
33
  end
22
34
  end
23
35
  end
@@ -30,8 +42,7 @@ module Pod
30
42
  end
31
43
  end
32
44
 
33
- def validate_platform!(set)
34
- spec = set.specification
45
+ def validate_platform!(spec)
35
46
  unless spec.platform.nil? || spec.platform == @specification.platform
36
47
  raise Informative, "The platform required by the Podfile (:#{@specification.platform}) " \
37
48
  "does not match that of #{spec} (:#{spec.platform})"
@@ -13,8 +13,7 @@ module Pod
13
13
 
14
14
  def self.search(dependency)
15
15
  all.map { |s| s.search(dependency) }.compact.first ||
16
- raise(Informative, "Unable to find a pod named `#{dependency.name}'.\n" \
17
- "You might want to run `pod repo update` and try again.")
16
+ raise(Informative, "Unable to find a pod named `#{dependency.name}'")
18
17
  end
19
18
 
20
19
  def self.search_by_name(query, full_text_search)
@@ -42,7 +41,13 @@ module Pod
42
41
  end
43
42
 
44
43
  def search(dependency)
45
- pod_sets.find { |set| set.name == dependency.name }
44
+ pod_sets.find do |set|
45
+ # First match the (top level) name, which does not yet load the spec from disk
46
+ set.name == dependency.top_level_spec_name &&
47
+ # Now either check if it's a dependency on the top level spec, or if it's not
48
+ # check if the requested subspec exists in the top level spec.
49
+ (!dependency.subspec_dependency? || !set.specification.subspec_by_name(dependency.name).nil?)
50
+ end
46
51
  end
47
52
 
48
53
  def search_by_name(query, full_text_search)
@@ -21,11 +21,16 @@ module Pod
21
21
  attr_accessor :defined_in_file
22
22
 
23
23
  def initialize
24
- @dependencies, @resources, @clean_paths = [], [], []
25
- @xcconfig = Xcodeproj::Config.new
24
+ post_initialize
26
25
  yield self if block_given?
27
26
  end
28
27
 
28
+ # TODO This is just to work around a MacRuby bug
29
+ def post_initialize
30
+ @dependencies, @source_files, @resources, @clean_paths, @subspecs = [], [], [], [], []
31
+ @xcconfig = Xcodeproj::Config.new
32
+ end
33
+
29
34
  # Attributes
30
35
 
31
36
  attr_accessor :name
@@ -53,10 +58,13 @@ module Pod
53
58
 
54
59
  def summary=(summary)
55
60
  @summary = summary
56
- @description ||= summary
57
61
  end
58
62
  attr_reader :summary
59
63
 
64
+ def description
65
+ @description || summary
66
+ end
67
+
60
68
  def part_of=(*name_and_version_requirements)
61
69
  self.part_of_dependency = *name_and_version_requirements
62
70
  @part_of.only_part_of_other_pod = true
@@ -111,19 +119,14 @@ module Pod
111
119
  attr_writer :compiler_flags
112
120
  def compiler_flags
113
121
  flags = "#{@compiler_flags} "
114
- flags << '-fobjc-arc' if @requires_arc
122
+ flags << '-fobjc-arc' if requires_arc
115
123
  flags
116
124
  end
117
125
 
118
- # These are attributes which are also on a Podfile
119
-
120
126
  attr_accessor :platform
121
127
 
122
128
  attr_accessor :requires_arc
123
129
 
124
- attr_accessor :generate_bridge_support
125
- alias_method :generate_bridge_support?, :generate_bridge_support
126
-
127
130
  def dependency(*name_and_version_requirements)
128
131
  name, *version_requirements = name_and_version_requirements.flatten
129
132
  dep = Dependency.new(name, *version_requirements)
@@ -132,18 +135,46 @@ module Pod
132
135
  end
133
136
  attr_reader :dependencies
134
137
 
138
+ def subspec(name, &block)
139
+ subspec = Subspec.new(self, name, &block)
140
+ @subspecs << subspec
141
+ subspec
142
+ end
143
+ attr_reader :subspecs
144
+
135
145
  # Not attributes
136
146
 
147
+ # TODO when we move to use a 'ResolveContext' this should happen there.
148
+ attr_accessor :defined_in_set
149
+
137
150
  include Config::Mixin
138
151
 
152
+ def wrapper?
153
+ source_files.empty? && !subspecs.empty?
154
+ end
155
+
156
+ def subspec_by_name(name)
157
+ # Remove this spec's name from the beginning of the name we’re looking for
158
+ # and take the first component from the remainder, which is the spec we need
159
+ # to find now.
160
+ remainder = name[self.name.size+1..-1].split('/')
161
+ subspec_name = remainder.shift
162
+ subspec = subspecs.find { |s| s.name == "#{self.name}/#{subspec_name}" }
163
+ # If this was the last component in the name, then return the subspec,
164
+ # otherwise we recursively keep calling subspec_by_name until we reach the
165
+ # last one and return that
166
+ remainder.empty? ? subspec : subspec.subspec_by_name(name)
167
+ end
168
+
139
169
  def ==(other)
140
- self.class === other &&
141
- name && name == other.name &&
142
- version && version == other.version
170
+ object_id == other.object_id ||
171
+ (self.class === other &&
172
+ name && name == other.name &&
173
+ version && version == other.version)
143
174
  end
144
175
 
145
- def dependency_by_name(name)
146
- @dependencies.find { |d| d.name == name }
176
+ def dependency_by_top_level_spec_name(name)
177
+ @dependencies.find { |d| d.top_level_spec_name == name }
147
178
  end
148
179
 
149
180
  def part_of_specification_set
@@ -284,7 +315,9 @@ module Pod
284
315
  missing << "`homepage'" unless homepage
285
316
  missing << "`author(s)'" unless authors
286
317
  missing << "either `source' or `part_of'" unless source || part_of
287
- missing << "`source_files'" unless source_files
318
+ missing << "`source_files'" if source_files.empty? && subspecs.empty?
319
+ # TODO
320
+ # * validate subspecs
288
321
 
289
322
  incorrect = []
290
323
  allowed = [nil, :ios, :osx]
@@ -363,6 +396,52 @@ module Pod
363
396
  def post_install(target)
364
397
  end
365
398
 
399
+ class Subspec < Specification
400
+ attr_reader :parent
401
+
402
+ def initialize(parent, name)
403
+ @parent, @name = parent, name
404
+ # TODO a MacRuby bug, the correct super impl `initialize' is not called consistently
405
+ #super(&block)
406
+ post_initialize
407
+
408
+ # A subspec is _always_ part of the source of its top level spec.
409
+ self.part_of = top_level_parent.name, version
410
+ # A subspec has a dependency on the parent if the parent is a subspec too.
411
+ dependency(@parent.name, version) if @parent.is_a?(Subspec)
412
+
413
+ yield self if block_given?
414
+ end
415
+
416
+ undef_method :name=, :version=, :source=, :defined_in_set=
417
+
418
+ def top_level_parent
419
+ top_level_parent = @parent
420
+ top_level_parent = top_level_parent.parent while top_level_parent.is_a?(Subspec)
421
+ top_level_parent
422
+ end
423
+
424
+ def name
425
+ "#{@parent.name}/#{@name}"
426
+ end
427
+
428
+ # TODO manually forwarding the attributes that we have so far needed to forward,
429
+ # but need to think if there's a better way to do this.
430
+
431
+ def summary
432
+ @summary ? @summary : top_level_parent.summary
433
+ end
434
+
435
+ # Override the getters to always return the value of the top level parent spec.
436
+ [:version, :summary, :platform, :license, :authors, :requires_arc, :compiler_flags, :defined_in_set].each do |attr|
437
+ define_method(attr) { top_level_parent.send(attr) }
438
+ end
439
+
440
+ def copy_header_mapping(from)
441
+ top_level_parent.copy_header_mapping(from)
442
+ end
443
+ end
444
+
366
445
  end
367
446
 
368
447
  Spec = Specification
@@ -25,7 +25,7 @@ module Pod
25
25
  end
26
26
 
27
27
  def required_by(specification)
28
- dependency = specification.dependency_by_name(name)
28
+ dependency = specification.dependency_by_top_level_spec_name(name)
29
29
  unless @required_by.empty? || dependency.requirement.satisfied_by?(required_version)
30
30
  # TODO add graph that shows which dependencies led to this.
31
31
  raise Informative, "#{specification} tries to activate `#{dependency}', " \
@@ -38,12 +38,12 @@ module Pod
38
38
 
39
39
  def dependency
40
40
  @required_by.inject(Dependency.new(name)) do |previous, spec|
41
- previous.merge(spec.dependency_by_name(name))
41
+ previous.merge(spec.dependency_by_top_level_spec_name(name).to_top_level_spec_dependency)
42
42
  end
43
43
  end
44
44
 
45
45
  def only_part_of_other_pod?
46
- @required_by.all? { |spec| spec.dependency_by_name(name).only_part_of_other_pod? }
46
+ @required_by.all? { |spec| spec.dependency_by_top_level_spec_name(name).only_part_of_other_pod? }
47
47
  end
48
48
 
49
49
  def name
@@ -55,7 +55,7 @@ module Pod
55
55
  end
56
56
 
57
57
  def specification
58
- @specification ||= Specification.from_file(specification_path)
58
+ @specification ||= Specification.from_file(specification_path).tap { |spec| spec.defined_in_set = self }
59
59
  end
60
60
 
61
61
  # Return the first version that matches the current dependency.
@@ -85,6 +85,7 @@ module Pod
85
85
  class External < Set
86
86
  def initialize(specification)
87
87
  @specification = specification
88
+ @specification.defined_in_set = self
88
89
  @required_by = []
89
90
  end
90
91
 
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 6
9
- version: 0.3.6
8
+ - 7
9
+ version: 0.3.7
10
10
  platform: ruby
11
11
  authors:
12
12
  - Eloy Duran