cocoapods-core 0.30.0 → 1.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +7 -10
  3. data/lib/cocoapods-core/build_type.rb +121 -0
  4. data/lib/cocoapods-core/cdn_source.rb +501 -0
  5. data/lib/cocoapods-core/core_ui.rb +4 -3
  6. data/lib/cocoapods-core/dependency.rb +100 -73
  7. data/lib/cocoapods-core/gem_version.rb +1 -2
  8. data/lib/cocoapods-core/github.rb +32 -5
  9. data/lib/cocoapods-core/http.rb +86 -0
  10. data/lib/cocoapods-core/lockfile.rb +161 -56
  11. data/lib/cocoapods-core/metrics.rb +47 -0
  12. data/lib/cocoapods-core/platform.rb +99 -11
  13. data/lib/cocoapods-core/podfile/dsl.rb +623 -124
  14. data/lib/cocoapods-core/podfile/target_definition.rb +662 -109
  15. data/lib/cocoapods-core/podfile.rb +138 -65
  16. data/lib/cocoapods-core/requirement.rb +37 -8
  17. data/lib/cocoapods-core/source/acceptor.rb +16 -13
  18. data/lib/cocoapods-core/source/aggregate.rb +79 -103
  19. data/lib/cocoapods-core/source/health_reporter.rb +9 -18
  20. data/lib/cocoapods-core/source/manager.rb +488 -0
  21. data/lib/cocoapods-core/source/metadata.rb +79 -0
  22. data/lib/cocoapods-core/source.rb +241 -70
  23. data/lib/cocoapods-core/specification/consumer.rb +187 -47
  24. data/lib/cocoapods-core/specification/dsl/attribute.rb +49 -85
  25. data/lib/cocoapods-core/specification/dsl/attribute_support.rb +6 -8
  26. data/lib/cocoapods-core/specification/dsl/deprecations.rb +9 -126
  27. data/lib/cocoapods-core/specification/dsl/platform_proxy.rb +30 -20
  28. data/lib/cocoapods-core/specification/dsl.rb +943 -296
  29. data/lib/cocoapods-core/specification/json.rb +64 -23
  30. data/lib/cocoapods-core/specification/linter/analyzer.rb +218 -0
  31. data/lib/cocoapods-core/specification/linter/result.rb +128 -0
  32. data/lib/cocoapods-core/specification/linter.rb +310 -309
  33. data/lib/cocoapods-core/specification/root_attribute_accessors.rb +90 -39
  34. data/lib/cocoapods-core/specification/set/presenter.rb +35 -71
  35. data/lib/cocoapods-core/specification/set.rb +42 -96
  36. data/lib/cocoapods-core/specification.rb +368 -130
  37. data/lib/cocoapods-core/standard_error.rb +45 -24
  38. data/lib/cocoapods-core/trunk_source.rb +14 -0
  39. data/lib/cocoapods-core/vendor/requirement.rb +133 -53
  40. data/lib/cocoapods-core/vendor/version.rb +197 -156
  41. data/lib/cocoapods-core/vendor.rb +1 -5
  42. data/lib/cocoapods-core/version.rb +137 -42
  43. data/lib/cocoapods-core/yaml_helper.rb +334 -0
  44. data/lib/cocoapods-core.rb +10 -4
  45. metadata +100 -27
  46. data/lib/cocoapods-core/source/abstract_data_provider.rb +0 -71
  47. data/lib/cocoapods-core/source/file_system_data_provider.rb +0 -150
  48. data/lib/cocoapods-core/source/github_data_provider.rb +0 -143
  49. data/lib/cocoapods-core/specification/set/statistics.rb +0 -266
  50. data/lib/cocoapods-core/yaml_converter.rb +0 -192
@@ -1,17 +1,15 @@
1
1
  module Pod
2
2
  class Specification
3
3
  module DSL
4
-
5
4
  # Provides the accessors methods for the root attributes. Root attributes
6
5
  # do not support multi-platform values and inheritance.
7
6
  #
8
7
  module RootAttributesAccessors
9
-
10
8
  # @return [String] The name of the specification *not* including the
11
9
  # names of the parents, in case of ‘sub-specifications’.
12
10
  #
13
11
  def base_name
14
- attributes_hash["name"]
12
+ attributes_hash['name']
15
13
  end
16
14
 
17
15
  # @return [String] The name of the specification including the names of
