Spec-Zone.ru › Ruby 2.7

класс Bundler::Installer

Родитель:
Объект

Атрибуты

ambiguous_gems[RW]
post_install_messages[R]

Публичные методы класса

install(root, definition, options = {}) Показать исходный код
# File lib/bundler/installer.rb, line 22
def self.install(root, definition, options = {})
  installer = new(root, definition)
  Plugin.hook(Plugin::Events::GEM_BEFORE_INSTALL_ALL, definition.dependencies)
  installer.run(options)
  Plugin.hook(Plugin::Events::GEM_AFTER_INSTALL_ALL, definition.dependencies)
  installer
end

Начинает процесс установки для Bundler. Дополнительную информацию см. в методе run этого класса.

new(root, definition) Показать исходный код
# File lib/bundler/installer.rb, line 30
def initialize(root, definition)
  @root = root
  @definition = definition
  @post_install_messages = {}
end

Публичные методы экземпляра

generate_bundler_executable_stubs(spec, options = {}) Показать исходный код
# File lib/bundler/installer.rb, line 99
def generate_bundler_executable_stubs(spec, options = {})
  if options[:binstubs_cmd] && spec.executables.empty?
    options = {}
    spec.runtime_dependencies.each do |dep|
      bins = @definition.specs[dep].first.executables
      options[dep.name] = bins unless bins.empty?
    end
    if options.any?
      Bundler.ui.warn "#{spec.name} has no executables, but you may want " \
        "one from a gem it depends on."
      options.each {|name, bins| Bundler.ui.warn "  #{name} has: #{bins.join(", ")}" }
    else
      Bundler.ui.warn "There are no executables for the gem #{spec.name}."
    end
    return
  end

  # double-assignment to avoid warnings about variables that will be used by ERB
  bin_path = Bundler.bin_path
  bin_path = bin_path
  relative_gemfile_path = Bundler.default_gemfile.relative_path_from(bin_path)
  relative_gemfile_path = relative_gemfile_path
  ruby_command = Thor::Util.ruby_command
  ruby_command = ruby_command
  template_path = File.expand_path("../templates/Executable", __FILE__)
  if spec.name == "bundler"
    template_path += ".bundler"
    spec.executables = %(bundle)
  end
  template = File.read(template_path)

  exists = []
  spec.executables.each do |executable|
    binstub_path = "#{bin_path}/#{executable}"
    if File.exist?(binstub_path) && !options[:force]
      exists << executable
      next
    end

    File.open(binstub_path, "w", 0o777 & ~File.umask) do |f|
      if RUBY_VERSION >= "2.6"
        f.puts ERB.new(template, :trim_mode => "-").result(binding)
      else
        f.puts ERB.new(template, nil, "-").result(binding)
      end
    end
  end

  if options[:binstubs_cmd] && exists.any?
    case exists.size
    when 1
      Bundler.ui.warn "Skipped #{exists[0]} since it already exists."
    when 2
      Bundler.ui.warn "Skipped #{exists.join(" and ")} since they already exist."
    else
      items = exists[0...-1].empty? ? nil : exists[0...-1].join(", ")
      skipped = [items, exists[-1]].compact.join(" and ")
      Bundler.ui.warn "Skipped #{skipped} since they already exist."
    end
    Bundler.ui.warn "If you want to overwrite skipped stubs, use --force."
  end
end
generate_standalone_bundler_executable_stubs(spec) Показать исходный код
# File lib/bundler/installer.rb, line 162
def generate_standalone_bundler_executable_stubs(spec)
  # double-assignment to avoid warnings about variables that will be used by ERB
  bin_path = Bundler.bin_path
  unless path = Bundler.settings[:path]
    raise "Can't standalone without an explicit path set"
  end
  standalone_path = Bundler.root.join(path).relative_path_from(bin_path)
  standalone_path = standalone_path
  template = File.read(File.expand_path("../templates/Executable.standalone", __FILE__))
  ruby_command = Thor::Util.ruby_command
  ruby_command = ruby_command

  spec.executables.each do |executable|
    next if executable == "bundle"
    executable_path = Pathname(spec.full_gem_path).join(spec.bindir, executable).relative_path_from(bin_path)
    executable_path = executable_path
    File.open "#{bin_path}/#{executable}", "w", 0o755 do |f|
      if RUBY_VERSION >= "2.6"
        f.puts ERB.new(template, :trim_mode => "-").result(binding)
      else
        f.puts ERB.new(template, nil, "-").result(binding)
      end
    end
  end
