cocoapods-square-stable 0.19.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1296 -0
  3. data/LICENSE +20 -0
  4. data/README.md +94 -0
  5. data/bin/pod +16 -0
  6. data/bin/sandbox-pod +120 -0
  7. data/lib/cocoapods.rb +77 -0
  8. data/lib/cocoapods/command.rb +116 -0
  9. data/lib/cocoapods/command/help.rb +23 -0
  10. data/lib/cocoapods/command/inter_process_communication.rb +178 -0
  11. data/lib/cocoapods/command/list.rb +77 -0
  12. data/lib/cocoapods/command/outdated.rb +56 -0
  13. data/lib/cocoapods/command/podfile_info.rb +91 -0
  14. data/lib/cocoapods/command/project.rb +88 -0
  15. data/lib/cocoapods/command/push.rb +172 -0
  16. data/lib/cocoapods/command/repo.rb +145 -0
  17. data/lib/cocoapods/command/search.rb +61 -0
  18. data/lib/cocoapods/command/setup.rb +134 -0
  19. data/lib/cocoapods/command/spec.rb +590 -0
  20. data/lib/cocoapods/config.rb +231 -0
  21. data/lib/cocoapods/downloader.rb +59 -0
  22. data/lib/cocoapods/executable.rb +118 -0
  23. data/lib/cocoapods/external_sources.rb +363 -0
  24. data/lib/cocoapods/file_list.rb +36 -0
  25. data/lib/cocoapods/gem_version.rb +7 -0
  26. data/lib/cocoapods/generator/acknowledgements.rb +107 -0
  27. data/lib/cocoapods/generator/acknowledgements/markdown.rb +40 -0
  28. data/lib/cocoapods/generator/acknowledgements/plist.rb +64 -0
  29. data/lib/cocoapods/generator/bridge_support.rb +22 -0
  30. data/lib/cocoapods/generator/copy_resources_script.rb +54 -0
  31. data/lib/cocoapods/generator/dummy_source.rb +22 -0
  32. data/lib/cocoapods/generator/prefix_header.rb +82 -0
  33. data/lib/cocoapods/generator/target_environment_header.rb +86 -0
  34. data/lib/cocoapods/generator/xcconfig.rb +185 -0
  35. data/lib/cocoapods/hooks/installer_representation.rb +134 -0
  36. data/lib/cocoapods/hooks/library_representation.rb +94 -0
  37. data/lib/cocoapods/hooks/pod_representation.rb +74 -0
  38. data/lib/cocoapods/installer.rb +571 -0
  39. data/lib/cocoapods/installer/analyzer.rb +559 -0
  40. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +253 -0
  41. data/lib/cocoapods/installer/file_references_installer.rb +179 -0
  42. data/lib/cocoapods/installer/pod_source_installer.rb +248 -0
  43. data/lib/cocoapods/installer/target_installer.rb +379 -0
  44. data/lib/cocoapods/installer/user_project_integrator.rb +180 -0
  45. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +224 -0
  46. data/lib/cocoapods/library.rb +202 -0
  47. data/lib/cocoapods/open_uri.rb +24 -0
  48. data/lib/cocoapods/project.rb +209 -0
  49. data/lib/cocoapods/resolver.rb +212 -0
  50. data/lib/cocoapods/sandbox.rb +343 -0
  51. data/lib/cocoapods/sandbox/file_accessor.rb +217 -0
  52. data/lib/cocoapods/sandbox/headers_store.rb +96 -0
  53. data/lib/cocoapods/sandbox/path_list.rb +208 -0
  54. data/lib/cocoapods/sources_manager.rb +276 -0
  55. data/lib/cocoapods/user_interface.rb +304 -0
  56. data/lib/cocoapods/user_interface/error_report.rb +101 -0
  57. data/lib/cocoapods/validator.rb +350 -0
  58. metadata +238 -0