@@ -21,21 +19,49 @@ module Pod
21
19
  parent ? "#{parent.name}/#{base_name}" : base_name
22
20
  end
23
21
 
24
- # @return [Version] The version of the Pod.
22
+ # @return [Bool, String, Array<String>] The requires_arc value.
25
23
  #
26
- # @todo The version is memoized because the Resolvers sets the head
27
- # state on it. This information should be stored in the
28
- # specification instance and the lockfile should have a more
29
- # robust handling of head versions (like a dedicated section).
24
+ def requires_arc
25
+ attributes_hash['requires_arc']
26
+ end
27
+
28
+ # @return [Version] The version of the Pod.
30
29
  #
31
30
  def version
32
31
  if root?
33
- @version ||= Version.new(attributes_hash["version"])
32
+ @version ||= Version.new(attributes_hash['version'])
34
33
  else
35
34
  @version ||= root.version
36
35
  end
37
36
  end
38
37
 
38
+ # @deprecated in favor of #swift_versions
39
+ #
40
+ # @return [Version] The Swift version specified by the specification.
41
+ #
42
+ def swift_version
43
+ swift_versions.last
44
+ end
45
+
46
+ # @return [Array<Version>] The Swift versions supported by the specification.
47
+ #
48
+ def swift_versions
49
+ @swift_versions ||= begin
50
+ swift_versions = Array(attributes_hash['swift_versions']).dup
51
+ # Pre 1.7.0, the DSL was singularized as it supported only a single version of Swift. In 1.7.0 the DSL
52
+ # is now pluralized always and a specification can support multiple versions of Swift. This ensures
53
+ # we parse the old JSON serialized format and include it as part of the Swift versions supported.
54
+ swift_versions << attributes_hash['swift_version'] unless attributes_hash['swift_version'].nil?
55
+ swift_versions.map { |swift_version| Version.new(swift_version) }.uniq.sort
56
+ end
57
+ end
58
+
59
+ # @return [Requirement] The CocoaPods version required to use the specification.
60
+ #
61
+ def cocoapods_version
62
+ @cocoapods_version ||= Requirement.create(attributes_hash['cocoapods_version'])
63
+ end
64
+
39
65
  # @return [Hash] a hash containing the authors as the keys and their
40
66
  # email address as the values.
41
67
  #
@@ -49,7 +75,7 @@ module Pod
49
75
  # 'Author'
50
76
  #
51
77
  def authors
52
- authors = attributes_hash["authors"]
78
+ authors = attributes_hash['authors']
53
79
  if authors.is_a?(Hash)
54
80
  authors
55
81
  elsif authors.is_a?(Array)
@@ -70,13 +96,19 @@ module Pod
70
96
  # @return [String] The social media URL.
71
97
  #
72
98
  def social_media_url
73
- attributes_hash["social_media_url"]
99
+ attributes_hash['social_media_url']
74
100
  end
75
101
 
76
- # @return [String] The docset URL.
102
+ # @return [String] The readme.
77
103
  #
78
- def docset_url
79
- attributes_hash["docset_url"]
104
+ def readme
105
+ attributes_hash['readme']
106
+ end
107
+
108
+ # @return [String] The changelog.
109
+ #
110
+ def changelog
111
+ attributes_hash['changelog']
80
112
  end
81
113
 
82
114
  # @return [Hash] A hash containing the license information of the Pod.
@@ -84,11 +116,11 @@ module Pod
84
116
  # @note The indentation is stripped from the license text.
85
117
  #
86
118
  def license
87
- license = attributes_hash["license"]
119
+ license = attributes_hash['license']
88
120
  if license.is_a?(String)
89
121
  { :type => license }
90
122
  elsif license.is_a?(Hash)
91
- license = convert_keys_to_symbol(license)
123
+ license = Specification.convert_keys_to_symbol(license)
92
124
  license[:text] = license[:text].strip_heredoc if license[:text]
93
125
  license
94
126
  else
@@ -99,20 +131,26 @@ module Pod
99
131
  # @return [String] The URL of the homepage of the Pod.
100
132
  #
101
133
  def homepage
102
- attributes_hash["homepage"]
134
+ attributes_hash['homepage']
103
135
  end
104
136
 
105
137
  # @return [Hash{Symbol=>String}] The location from where the library
106
138
  # should be retrieved.
107
139
  #
108
140
  def source
