Class: Pod::SourcesManager

Inherits:
Object
  • Object
show all
Extended by:
Config::Mixin, Executable
Defined in:
lib/cocoapods/sources_manager.rb

Overview

Manages all the sources known to the running CocoaPods Instance.

Class Attribute Summary collapse

Master repo collapse

Class Method Summary collapse

Methods included from Config::Mixin

config

Methods included from Executable

executable, execute_command, which

Class Attribute Details

.updated_search_indexHash{String => String}

Note:

This operation is fairly expensive, because of the YAML conversion.

Creates or updates the search data and returns it. The search data groups by name the following information for each set:

- version
- summary
- description
- authors

Returns:

  • (Hash{String => String})

    The up to date search data.



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/cocoapods/sources_manager.rb', line 158

def updated_search_index
  unless @updated_search_index
    if search_index_path.exist?
      require 'yaml'
      stored_index = YAML.load(search_index_path.read)
      if stored_index && stored_index.is_a?(Hash)
        search_index = aggregate.update_search_index(stored_index)
      else
        search_index = aggregate.generate_search_index
      end
    else
      search_index = aggregate.generate_search_index
    end

    File.open(search_index_path, 'w') do |file|
      file.write(search_index.to_yaml)
    end
    @updated_search_index = search_index
  end
  @updated_search_index
end

Class Method Details

.aggregateSource::Aggregate

Returns The aggregate of all the sources with the known Pods.

Returns:

  • (Source::Aggregate)

    The aggregate of all the sources with the known Pods.



11
12
13
14
15
# File 'lib/cocoapods/sources_manager.rb', line 11

def aggregate
  return Source::Aggregate.new([]) unless config.repos_dir.exist?
  dirs = config.repos_dir.children.select(&:directory?)
  Source::Aggregate.new(dirs)
end

.allArray<Source>

Returns The list of all the sources known to this installation of CocoaPods.

Returns:

  • (Array<Source>)

    The list of all the sources known to this installation of CocoaPods.



77
78
79
80
81
# File 'lib/cocoapods/sources_manager.rb', line 77

def all
  return [] unless config.repos_dir.exist?
  dirs = config.repos_dir.children.select(&:directory?)
  dirs.map { |repo| Source.new(repo) }
end

.check_version_information(dir) ⇒ void

This method returns an undefined value.

Checks the version information of the source with the given directory. It raises if the source is not compatible and if there is CocoaPods update it informs the user.

Parameters:

  • dir (Pathname)

    The directory where the source is stored.

Raises:

  • If the source is not compatible.



252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/cocoapods/sources_manager.rb', line 252

def check_version_information(dir)
  versions = version_information(dir)
  unless repo_compatible?(dir)
    min, max = versions['min'], versions['max']
    version_msg = (min == max) ? min : "#{min} - #{max}"
    raise Informative, "The `#{dir.basename}` repo requires " \
    "CocoaPods #{version_msg} (currently using #{Pod::VERSION})\n".red +
      'Update CocoaPods, or checkout the appropriate tag in the repo.'
  end

  needs_sudo = path_writable?(__FILE__)

  if config.new_version_message? && cocoapods_update?(versions)
    last = versions['last']
    rc = Gem::Version.new(last).prerelease?
    install_message = needs_sudo ? 'sudo ' : ''
    install_message << 'gem install cocoapods'
    install_message << ' --pre' if rc
    message = [
      "CocoaPods #{versions['last']} is available.".green,
      "To update use: `#{install_message}`".green,
      ("[!] This is a test version we'd love you to try.".yellow if rc),
      ("Until we reach version 1.0 the features of CocoaPods can and will change.\n" \
       'We strongly recommend that you use the latest version at all times.'.yellow unless rc),
      '',
      'For more information see http://blog.cocoapods.org'.green,
      'and the CHANGELOG for this version http://git.io/BaH8pQ.'.green,
      '',
    ].compact.join("\n")
    UI.puts("\n#{message}\n")
  end
end

.cocoapods_update?(version_information) ⇒ Bool

Checks whether there is a CocoaPods given the version information of a repo.

Parameters:

  • version_information (Hash)

    The version information of a repository.

Returns:

  • (Bool)

    whether there is an update.