@@ -0,0 +1,276 @@
1
+ module Pod
2
+
3
+ # Manages all the sources known to the running CocoaPods Instance.
4
+ #
5
+ class SourcesManager
6
+
7
+ class << self
8
+
9
+ include Config::Mixin
10
+
11
+ # @return [Source::Aggregate] the aggregate of all the sources known to
12
+ # this installation of CocoaPods.
13
+ #
14
+ def aggregate
15
+ Source::Aggregate.new(config.repos_dir)
16
+ end
17
+
18
+ # @return [Array<Source>] the list of all the sources known to this
19
+ # installation of CocoaPods.
20
+ #
21
+ def all
22
+ aggregate.all
23
+ end
24
+
25
+ # @return [Array<Specification::Set>] the list of all the specification
26
+ # sets know to this installation of CocoaPods.
27
+ #
28
+ def all_sets
29
+ aggregate.all_sets
30
+ end
31
+
32
+ # Search all the sources to match the set for the given dependency.
33
+ #
34
+ # @return [Set, nil] a set for a given dependency including all the
35
+ # {Source} that contain the Pod. If no sources containing the
36
+ # Pod where found it returns nil.
37
+ #
38
+ # @raise If no source including the set can be found.
39
+ #
40
+ def search(dependency)
41
+ aggregate.search(dependency)
42
+ end
43
+
44
+ # Search all the sources with the given search term.
45
+ #
46
+ # @param [String] query
47
+ # The search term.
48
+ #
49
+ # @param [Bool] full_text_search
50
+ # Whether the search should be limited to the name of the Pod or
51
+ # should include also the author, the summary, and the
52
+ # description.
53
+ #
54
+ # @raise If no source including the set can be found.
55
+ #
56
+ # @note Full text search requires to load the specification for each
57
+ # pod, hence is considerably slower.
58
+ #
59
+ # @return [Array<Set>] The sets that contain the search term.
60
+ #
61
+ def search_by_name(query, full_text_search = false)
62
+ if full_text_search
63
+ set_names = []
64
+ updated_search_index.each do |name, set_data|
65
+ text = name.dup
66
+ if full_text_search
67
+ text << set_data['authors'].to_s if set_data['authors']
68
+ text << set_data['summary'] if set_data['summary']
69
+ text << set_data['description'] if set_data['description']
70
+ end
71
+ set_names << name if text.downcase.include?(query.downcase)
72
+ end
73
+ sets = set_names.sort.map { |name| aggregate.represenative_set(name) }
74
+ else
75
+ sets = aggregate.search_by_name(query, false)
76
+ end
77
+ if sets.empty?
78
+ extra = ", author, summary, or description" if full_text_search
79
+ raise Informative, "Unable to find a pod with name#{extra} matching `#{query}`"
80
+ end
81
+ sets
82
+ end
83
+
84
+ # Creates or updates the search data and returns it. The search data
85
+ # groups by name the following information for each set:
86
+ #
87
+ # - version
88
+ # - summary
89
+ # - description
90
+ # - authors
91
+ #
92
+ # @note This operation is fairly expensive, because of the YAML
93
+ # conversion.
94
+ #
95
+ # @return [Hash{String => String}] The up to date search data.
96
+ #
97
+ def updated_search_index
98
+ unless @updated_search_index
99
+ if search_index_path.exist?
100
+ stored_index = YAML.load(search_index_path.read)
101
+ if stored_index && stored_index.is_a?(Hash)
102
+ search_index = aggregate.update_search_index(stored_index)
103
+ else
104
+ search_index = aggregate.generate_search_index
105
+ end
106
+ else
107
+ search_index = aggregate.generate_search_index
108
+ end
109
+
110
+ File.open(search_index_path, 'w') {|f| f.write(search_index.to_yaml) }
111
+ @updated_search_index = search_index
112
+ end
113
+ @updated_search_index
114
+ end
115
+
116
+ # Allows to clear the search index.
117
+ #
118
+ attr_writer :updated_search_index
119
+
120
+ # @return [Pathname] The path where the search index should be stored.
121
+ #
122
+ def search_index_path
123
+ CACHE_ROOT + 'search_index.yaml'
124
+ end
125
+
126
+ public
127
+
128
+ # @!group Updating Sources
129
+ #-----------------------------------------------------------------------#
130
+
131
+ extend Executable
132
+ executable :git
133
+
134
+ # Updates the local clone of the spec-repo with the given name or of all
135
+ # the git repos if the name is omitted.
136
+ #
137
+ # @param [String] name
138
+ #
139
+ # @return [void]
140
+ #
141
+ def update(source_name = nil, show_output = false)
142
+ if source_name
143
+ specified_source = aggregate.all.find { |s| s.name == source_name }
144
+ raise Informative, "Unable to find the `#{source_name}` repo." unless specified_source
145
+ raise Informative, "The `#{source_name}` repo is not a git repo." unless git_repo?(specified_source.repo)
146
+ sources = [specified_source]
147
+ else
148
+ sources = aggregate.all.select { |source| git_repo?(source.repo) }
149
+ end
150
+
151
+ sources.each do |source|
152
+ UI.section "Updating spec repo `#{source.name}`" do
153
+ Dir.chdir(source.repo) do
154
+ output = git!("pull")
155
+ UI.puts output if show_output && !config.verbose?
156
+ end
157
+ check_version_information(source.repo)
158
+ end
159
+ end
160
+ end
161
+
162
+ # Returns whether a source is a GIT repo.
163
+ #
164
+ # @param [Pathname] dir
165
+ # The directory where the source is stored.
166
+ #
167
+ # @return [Bool] Wether the given source is a GIT repo.
168
+ #
169
+ def git_repo?(dir)
170
+ Dir.chdir(dir) { `git rev-parse >/dev/null 2>&1` }
171
+ $?.exitstatus.zero?
172
+ end
173
+
174
+ # Checks the version information of the source with the given directory.
175
+ # It raises if the source is not compatible and if there is CocoaPods
176
+ # update it informs the user.
177
+ #
178
+ # @param [Pathname] dir
179
+ # The directory where the source is stored.
180
+ #
181
+ # @raise If the source is not compatible.
182
+ #
183
+ # @return [void]
184
+ #
185
+ def check_version_information(dir)
186
+ versions = version_information(dir)
187
+ unless repo_compatible?(dir)
188
+ min, max = versions['min'], versions['max']
189
+ version_msg = ( min == max ) ? min : "#{min} - #{max}"
190
+ raise Informative, "The `#{dir.basename}` repo requires " \
191
+ "CocoaPods #{version_msg}\n".red +
192
+ "Update CocoaPods, or checkout the appropriate tag in the repo."
193
+ end
194
+
195
+ if config.new_version_message? && cocoapods_update?(versions)
196
+ UI.puts "\nCocoaPods #{versions['last']} is available.\n".green
197
+ end
198
+ end
199
+
200
+ # Returns whether a source is compatible with the current version of
201
+ # CocoaPods.
202
+ #
203
+ # @param [Pathname] dir
204
+ # The directory where the source is stored.
205
+ #
206
+ # @return [Bool] whether the source is compatible.
207
+ #
208
+ def repo_compatible?(dir)
209
+ versions = version_information(dir)
210
+
211
+ min, max = versions['min'], versions['max']
212
+ bin_version = Gem::Version.new(Pod::VERSION)
213
+ supports_min = !min || bin_version >= Gem::Version.new(min)
214
+ supports_max = !max || bin_version <= Gem::Version.new(max)
215
+ supports_min && supports_max
216
+ end
217
+
218
+ # Checks whether there is a CocoaPods given the version information of a
219
+ # repo.
220
+ #
221
+ # @param [Hash] version_information
222
+ # The version information of a repository.
223
+ #
224
+ # @return [Bool] whether there is an update.
225
+ #
226
+ def cocoapods_update?(version_information)
227
+ version = version_information['last']
228
+ version && Gem::Version.new(version) > Gem::Version.new(Pod::VERSION)
229
+ end
230
+
231
+ # Returns the contents of the `CocoaPods-version.yml` file, which stores
232
+ # information about CocoaPods versions.
233
+ #
234
+ # This file is a hash with the following keys:
235
+ #
236
+ # - last: the last version of CocoaPods known to the source.
237
+ # - min: the minimum version of CocoaPods supported by the source.
238
+ # - max: the maximum version of CocoaPods supported by the source.
239
+ #
240
+ # @param [Pathname] dir
241
+ # The directory where the source is stored.
242
+ #
243
+ # @return [Hash] the versions information from the repo.
244
+ #
245
+ def version_information(dir)
246
+ require 'yaml'
247
+ yaml_file = dir + 'CocoaPods-version.yml'
248
+ yaml_file.exist? ? YAML.load_file(yaml_file) : {}
249
+ end
250
+
251
+ public
252
+
253
+ # @!group Master repo
254
+ #-----------------------------------------------------------------------#
255
+
256
+ # @return [Pathname] The path of the master repo.
257
+ #
258
+ def master_repo_dir
259
+ config.repos_dir + 'master'
260
+ end
261
+
262
+ # @return [Bool] Checks if the master repo is usable.
263
+ #
264
+ # @note Note this is used to automatically setup the master repo if
265
+ # needed.
266
+ #
267
+ def master_repo_functional?
268
+ master_repo_dir.exist? && repo_compatible?(master_repo_dir)
269
+ end
270
+
271
+ #-----------------------------------------------------------------------#
272
+
273
+ end
274
+ end
275
+ end
276
+
@@ -0,0 +1,304 @@
1
+ require 'cocoapods/user_interface/error_report'
2
+
3
+ module Pod
4
+
5
+ # Provides support for UI output. It provides support for nested sections of
6
+ # information and for a verbose mode.
7
+ #
8
+ module UserInterface
9
+
10
+ require 'colored'
11
+
12
+ @title_colors = %w|yellow green|
13
+ @title_level = 0
14
+ @indentation_level = 2
15
+ @treat_titles_as_messages = false
16
+ @warnings = []
17
+
18
+ class << self
19
+
20
+ include Config::Mixin
21
+
22
+ attr_accessor :indentation_level
23
+ attr_accessor :title_level
24
+ attr_accessor :warnings
25
+
26
+ # @return [Bool] Whether the wrapping of the strings to the width of the
27
+ # terminal should be disabled.
28
+ #
29
+ attr_accessor :disable_wrap
30
+ alias_method :disable_wrap?, :disable_wrap
31
+
32
+ # Prints a title taking an optional verbose prefix and
33
+ # a relative indentation valid for the UI action in the passed
34
+ # block.
35
+ #
36
+ # In verbose mode titles are printed with a color according
37
+ # to their level. In normal mode titles are printed only if
38
+ # they have nesting level smaller than 2.
39
+ #
40
+ # @todo Refactor to title (for always visible titles like search)
41
+ # and sections (titles that represent collapsible sections).
42
+ #
43
+ def section(title, verbose_prefix = '', relative_indentation = 0)
44
+ if config.verbose?
45
+ title(title, verbose_prefix, relative_indentation)
46
+ elsif title_level < 1
47
+ puts title
48
+ end
49
+
50
+ self.indentation_level += relative_indentation
51
+ self.title_level += 1
52
+ yield if block_given?
53
+ self.indentation_level -= relative_indentation
54
+ self.title_level -= 1
55
+ end
56
+
57
+ # In verbose mode it shows the sections and the contents.
58
+ # In normal mode it just prints the title.
59
+ #
60
+ # @return [void]
61
+ #
62
+ def titled_section(title, options = {})
63
+ relative_indentation = options[:relative_indentation] || 0
64
+ verbose_prefix = options[:verbose_prefix] || ''
65
+ if config.verbose?
66
+ title(title, verbose_prefix, relative_indentation)
67
+ else
68
+ puts title
69
+ end
70
+
71
+ self.indentation_level += relative_indentation
72
+ self.title_level += 1
73
+ yield if block_given?
74
+ self.indentation_level -= relative_indentation
75
+ self.title_level -= 1
76
+ end
77
+
78
+ # A title opposed to a section is always visible
79
+ #
80
+ def title(title, verbose_prefix = '', relative_indentation = 2)
81
+ if(@treat_titles_as_messages)
82
+ message(title, verbose_prefix)
83
+ else
84
+ title = verbose_prefix + title if config.verbose?
85
+ title = "\n#{title}" if @title_level < 2
86
+ if (color = @title_colors[@title_level])
87
+ title = title.send(color)
88
+ end
89
+ puts "#{title}"
90
+ end
91
+
92
+ self.indentation_level += relative_indentation
93
+ self.title_level += 1
94
+ yield if block_given?
95
+ self.indentation_level -= relative_indentation
96
+ self.title_level -= 1
97
+ end
98
+
99
+ # def title(title, verbose_prefix = '', relative_indentation = 2)
100
+ # end
101
+
102
+ # Prints a verbose message taking an optional verbose prefix and
103
+ # a relative indentation valid for the UI action in the passed
104
+ # block.
105
+ #
106
+ # @todo Clean interface.
107
+ #
108
+ def message(message, verbose_prefix = '', relative_indentation = 2)
109
+ message = verbose_prefix + message if config.verbose?
110
+ puts_indented message if config.verbose?
111
+
112
+ self.indentation_level += relative_indentation
113
+ yield if block_given?
114
+ self.indentation_level -= relative_indentation
115
+ end
116
+
117
+ # Prints an info to the user. The info is always displayed.
118
+ # It respects the current indentation level only in verbose
119
+ # mode.
120
+ #
121
+ # Any title printed in the optional block is treated as a message.
122
+ #
123
+ def info(message)
124
+ indentation = config.verbose? ? self.indentation_level : 0
125
+ indented = wrap_string(message, " " * indentation)
126
+ puts(indented)
127
+
128
+ self.indentation_level += 2
129
+ @treat_titles_as_messages = true
130
+ yield if block_given?
131
+ @treat_titles_as_messages = false
132
+ self.indentation_level -= 2
133
+ end
134
+
135
+ # Prints an important message to the user.
136
+ #
137
+ # @param [String] message The message to print.
138
+ #
139
+ # return [void]
140
+ #
141
+ def notice(message)
142
+ puts("\n[!] #{message}".green)
143
+ end
144
+
145
+ # Returns a string containing relative location of a path from the Podfile.
146
+ # The returned path is quoted. If the argument is nit it returns the
147
+ # empty string.
148
+ #
149
+ def path(pathname)
150
+ if pathname
151
+ path = pathname.relative_path_from(config.podfile_path.dirname || Pathname.pwd)
152
+ "`#{path}`"
153
+ else
154
+ ''
155
+ end
156
+ end
157
+
158
+ # Prints the textual representation of a given set.
159
+ #
160
+ def pod(set, mode = :normal, statistics_provider = nil)
161
+ if mode == :name
162
+ puts_indented set.name
163
+ else
164
+ pod = Specification::Set::Presenter.new(set, statistics_provider)
165
+ title("\n-> #{pod.name} (#{pod.version})".green, '', 1) do
166
+ puts_indented pod.summary
167
+ labeled('Homepage', pod.homepage)
168
+ labeled('Source', pod.source_url)
169
+ labeled('Versions', pod.verions_by_source)
170
+ if mode == :stats
171
+ labeled('Pushed', pod.github_last_activity)
172
+ labeled('Authors', pod.authors) if pod.authors =~ /,/
173
+ labeled('Author', pod.authors) if pod.authors !~ /,/
174
+ labeled('License', pod.license)
175
+ labeled('Platform', pod.platform)
176
+ labeled('Watchers', pod.github_watchers)
177
+ labeled('Forks', pod.github_forks)
178
+ end
179
+ labeled('Sub specs', pod.subspecs)
180
+ end
181
+ end
182
+ end
183
+
184
+ # Prints a message with a label.
185
+ #
186
+ def labeled(label, value)
187
+ if value
188
+ ''.tap do |t|
189
+ t << " - #{label}:".ljust(16)
190
+ if value.is_a?(Array)
191
+ separator = "\n - "
192
+ puts_indented t << separator << value.join(separator)
193
+ else
194
+ puts_indented t << value.to_s << "\n"
195
+ end
196
+ end
197
+ end
198
+ end
199
+
200
+ # Prints a message respecting the current indentation level and
201
+ # wrapping it to the terminal width if necessary.
202
+ #
203
+ def puts_indented(message = '')
204
+ indented = wrap_string(message, " " * self.indentation_level)
205
+ puts(indented)
206
+ end
207
+
208
+ # Prints the stored warnings. This method is intended to be called at the
209
+ # end of the execution of the binary.
210
+ #
211
+ # @return [void]
212
+ #
213
+ def print_warnings
214
+ STDOUT.flush
215
+ warnings.each do |warning|
216
+ next if warning[:verbose_only] && !config.verbose?
217
+ STDERR.puts("\n[!] #{warning[:message]}".yellow)
218
+ warning[:actions].each do |action|
219
+ indented = wrap_string(action, " - ")
220
+ puts(indented)
221
+ end
222
+ end
223
+ end
224
+
225
+ public
226
+
227
+ # @!group Basic methods
228
+ #-----------------------------------------------------------------------#
229
+
230
+ # prints a message followed by a new line unless config is silent.
231
+ #
232
+ def puts(message = '')
233
+ STDOUT.puts(message) unless config.silent?
234
+ end
235
+
236
+ # prints a message followed by a new line unless config is silent.
237
+ #
238
+ def print(message)
239
+ STDOUT.print(message) unless config.silent?
240
+ end
241
+
242
+ # Stores important warning to the user optionally followed by actions
243
+ # that the user should take. To print them use {#print_warnings}.
244
+ #
245
+ # @param [String] message The message to print.
246
+ # @param [Array] actions The actions that the user should take.
247
+ #
248
+ # return [void]
249
+ #
250
+ def warn(message, actions = [], verbose_only = false)
251
+ warnings << { :message => message, :actions => actions, :verbose_only => verbose_only }
252
+ end
253
+
254
+ private
255
+
256
+ # @!group Helpers
257
+ #-----------------------------------------------------------------------#
258
+
259
+ # @return [String] Wraps a string taking into account the width of the
260
+ # terminal and an option indent. Adapted from
261
+ # http://blog.macromates.com/2006/wrapping-text-with-regular-expressions/
262
+ #
263
+ # @param [String] txt The string to wrap
264
+ #
265
+ # @param [String] indent The string to use to indent the result.
266
+ #
267
+ # @return [String] The formatted string.
268
+ #
269
+ # @note If CocoaPods is not being run in a terminal or the width of the
270
+ # terminal is too small a width of 80 is assumed.
271
+ #
272
+ def wrap_string(txt, indent = '')
273
+ if disable_wrap || !STDIN.tty?
274
+ txt
275
+ else
276
+ width = `stty size`.split(' ')[1].to_i - indent.length
277
+ width = 80 unless width >= 10
278
+ txt.strip.gsub(/(.{1,#{width}})( +|$)\n?|(.{#{width}})/, indent + "\\1\\3\n")
279
+ end
280
+ end
281
+ end
282
+ end
283
+ UI = UserInterface
284
+
285
+ # Redirects cocoapods-core UI.
286
+ #
287
+ module CoreUI
288
+
289
+ class << self
290
+
291
+ # @todo enable in CocoaPods 0.17.0 release
292
+ #
293
+ def puts(message)
294
+ # UI.puts message
295
+ end
296
+
297
+ # @todo enable in CocoaPods 0.17.0 release
298
+ #
299
+ def warn(message)
300
+ # UI.warn message
301
+ end
302
+ end
303
+ end
304
+ end