109
- convert_keys_to_symbol(attributes_hash["source"])
141
+ value = attributes_hash['source']
142
+ if value && value.is_a?(Hash)
143
+ Specification.convert_keys_to_symbol(value)
144
+ else
145
+ value
146
+ end
110
147
  end
111
148
 
112
149
  # @return [String] A short description of the Pod.
113
150
  #
114
151
  def summary
115
- attributes_hash["summary"]
152
+ summary = attributes_hash['summary']
153
+ summary.strip_heredoc.chomp if summary
116
154
  end
117
155
 
118
156
  # @return [String] A longer description of the Pod.
@@ -120,8 +158,8 @@ module Pod
120
158
  # @note The indentation is stripped from the description.
121
159
  #
122
160
  def description
123
- description = attributes_hash["description"]
124
- description.strip_heredoc if description
161
+ description = attributes_hash['description']
162
+ description.strip_heredoc.chomp if description
125
163
  end
126
164
 
127
165
  # @return [Array<String>] The list of the URL for the screenshots of
@@ -130,45 +168,58 @@ module Pod
130
168
  # @note The value is coerced to an array.
131
169
  #
132
170
  def screenshots
133
- value = attributes_hash["screenshots"]
171
+ value = attributes_hash['screenshots']
134
172
  [*value]
135
173
  end
136
174
 
137
175
  # @return [String, Nil] The documentation URL of the Pod if specified.
138
176
  #
139
177
  def documentation_url
140
- attributes_hash["documentation_url"]
178
+ attributes_hash['documentation_url']
141
179
  end
142
180
 
143
181
  # @return [String, Nil] The prepare command of the Pod if specified.
144
182
  #
145
183
  def prepare_command
146
- attributes_hash["prepare_command"]
184
+ command = attributes_hash['prepare_command']
185
+ command.strip_heredoc.chomp if command
147
186
  end
148
187
 
149
- #---------------------------------------------------------------------#
188
+ # @return [Boolean] Indicates, that if use_frameworks! is specified, the
189
+ # framework should include a static library.
190
+ #
191
+ def static_framework
192
+ attributes_hash['static_framework']
193
+ end
150
194
 
151
- private
195
+ # @return [Boolean] Whether the Pod has been deprecated.
196
+ #
197
+ def deprecated
198
+ attributes_hash['deprecated']
199
+ end
152
200
 
153
- # Converts the keys of the given hash to a string.
201
+ # @return [String] The name of the Pod that this one has been
202
+ # deprecated in favor of.
154
203
  #
155
- # @param [Object] value
156
- # the value that needs to be stripped from the Symbols.
204
+ def deprecated_in_favor_of
205
+ attributes_hash['deprecated_in_favor_of']
206
+ end
207
+
208
+ # @return [Boolean] Wether the pod is deprecated either in favor of some other
209
+ # pod or simply deprecated.
157
210
  #
158
- # @return [Hash] the hash with the strings instead of the keys.
211
+ def deprecated?
212
+ deprecated || !deprecated_in_favor_of.nil?
213
+ end
214
+
215
+ # @return [String, Nil] The custom module map file of the Pod,
216
+ # if specified.
159
217
  #
160
- def convert_keys_to_symbol(value)
161
- return unless value
162
- result = {}
163
- value.each do |key, subvalue|
164
- subvalue = convert_keys_to_symbol(subvalue) if subvalue.is_a?(Hash)
165
- result[key.to_sym] = subvalue
166
- end
167
- result
218
+ def module_map
219
+ attributes_hash['module_map']
168
220
  end
169
221
 
170
222
  #---------------------------------------------------------------------#
171
-
172
223
  end
173
224
  end
174
225
  end
@@ -3,25 +3,18 @@ require 'active_support/core_ext/array/conversions'
3
3
  module Pod
4
4
  class Specification
5
5
  class Set
6
-
7
6
  # Provides support for presenting a Pod described by a {Set} in a
8
7
  # consistent way across clients of CocoaPods-Core.
9
8
  #
10
9
  class Presenter
11
-
12
10
  # @return [Set] the set that should be presented.
13
11
  #
14
12
  attr_reader :set
15
13
 
16
- # @return [Statistics] The statistics provider.
17
- #
18
- attr_reader :statistics_provider
19
-
20
14
  # @param [Set] set @see #set.
21
15
  #
22
- def initialize(set, statistics_provider = nil)
16
+ def initialize(set)
23
17
  @set = set
24
- @statistics_provider = statistics_provider || Statistics.instance
25
18
  end
26
19
 