311
312
313
314
# File 'lib/cocoapods/sources_manager.rb', line 311

def cocoapods_update?(version_information)
  version = version_information['last']
  version && Gem::Version.new(version) > Gem::Version.new(Pod::VERSION)
end

.find_or_create_source_with_url(url) ⇒ Source

Returns the source whose Source#url is equal to ‘url`, adding the repo in a manner similarly to `pod repo add` if it is not found.

Parameters:

  • url (String)

    The URL of the source.

Returns:

  • (Source)

    The source whose Source#url is equal to ‘url`,

Raises:

  • If no source with the given ‘url` could be created,



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/cocoapods/sources_manager.rb', line 37

def find_or_create_source_with_url(url)
  unless source = source_with_url(url)
    name = name_for_url(url)
    # Hack to ensure that `repo add` output is shown.
    previous_title_level = UI.title_level
    UI.title_level = 0
    begin
      argv = [name, url]
      argv << '--shallow' if name =~ /^master(-\d+)?$/
      Command::Repo::Add.new(CLAide::ARGV.new(argv)).run
    rescue Informative
      raise Informative, "Unable to add a source with url `#{url}` " \
        "named `#{name}`.\nYou can try adding it manually in " \
        '`~/.cocoapods/repos` or via `pod repo add`.'
    ensure
      UI.title_level = previous_title_level
    end
    source = source_with_url(url)
  end

  source
end

.git_repo?(dir) ⇒ Bool

Returns whether a source is a GIT repo.

Parameters:

  • dir (Pathname)

    The directory where the source is stored.

Returns:

  • (Bool)

    Whether the given source is a GIT repo.



236
237
238
239
# File 'lib/cocoapods/sources_manager.rb', line 236

def git_repo?(dir)
  Dir.chdir(dir) { `git rev-parse >/dev/null 2>&1` }
  $?.success?
end

.masterArray<Source>

Returns The CocoaPods Master Repo source.

Returns:

  • (Array<Source>)

    The CocoaPods Master Repo source.



85
86
87
# File 'lib/cocoapods/sources_manager.rb', line 85

def master
  sources(['master'])
end

.master_repo_dirPathname

Returns The path of the master repo.

Returns:

  • (Pathname)

    The path of the master repo.



348
349
350
# File 'lib/cocoapods/sources_manager.rb', line 348

def master_repo_dir
  config.repos_dir + 'master'
end

.master_repo_functional?Bool

Note:

Note this is used to automatically setup the master repo if needed.

Returns Checks if the master repo is usable.

Returns:

  • (Bool)

    Checks if the master repo is usable.



357
358
359
# File 'lib/cocoapods/sources_manager.rb', line 357

def master_repo_functional?
  master_repo_dir.exist? && repo_compatible?(master_repo_dir)
end

.repo_compatible?(dir) ⇒ Bool

Returns whether a source is compatible with the current version of CocoaPods.

Parameters:

  • dir (Pathname)

    The directory where the source is stored.

Returns:

  • (Bool)

    whether the source is compatible.



293
294
295
296
297
298
299
300
301
# File 'lib/cocoapods/sources_manager.rb', line 293

def repo_compatible?(dir)
  versions = version_information(dir)

  min, max = versions['min'], versions['max']
  bin_version  = Gem::Version.new(Pod::VERSION)
  supports_min = !min || bin_version >= Gem::Version.new(min)
  supports_max = !max || bin_version <= Gem::Version.new(max)
  supports_min && supports_max
end

.search(dependency) ⇒ Set?

Search all the sources to match the set for the given dependency.

Returns:

  • (Set, nil)

    a set for a given dependency including all the Source that contain the Pod. If no sources containing the Pod where found it returns nil.

Raises:

  • If no source including the set can be found.



97
98
99
# File 'lib/cocoapods/sources_manager.rb', line 97

def search(dependency)
  aggregate.search(dependency)
end

.search_by_name(query, full_text_search = false) ⇒ Array<Set>

Note:

Full text search requires to load the specification for each pod, hence is considerably slower.

Search all the sources with the given search term.

Parameters:

  • query (String)

    The search term.

  • full_text_search (Bool) (defaults to: false)

    Whether the search should be limited to the name of the Pod or should include also the author, the summary, and the description.

