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,45 +1,37 @@
1
1
  module Pod
2
2
  class Source
3
-
4
3
  # The Aggregate manages a directory of sources repositories.
5
4
  #
6
5
  class Aggregate
7
-
8
- # @return [Pathname] the directory were the repositories are stored.
6
+ # @return [Array<Source>] The ordered list of sources.
9
7
  #
10
- attr_reader :repos_dir
11
-
12
- # @param [Pathname] repos_dir @see repos_dir.
13
- #
14
- def initialize(repos_dir)
15
- @repos_dir = repos_dir
16
- end
8
+ attr_reader :sources
17
9
 
18
- # @return [Array<Source>] all the sources.
10
+ # @param [Array<Source>] repos_dirs @see Sources
19
11
  #
20
- def all
21
- @sources ||= dirs.map { |repo| Source.new(repo) }.sort_by(&:name)
12
+ def initialize(sources)
13
+ raise "Cannot initialize an aggregate with a nil source: (#{sources})" if sources.include?(nil)
14
+ @sources = sources
22
15
  end
23
16
 
24
17
  # @return [Array<String>] the names of all the pods available.
25
18
  #
26
19
  def all_pods
27
- all.map(&:pods).flatten.uniq
20
+ sources.map(&:pods).flatten.uniq
28
21
  end
29
22
 
30
- # @return [Array<Set>] the sets for all the pods available.
23
+ # @return [Array<Set>] The sets for all the pods available.
31
24
  #
32
25
  # @note Implementation detail: The sources don't cache their values
33
26
  # because they might change in response to an update. Therefore
34
- # this method to prevent slowness caches the values before
27
+ # this method to preserve performance caches the values before
35
28
  # processing them.
36
29
  #
37
30
  def all_sets
38
31
  pods_by_source = {}
39
- all.each do |source|
32
+ sources.each do |source|
40
33
  pods_by_source[source] = source.pods
41
34
  end
42
- sources = pods_by_source.keys
43
35
  pods = pods_by_source.values.flatten.uniq
44
36
 
45
37
  pods.map do |pod|
@@ -49,20 +41,6 @@ module Pod
49
41
  end
50
42
  end
51
43
 
52
- # @return [Array<Pathname>] the directories where the sources are stored.
53
- #
54
- # @note If the repos dir doesn't exits this will return an empty array.
55
- #
56
- # @raise If the repos dir doesn't exits.
57
- #
58
- def dirs
59
- if repos_dir.exist?
60
- repos_dir.children.select(&:directory?)
61
- else
62
- []
63
- end
64
- end
65
-
66
44
  # Returns a set configured with the source which contains the highest
67
45
  # version in the aggregate.
68
46
  #
@@ -70,12 +48,12 @@ module Pod
70
48
  # The name of the Pod.
71
49
  #
72
50
  # @return [Set] The most representative set for the Pod with the given
73
- # name.
51
+ # name. Returns nil if no representative source found containing a pod with given name.
74
52
  #
75
53
  def representative_set(name)
76
54
  representative_source = nil
77
55
  highest_version = nil
78
- all.each do |source|
56
+ sources.each do |source|
79
57
  source_versions = source.versions(name)
80
58
  if source_versions
81
59
  source_version = source_versions.first
@@ -85,7 +63,7 @@ module Pod
85
63
  end
86
64
  end
87
65
  end
88
- Specification::Set.new(name, representative_source)
66
+ representative_source ? Specification::Set.new(name, representative_source) : nil
89
67
  end
90
68
 
91
69
  public
@@ -102,9 +80,9 @@ module Pod
102
80
  # @see Source#search
103
81
  #
104
82
  def search(dependency)
105
- sources = all.select { |s| !s.search(dependency).nil? }
106
- unless sources.empty?
107
- Specification::Set.new(dependency.root_name, sources)
83
+ found_sources = sources.select { |s| s.search(dependency) }
84
+ unless found_sources.empty?
85
+ Specification::Set.new(dependency.root_name, found_sources)
108
86
  end
109
87
  end
110
88
 
@@ -119,21 +97,23 @@ module Pod
119
97
  def search_by_name(query, full_text_search = false)
120
98
  pods_by_source = {}
121
99
  result = []
122
- all.each do |s|
100
+ sources.each do |s|
123
101
  source_pods = s.search_by_name(query, full_text_search)
124
102
  pods_by_source[s] = source_pods.map(&:name)
125
103
  end
104
+
126
105
  root_spec_names = pods_by_source.values.flatten.uniq
127
106
  root_spec_names.each do |pod|