27
20
  #---------------------------------------------------------------------#
@@ -44,7 +37,7 @@ module Pod
44
37
  # order.
45
38
  #
46
39
  def versions
47
- @set.versions.sort.reverse
40
+ @set.versions
48
41
  end
49
42
 
50
43
  # @return [String] all the versions available sorted from the highest
@@ -56,7 +49,7 @@ module Pod
56
49
  #
57
50
  # @note This method orders the sources by name.
58
51
  #
59
- def verions_by_source
52
+ def versions_by_source
60
53
  result = []
61
54
  versions_by_source = @set.versions_by_source
62
55
  @set.sources.sort.each do |source|
@@ -92,17 +85,9 @@ module Pod
92
85
  #
93
86
  # "Author 1, Author 2 and Author 3"
94
87
  #
95
- # @note In ruby 1.8.7 the authors are sorted by name because the
96
- # hash doesn't preserve the order in which they are defined
97
- # in the podspec.
98
- #
99
88
  def authors
100
89
  return '' unless spec.authors
101
- if RUBY_VERSION == '1.8.7'
102
- spec.authors.keys.sort.to_sentence
103
- else
104
- spec.authors.keys.to_sentence
105
- end
90
+ spec.authors.keys.to_sentence
106
91
  end
107
92
 
108
93
  # @return [String] the homepage of the pod.
@@ -125,6 +110,28 @@ module Pod
125
110
  spec.description || spec.summary
126
111
  end
127
112
 
113
+ # @return [String] A string that describes the deprecation of the pod.
114
+ # If the pod is deprecated in favor of another pod it will contain
115
+ # information about that. If the pod is not deprecated returns nil.
116
+ #
117
+ # @example Output example
118
+ #
119
+ # "[DEPRECATED]"
120
+ # "[DEPRECATED in favor of NewAwesomePod]"
121
+ #
122
+ def deprecation_description
123
+ if spec.deprecated?
124
+ description = '[DEPRECATED'
125
+ description += if spec.deprecated_in_favor_of.nil?
126
+ ']'
127
+ else
128
+ " in favor of #{spec.deprecated_in_favor_of}]"
129
+ end
130
+
131
+ description
132
+ end
133
+ end
134
+
128
135
  # @return [String] the URL of the source of the Pod.
129
136
  #
130
137
  def source_url
@@ -167,72 +174,29 @@ module Pod
167
174
 
168
175
  # @!group Statistics
169
176
 
170
- # @return [Time] the creation date of the first known `podspec` of the
171
- # Pod.
172
- #
173
- def creation_date
174
- statistics_provider.creation_date(@set)
175
- end
176
-
177
177
  # @return [Integer] the GitHub likes of the repo of the Pod.
178
178
  #
179
- def github_watchers
180
- statistics_provider.github_watchers(@set)
179
+ def github_stargazers
180
+ github_metrics['stargazers']
181
181
  end
182
182
 
183
183
  # @return [Integer] the GitHub forks of the repo of the Pod.
184
184
  #
185
185
  def github_forks
186
- statistics_provider.github_forks(@set)
187
- end
188
-
189
- # @return [String] the relative time of the last push of the repo the Pod.
190
- #
191
- def github_last_activity
192
- distance_from_now_in_words(statistics_provider.github_pushed_at(@set))
186
+ github_metrics['forks']
193
187
  end
194
188
 
195
189
  #---------------------------------------------------------------------#
196
190
 
197
- private
198
-
199
- # Computes a human readable string that represents a past date in
200
- # relative terms.
201
- #
202
- # @param [Time, String] from_time
203
- # the date that should be represented.
204
- #
205
- # @example Possible outputs
206
- #
207
- # "less than a week ago"
208
- # "15 days ago"
209
- # "3 month ago"
210
- # "more than a year ago"
211
- #
212
- # @return [String] a string that represents a past date.
213
- #
214
- def distance_from_now_in_words(from_time)
215
- return nil unless from_time
216
- from_time = Time.parse(from_time) unless from_time.is_a?(Time)
217
- to_time = Time.now
218
- distance_in_days = (((to_time - from_time).abs) / 60 / 60 / 24).round
191
+ # @!group Private Helpers
219
192
 