end
run(options) Показать исходный код
# File lib/bundler/installer.rb, line 70
def run(options)
  create_bundle_path

  ProcessLock.lock do
    if Bundler.frozen_bundle?
      @definition.ensure_equivalent_gemfile_and_lockfile(options[:deployment])
    end

    if @definition.dependencies.empty?
      Bundler.ui.warn "The Gemfile specifies no dependencies"
      lock
      return
    end

    if resolve_if_needed(options)
      ensure_specs_are_compatible!
      warn_on_incompatible_bundler_deps
      load_plugins
      options.delete(:jobs)
    else
      options[:jobs] = 1 # to avoid the overhead of Bundler::Worker
    end
    install(options)

    lock unless Bundler.frozen_bundle?
    Standalone.new(options[:standalone], @definition).generate if options[:standalone]
  end
end

Выполняет процедуры установки для определённого Gemfile.

Сначала этот метод проверяет существование `Bundler.bundle_path`. Если его нет, то Bundler создаёт каталог. Это обычно та же директория, что и RubyGems, типичный путь - `~/.gem`, если не указано иное.

Во-вторых, он проверяет, настроен ли Bundler на «замораживание» («frozen»). Замораживание гарантирует, что Gemfile и Gemfile.lock совпадают. Это предотвращает ситуации, когда разработчик обновляет Gemfile, но не выполняет `bundle install`, что приводит к тому, что Gemfile.lock не обновляется правильно. Если этот файл не обновлён, любой другой разработчик, выполняющий `bundle install`, потенциально установит неверные gem'ы.

В-третьих, Bundler проверяет, есть ли зависимые компоненты, указанные в Gemfile. Если зависимостей нет, Bundler выводит предупреждение и метод завершает работу.

В-четвёртых, Bundler проверяет существование Gemfile.lock и, если оно есть, устанавливает определение на основе Gemfile и Gemfile.lock. На этом шаге Bundler также загрузит информацию о новых gem'ах, отсутствующих в Gemfile.lock, и, при необходимости, разрешит зависимости.

В-пятых, Bundler разрешает зависимости, либо из кэша gem'ов, либо удалённо. Затем происходит установка gem'ов, а также создание заглушек для их исполняемых файлов, только если опция –binstubs была передана или Bundler.options был установлен ранее.

В-шестых, создаётся новый Gemfile.lock на основе установленных gem'ов, чтобы при следующем запуске `bundle install` пользователь получал любые обновления из этого процесса.

Наконец, если пользователь указал флаг standalone, Bundler сгенерирует необходимые пути require и сохранит их в файле setup.rb. Для получения дополнительной информации см. `bundle standalone –help`.

Приватные методы экземпляра

can_install_in_parallel?() Показать исходный код
# File lib/bundler/installer.rb, line 277
def can_install_in_parallel?
  true
end
create_bundle_path() Показать исходный код
# File lib/bundler/installer.rb, line 288
def create_bundle_path
  SharedHelpers.filesystem_access(Bundler.bundle_path.to_s) do |p|
    Bundler.mkdir_p(p)
  end unless Bundler.bundle_path.exist?
rescue Errno::EEXIST
  raise PathError, "Could not install to path `#{Bundler.bundle_path}` " \
    "because a file already exists at that path. Either remove or rename the file so the directory can be created."