128
- sources = []
129
- pods_by_source.each do |source, pods|
130
- sources << source if pods.include?(pod)
107
+ result_sources = sources.select do |source|
108
+ pods_by_source[source].include?(pod)
131
109
  end
132
- result << Specification::Set.new(pod, sources)
110
+
111
+ result << Specification::Set.new(pod, result_sources)
133
112
  end
113
+
134
114
  if result.empty?
135
- extra = ", author, summary, or description" if full_text_search
136
- raise Informative, "Unable to find a pod with name" \
115
+ extra = ', author, summary, or description' if full_text_search
116
+ raise Informative, 'Unable to find a pod with name' \
137
117
  "#{extra} matching `#{query}'"
138
118
  end
139
119
  result
@@ -144,57 +124,35 @@ module Pod
144
124
  # @!group Search Index
145
125
  #-----------------------------------------------------------------------#
146
126
 
147
- # Generates from scratch the search data for all the sources of the
148
- # aggregate. This operation can take a considerable amount of time
127
+ # Generates from scratch the search data for given source.
128
+ # This operation can take a considerable amount of time
149
129
  # (seconds) as it needs to evaluate the most representative podspec
150
130
  # for each Pod.
151
131
  #
152
- # @return [Hash{String=>Hash}] The search data of every set grouped by
153
- # name.
132
+ # @param [Source] source
133
+ # The source from which a search index will be generated.
154
134
  #
155
- def generate_search_index
156
- result = {}
157
- all_sets.each do |set|
158
- result[set.name] = search_data_from_set(set)
159
- end
160
- result
135
+ # @return [Hash{String=>Hash}] The search data for the source.
136
+ #
137
+ def generate_search_index_for_source(source)
138
+ generate_search_index_for_sets(source.pod_sets)
161
139
  end
162
140
 
163
- # Updates inline the given search data with the information stored in all
164
- # the sources. The update skips the Pods for which the version of the
165
- # search data is the same of the highest version known to the aggregate.
166
- # This can lead to updates in podspecs being skipped until a new version
167
- # is released.
168
- #
169
- # @note This procedure is considerably faster as it only needs to
170
- # load the most representative spec of the new or updated Pods.
171
- #
172
- # @return [Hash{String=>Hash}] The search data of every set grouped by
173
- # name.
174
- #
175
- def update_search_index(search_data)
176
- enumerated_names = []
177
- all_sets.each do |set|
178
- enumerated_names << set.name
179
- set_data = search_data[set.name]
180
- has_data = set_data && set_data['version']
181
- if has_data
182
- stored_version = Version.new(set_data['version'])
183
- if stored_version < set.required_version
184
- search_data[set.name] = search_data_from_set(set)
185
- end
186
- else
187
- search_data[set.name] = search_data_from_set(set)
188
- end
189
- end
190
-
191
- stored_names = search_data.keys
192
- delted_names = stored_names - enumerated_names
193
- delted_names.each do |name|
194
- search_data.delete(name)
141
+ # Generates from scratch the search data for changed specifications in given source.
142
+ #
143
+ # @param [Source] source
144
+ # The source from which a search index will be generated.
145
+ # @param [Array<String>] spec_paths
146
+ # Array of file path names for corresponding changed specifications.
147
+ #
148
+ # @return [Hash{String=>Hash}] The search data for changed specifications.
149
+ #
150
+ def generate_search_index_for_changes_in_source(source, spec_paths)
151
+ pods = source.pods_for_specification_paths(spec_paths)
152
+ sets = pods.map do |pod|
153
+ Specification::Set.new(pod, source)
195
154
  end
196
-
197
- search_data
155
+ generate_search_index_for_sets(sets)
198
156
  end
199
157
 
200
158
  private
@@ -202,8 +160,19 @@ module Pod
202
160
  # @!group Private helpers
203
161
  #-----------------------------------------------------------------------#
204
162
 
205
- # Returns the search related information from the most representative
206
- # specification of the set following keys:
163
+ # Generates search data for given array of sets.
164
+ def generate_search_index_for_sets(sets)
165
+ result = {}
166
+ sets.each do |set|
167
+ word_list_from_set(set).each do |w|
168
+ (result[w] ||= []).push(set.name)
169
+ end
170
+ end
171
+ result
172
+ end
173
+
174
+ # Returns the vocabulary extracted from the most representative
175
+ # specification of the set. Vocabulary contains words from following information:
207
176
  #
208
177
  # - version
209
178
  # - summary
@@ -213,30 +182,37 @@ module Pod
213
182
  # @param [Set] set