220
- case distance_in_days
221
- when 0..7
222
- "less than a week ago"
223
- when 8..29
224
- "#{distance_in_days} days ago"
225
- when 30..45
226
- "1 month ago"
227
- when 46..365
228
- "#{(distance_in_days.to_f / 30).round} months ago"
229
- else
230
- "more than a year ago"
231
- end
193
+ def metrics
194
+ @metrics ||= Metrics.pod(name) || {}
232
195
  end
233
196
 
234
- #---------------------------------------------------------------------#
235
-
197
+ def github_metrics
198
+ metrics['github'] || {}
199
+ end
236
200
  end
237
201
  end
238
202
  end
@@ -1,22 +1,19 @@
1
1
  require 'active_support/core_ext/array/conversions'
2
2
  require 'cocoapods-core/specification/set/presenter'
3
- require 'cocoapods-core/specification/set/statistics'
4
3
 
5
4
  module Pod
6
5
  class Specification
7
-
8
6
  # A Specification::Set is responsible of handling all the specifications of
9
7
  # a Pod. This class stores the information of the dependencies that required
10
8
  # a Pod in the resolution process.
11
9
  #
12
- # @note The alphabetical order of the sets is used to select a
10
+ # @note The order in which the sets are provided is used to select a
13
11
  # specification if multiple are available for a given version.
14
12
  #
15
13
  # @note The set class is not and should be not aware of the backing store
16
14
  # of a Source.
17
15
  #
18
16
  class Set
19
-
20
17
  # @return [String] the name of the Pod.
21
18
  #
22
19
  attr_reader :name
@@ -33,104 +30,49 @@ module Pod
33
30
  # the sources that contain a Pod.
34
31
  #
35
32
  def initialize(name, sources = [])
36
- @name = name
37
- sources = sources.is_a?(Array) ? sources : [sources]
38
- @sources = sources.sort_by(&:name)
39
- @dependencies_by_requirer_name = {}
40
- @dependencies = []
41
- end
42
-
43
- # Stores a dependency on the Pod.
44
- #
45
- # @param [Dependency] dependency
46
- # a dependency that requires the Pod.
47
- #
48
- # @param [String] dependent_name
49
- # the name of the owner of the dependency. It is used only to
50
- # display the Pod::Informative.
51
- #
52
- # @raise If the versions requirement of the dependency are not
53
- # compatible with the previously stored dependencies.
54
- #
55
- # @todo This should simply return a boolean. Is CocoaPods that should
56
- # raise.
57
- #
58
- # @return [void]
59
- #
60
- def required_by(dependency, dependent_name)
61
- dependencies_by_requirer_name[dependent_name] ||= []
62
- dependencies_by_requirer_name[dependent_name] << dependency
63
- dependencies << dependency
64
-
65
- if acceptable_versions.empty?
66
- message = "Unable to satisfy the following requirements:\n"
67
- dependencies_by_requirer_name.each do |name, dependencies|
68
- dependencies.each do |dep|
69
- message << "- `#{dep}` required by `#{name}`"
70
- end
71
- end
72
- raise Informative, message
73
- end
74
- end
75
-
76
- # @return [Dependency] A dependency that includes all the versions
77
- # requirements of the stored dependencies.
78
- #
79
- def dependency
80
- dependencies.reduce(Dependency.new(name)) do |previous, dependency|
81
- previous.merge(dependency.to_root_dependency)
82
- end
33
+ @name = name
34
+ @sources = Array(sources)
83
35
  end
84
36
 
85
37
  # @return [Specification] the top level specification of the Pod for the
86
38
  # {#required_version}.
87
39
  #
88
40
  # @note If multiple sources have a specification for the
89
- # {#required_version} The alphabetical order of their names is
90
- # used to disambiguate.
41
+ # {#required_version}, the order in which they are provided
42
+ # is used to disambiguate.
91
43
  #
92
44
  def specification
93
- path = specification_path_for_version(required_version)
94
- Specification.from_file(path)
95
- end
96
-
97
- # TODO
98
- #
99
- def specification_path_for_version(version)
100
- sources = []
101
- versions_by_source.each do |source, source_versions|
102
- sources << source if source_versions.include?(required_version)
45
+ unless highest_version_spec_path
46
+ raise Informative, "Could not find the highest version for `#{name}`. "\
47
+ "This could be due to an empty #{name} directory in a local repository."
103
48
  end
104
- source = sources.sort_by(&:name).first
105
- source.specification_path(name, required_version)
49
+
50
+ Specification.from_file(highest_version_spec_path)
106
51
  end
107
52
 
