cocoapods-square-stable 0.19.3

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 (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