214
183
  # The set for which the information is needed.
215
184
  #
216
- # @note If the specification can't load an empty hash is returned and
185
+ # @note If the specification can't load an empty array is returned and
217
186
  # a warning is printed.
218
187
  #
219
188
  # @note For compatibility with non Ruby clients a strings are used
220
189
  # instead of symbols for the keys.
221
190
  #
222
- # @return [Hash{String=>String}] A hash with the search information.
191
+ # @return [Array<String>] An array of words contained by the set's search related information.
223
192
  #
224
- def search_data_from_set(set)
225
- result = {}
193
+ def word_list_from_set(set)
226
194
  spec = set.specification
227
- result['version'] = spec.version.to_s
228
- result['summary'] = spec.summary
229
- result['description'] = spec.description
230
- result['authors'] = spec.authors.keys.sort * ', '
231
- result
195
+ word_list = [set.name.dup]
196
+ if spec.summary
197
+ word_list += spec.summary.split
198
+ end
199
+ if spec.description
200
+ word_list += spec.description.split
201
+ end
202
+ if spec.authors
203
+ spec.authors.each_pair do |k, v|
204
+ word_list += k.split if k
205
+ word_list += v.split if v
206
+ end
207
+ end
208
+ word_list.uniq
232
209
  rescue
233
210
  CoreUI.warn "Skipping `#{set.name}` because the podspec contains " \
234
- "errors."
235
- result
211
+ 'errors.'
212
+ []
236
213
  end
237
214
 
238
215
  #-----------------------------------------------------------------------#
239
-
240
216
  end
241
217
  end
242
218
  end
@@ -1,10 +1,8 @@
1
1
  module Pod
2
2
  class Source
3
-
4
3
  # Checks a source for errors and warnings.
5
4
  #
6
5
  class HealthReporter
7
-
8
6
  # @return [Source] the source to check.
9
7
  #
10
8
  attr_reader :source
@@ -89,8 +87,8 @@ module Pod
89
87
  linter = Specification::Linter.new(spec_path)
90
88
  linter.lint
91
89
  linter.results.each do |result|
92
- type = result.type == :error ? :error : :warning
93
- report.add_message(type, result.message, name, version)
90
+ next if result.public_only?
91
+ report.add_message(result.type, result.message, name, version)
94
92
  end
95
93
  linter.spec
96
94
  end
@@ -111,7 +109,7 @@ module Pod
111
109
  #
112
110
  def check_spec_path(name, version, spec)
113
111
  unless spec.name == name && spec.version.to_s == version.to_s
114
- message = "Incorrect path #{ spec.defined_in_file }"
112
+ message = "Incorrect path #{spec.defined_in_file}"
115
113
  report.add_message(:error, message, name, spec.version)
116
114
  end
117
115
  end
@@ -124,10 +122,10 @@ module Pod
124
122
  # @return [void]
125
123
  #
126
124
  def check_stray_specs
127
- all_paths = Pathname.glob(source.data_provider.repo + '**/*.podspec{,.json}')
125
+ all_paths = Pathname.glob(source.repo + '**/*.podspec{,.json}')
128
126
  stray_specs = all_paths - report.analyzed_paths
129
127
  stray_specs.each do |path|
130
- report.add_message(:error, "Stray spec", path)
128
+ report.add_message(:error, 'Stray spec', path)
131
129
  end
132
130
  end
133
131
 
@@ -136,7 +134,6 @@ module Pod
136
134
  # Encapsulates the information about the state of a repo.
137
135
  #
138
136
  class HealthReport
139
-
140
137
  # @return [Source] the source analyzed.
141
138
  #
142
139
  attr_reader :source
@@ -182,20 +179,14 @@ module Pod
182
179
  # @return [void]
183
180
  #
184
181
  def add_message(type, message, spec_name, spec_version = nil)
185
- if type == :error
186
- pods_by_error[message] ||= {}
187
- pods_by_error[message][spec_name] ||= []
188
- pods_by_error[message][spec_name] << spec_version
189
- else
190
- pods_by_warning[message] ||= {}
191
- pods_by_warning[message][spec_name] ||= []
192
- pods_by_warning[message][spec_name] << spec_version
193
- end
182
+ pods = send(:"pods_by_#{type}")
183
+ pods[message] ||= {}
184
+ pods[message][spec_name] ||= []
185
+ pods[message][spec_name] << spec_version
194
186
  end
195
187
  end
196
188
 
197
189
  #-----------------------------------------------------------------------#
198
-
199
190
  end
200
191
  end
201
192
  end