108
- # @return [Version] the highest version that satisfies the stored
109
- # dependencies.
110
- #
111
- # @todo This should simply return nil. CocoaPods should raise instead.
53
+ # @return [Specification] the top level specification for this set for any version.
112
54
  #
113
- def required_version
114
- version = versions.find { |v| dependency.match?(name, v) }
115
- unless version
116
- raise Informative, "Required version (#{dependency}) not found " \
117
- "for `#{name}`.\nAvailable versions: #{versions.join(', ')}"
55
+ def specification_name
56
+ versions_by_source.each do |source, versions|
57
+ next unless version = versions.first
58
+ return source.specification(name, version).name
118
59
  end
119
- version
60
+ nil
120
61
  end
121
62
 
122
- # @return [Array<Version>] All the versions which are acceptable given
123
- # the requirements.
63
+ # @return [Array<String>] the paths to specifications for the given
64
+ # version
124
65
  #
125
- def acceptable_versions
126
- versions.select { |v| dependency.match?(name, v) }
66
+ def specification_paths_for_version(version)
67
+ sources = @sources.select { |source| versions_by_source[source].include?(version) }
68
+ sources.map { |source| source.specification_path(name, version) }
127
69
  end
128
70
 
129
71
  # @return [Array<Version>] all the available versions for the Pod, sorted
130
72
  # from highest to lowest.
131
73
  #
132
74
  def versions
133
- versions_by_source.values.flatten.uniq.sort.reverse
75
+ @versions ||= versions_by_source.values.flatten.uniq.sort.reverse
134
76
  end
135
77
 
136
78
  # @return [Version] The highest version known of the specification.
@@ -141,19 +83,21 @@ module Pod
141
83
 
142
84
  # @return [Pathname] The path of the highest version.
143
85
  #
86
+ # @note If multiple sources have a specification for the
87
+ # {#required_version}, the order in which they are provided
88
+ # is used to disambiguate.
89
+ #
144
90
  def highest_version_spec_path
145
- specification_path_for_version(highest_version)
91
+ @highest_version_spec_path ||= specification_paths_for_version(highest_version).first
146
92
  end
147
93
 
148
94
  # @return [Hash{Source => Version}] all the available versions for the
149
95
  # Pod grouped by source.
150
96
  #
151
97
  def versions_by_source
152
- result = {}
153
- sources.each do |source|
98
+ @versions_by_source ||= sources.each_with_object({}) do |source, result|
154
99
  result[source] = source.versions(name)
155
100
  end
156
- result
157
101
  end
158
102
 
159
103
  def ==(other)
@@ -163,8 +107,7 @@ module Pod
163
107
  end
164
108
 
165
109
  def to_s
166
- "#<#{self.class.name} for `#{name}' with required version " \
167
- "`#{required_version}' available at `#{sources.map(&:name) * ', '}'>"
110
+ "#<#{self.class.name} for `#{name}' available at `#{sources.map(&:name).join(', ')}'>"
168
111
  end
169
112
  alias_method :inspect, :to_s
170
113
 
@@ -194,11 +137,6 @@ module Pod
194
137
 
195
138
  #-----------------------------------------------------------------------#
196
139
 
197
- attr_accessor :dependencies_by_requirer_name
198
- attr_accessor :dependencies
199
-
200
- #-----------------------------------------------------------------------#
201
-
202
140
  # The Set::External class handles Pods from external sources. Pods from
203
141
  # external sources don't use the {Source} and are initialized by a given
204
142
  # specification.
@@ -206,7 +144,6 @@ module Pod
206
144
  # @note External sources *don't* support subspecs.
207
145
  #
208
146
  class External < Set
209
-
210
147
  attr_reader :specification
211
148
 
212
149
  def initialize(spec)
@@ -218,14 +155,23 @@ module Pod
218
155
  self.class == other.class && specification == other.specification
219
156
  end
220
157
 
221
- def specification_path
222
- raise StandardError, "specification_path"
223
- end
224
-
225
158
  def versions
226
159
  [specification.version]
227
160
  end
228
161
  end
162
+
163
+ #-----------------------------------------------------------------------#
164
+
165
+ # The Set::Head class handles Pods in head mode. Pods in head
166
+ # mode don't use the {Source} and are initialized by a given
167
+ # specification.
168
+ #
169
+ class Head < External
170
+ def initialize(spec)
171
+ super
172
+ specification.version.head = true
173
+ end
174
+ end
229
175
  end
230
176
  end
231
177
  end