end
ensure_specs_are_compatible!() Показать исходный код
# File lib/bundler/installer.rb, line 243
def ensure_specs_are_compatible!
  system_ruby = Bundler::RubyVersion.system
  rubygems_version = Gem::Version.create(Gem::VERSION)
  @definition.specs.each do |spec|
    if required_ruby_version = spec.required_ruby_version
      unless required_ruby_version.satisfied_by?(system_ruby.gem_version)
        raise InstallError, "#{spec.full_name} requires ruby version #{required_ruby_version}, " \
          "which is incompatible with the current version, #{system_ruby}"
      end
    end
    next unless required_rubygems_version = spec.required_rubygems_version
    unless required_rubygems_version.satisfied_by?(rubygems_version)
      raise InstallError, "#{spec.full_name} requires rubygems version #{required_rubygems_version}, " \
        "which is incompatible with the current version, #{rubygems_version}"
    end
  end
end
install(options) Показать исходный код
# File lib/bundler/installer.rb, line 194
def install(options)
  force = options["force"]
  jobs = installation_parallelization(options)
  install_in_parallel jobs, options[:standalone], force
end

Порядок, предоставляемый решателем, важен, так как зависимости могут повлиять на установку gem. Однако это редкая ситуация (кроме rake), и параллельная установка намного быстрее. Поэтому мы позволяем людям выбирать.

install_in_parallel(size, standalone, force = false) Показать исходный код
# File lib/bundler/installer.rb, line 281
def install_in_parallel(size, standalone, force = false)
  spec_installations = ParallelInstaller.call(self, @definition.specs, size, standalone, force)
  spec_installations.each do |installation|
    post_install_messages[installation.name] = installation.post_install_message if installation.has_post_install_message?
  end
end
installation_parallelization(options) Показать исходный код
# File lib/bundler/installer.rb, line 200
def installation_parallelization(options)
  if jobs = options.delete(:jobs)
    return jobs
  end

  return 1 unless can_install_in_parallel?

  auto_config_jobs = Bundler.feature_flag.auto_config_jobs?
  if jobs = Bundler.settings[:jobs]
    if auto_config_jobs
      jobs
    else
      [jobs.pred, 1].max
    end
  elsif auto_config_jobs
    processor_count
  else
    1
  end
end
load_plugins() Показать исходный код
# File lib/bundler/installer.rb, line 228
def load_plugins
  Bundler.rubygems.load_plugins

  requested_path_gems = @definition.requested_specs.select {|s| s.source.is_a?(Source::Path) }
  path_plugin_files = requested_path_gems.map do |spec|
    begin
      Bundler.rubygems.spec_matches_for_glob(spec, "rubygems_plugin#{Bundler.rubygems.suffix_pattern}")
    rescue TypeError
      error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
      raise Gem::InvalidSpecificationException, error_message
    end
  end.flatten
  Bundler.rubygems.load_plugin_files(path_plugin_files)
end
lock(opts = {}) Показать исходный код
# File lib/bundler/installer.rb, line 307
def lock(opts = {})
  @definition.lock(Bundler.default_lockfile, opts[:preserve_unknown_sections])
end
processor_count() Показать исходный код
# File lib/bundler/installer.rb, line 221
def processor_count
  require "etc"
  Etc.nprocessors
rescue StandardError
  1
end
resolve_if_needed(options) Показать исходный код
# File lib/bundler/installer.rb, line 298
def resolve_if_needed(options)
  if !@definition.unlocking? && !options["force"] && !options["all-platforms"] && !Bundler.settings[:inline] && Bundler.default_lockfile.file?
    return false if @definition.nothing_changed? && !@definition.missing_specs?
  end

  options["local"] ? @definition.resolve_with_cache! : @definition.resolve_remotely!
  true
end

возвращает, нужно ли повторное разрешение

warn_on_incompatible_bundler_deps() Показать исходный код
# File lib/bundler/installer.rb, line 261
def warn_on_incompatible_bundler_deps
  bundler_version = Gem::Version.create(Bundler::VERSION)
  @definition.specs.each do |spec|
    spec.dependencies.each do |dep|
      next if dep.type == :development
      next unless dep.name == "bundler".freeze
      next if dep.requirement.satisfied_by?(bundler_version)

      Bundler.ui.warn "#{spec.name} (#{spec.version}) has dependency" \
        " #{SharedHelpers.pretty_dependency(dep)}" \
        ", which is unsatisfied by the current bundler version #{VERSION}" \
        ", so the dependency is being ignored"
    end
  end
end

Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API