Returns:

  • (Array<Set>)

    The sets that contain the search term.

Raises:

  • If no source including the set can be found.



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/cocoapods/sources_manager.rb', line 118

def search_by_name(query, full_text_search = false)
  if full_text_search
    set_names = []
    query_regexp = /#{query}/i
    updated_search_index.each do |name, set_data|
      texts = [name]
      if full_text_search
        texts << set_data['authors'].to_s if set_data['authors']
        texts << set_data['summary']      if set_data['summary']
        texts << set_data['description']  if set_data['description']
      end
      set_names << name unless texts.grep(query_regexp).empty?
    end
    sets = set_names.sort.map do |name|
      aggregate.representative_set(name)
    end
  else
    sets = aggregate.search_by_name(query, false)
  end
  if sets.empty?
    extra = ', author, summary, or description' if full_text_search
    raise Informative, "Unable to find a pod with name#{extra}" \
      "matching `#{query}`"
  end
  sets
end

.search_index_pathPathname

Returns The path where the search index should be stored.

Returns:

  • (Pathname)

    The path where the search index should be stored.



186
187
188
# File 'lib/cocoapods/sources_manager.rb', line 186

def search_index_path
  Config.instance.search_index_file
end

.source_with_name_or_url(name_or_url) ⇒ Source

Returns the source whose Source#name or Source#url is equal to the given ‘name_or_url`.

Parameters:

  • name_or_url (String)

    The name or the URL of the source.

Returns:

  • (Source)

    The source whose Source#name or Source#url is equal to the given ‘name_or_url`.



69
70
71
72
# File 'lib/cocoapods/sources_manager.rb', line 69

def source_with_name_or_url(name_or_url)
  all.find { |s| s.name == name_or_url } ||
    find_or_create_source_with_url(name_or_url)
end

.sources(names) ⇒ Array<Source>

Returns The list of the sources with the given names.

Parameters:

  • names (Array<#to_s>)

    The names of the sources.

Returns:

  • (Array<Source>)

    The list of the sources with the given names.



22
23
24
25
# File 'lib/cocoapods/sources_manager.rb', line 22

def sources(names)
  dirs = names.map { |name| source_dir(name) }
  dirs.map { |repo| Source.new(repo) }
end

.update(source_name = nil, show_output = false) ⇒ void

This method returns an undefined value.

Updates the local clone of the spec-repo with the given name or of all the git repos if the name is omitted.

Parameters:

  • source_name (String) (defaults to: nil)
  • show_output (Bool) (defaults to: false)


204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/cocoapods/sources_manager.rb', line 204

def update(source_name = nil, show_output = false)
  if source_name
    sources = [git_source_named(source_name)]
  else
    sources =  git_sources
  end

  sources.each do |source|
    UI.section "Updating spec repo `#{source.name}`" do
      Dir.chdir(source.repo) do
        begin
          output = git! %w(pull --ff-only)
          UI.puts output if show_output && !config.verbose?
        rescue Informative
          UI.warn 'CocoaPods was not able to update the ' \
            "`#{source.name}` repo. If this is an unexpected issue " \
            'and persists you can inspect it running ' \
            '`pod repo update --verbose`'
        end
      end
      check_version_information(source.repo)
    end
  end
end

.version_information(dir) ⇒ Hash

Returns the contents of the ‘CocoaPods-version.yml` file, which stores information about CocoaPods versions.

This file is a hash with the following keys:

  • last: the last version of CocoaPods known to the source.

  • min: the minimum version of CocoaPods supported by the source.

  • max: the maximum version of CocoaPods supported by the source.

Parameters:

  • dir (Pathname)

    The directory where the source is stored.

Returns:

  • (Hash)

    the versions information from the repo.



330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'lib/cocoapods/sources_manager.rb', line 330

def version_information(dir)
  require 'yaml'
  yaml_file  = dir + 'CocoaPods-version.yml'
  return {} unless yaml_file.exist?
  begin
    YAMLHelper.load_file(yaml_file)
  rescue Informative
    raise Informative, "There was an error reading '#{yaml_file}'.\n" \
      'Please consult http://blog.cocoapods.org/' \
      'Repairing-Our-Broken-Specs-Repository/ ' \
      'for more information.'
  end
end