cocoapods 0.3.6 → 0.3.7
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.
- data/lib/cocoapods.rb +1 -1
- data/lib/cocoapods/command/install.rb +5 -0
- data/lib/cocoapods/dependency.rb +20 -0
- data/lib/cocoapods/installer.rb +6 -4
- data/lib/cocoapods/podfile.rb +2 -2
- data/lib/cocoapods/resolver.rb +19 -8
- data/lib/cocoapods/source.rb +8 -3
- data/lib/cocoapods/specification.rb +94 -15
- data/lib/cocoapods/specification/set.rb +5 -4
- metadata +2 -2
data/lib/cocoapods.rb
CHANGED
@@ -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
|
data/lib/cocoapods/dependency.rb
CHANGED
@@ -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
|
data/lib/cocoapods/installer.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
module Pod
|
2
2
|
class Installer
|
3
3
|
module Shared
|
4
|
-
def
|
5
|
-
@
|
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
|
-
|
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
|
-
|
15
|
+
dependent_specifications - build_specifications
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
data/lib/cocoapods/podfile.rb
CHANGED
@@ -222,8 +222,8 @@ module Pod
|
|
222
222
|
@target_definitions.values.map(&:target_dependencies).flatten
|
223
223
|
end
|
224
224
|
|
225
|
-
def
|
226
|
-
dependencies.find { |d| d.
|
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?
|
data/lib/cocoapods/resolver.rb
CHANGED
@@ -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
|
-
@
|
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 @
|
18
|
-
|
19
|
-
|
20
|
-
|
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!(
|
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})"
|
data/lib/cocoapods/source.rb
CHANGED
@@ -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}'
|
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
|
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
|
-
|
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
|
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
|
-
|
141
|
-
|
142
|
-
|
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
|
146
|
-
@dependencies.find { |d| d.
|
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'"
|
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.
|
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.
|
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.
|
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
|
|