# class Bundler::Fetcher::CompactIndex

### Constants

ClientFetcher

### Public Class Methods

compact_index_request(method_name) click to toggle source

    # File lib/bundler/fetcher/compact_index.rb, line 11
    def self.compact_index_request(method_name)
      method = instance_method(method_name)
      undef_method(method_name)
      define_method(method_name) do |*args, &blk|
        begin
          method.bind(self).call(*args, &blk)
        rescue NetworkDownError, CompactIndexClient::Updater::MisMatchedChecksumError => e
          raise HTTPError, e.message
        rescue AuthenticationRequiredError
          # Fail since we got a 401 from the server.
          raise
        rescue HTTPError => e
          Bundler.ui.trace(e)
          nil
        end
      end
    end

### Public Instance Methods

api_fetcher?() click to toggle source

    # File lib/bundler/fetcher/compact_index.rb, line 76
    def api_fetcher?
      true
    end

available?() click to toggle source

    # File lib/bundler/fetcher/compact_index.rb, line 64
    def available?
      return nil unless SharedHelpers.md5_available?
      user_home = Bundler.user_home
      return nil unless user_home.directory? && user_home.writable?
      # Read info file checksums out of /versions, so we can know if gems are up to date
      fetch_uri.scheme != "file" && compact_index_client.update_and_parse_checksums!
    rescue CompactIndexClient::Updater::MisMatchedChecksumError => e
      Bundler.ui.debug(e.message)
      nil
    end

fetch_spec(spec) click to toggle source

    # File lib/bundler/fetcher/compact_index.rb, line 54
    def fetch_spec(spec)
      spec -= [nil, "ruby", ""]
      contents = compact_index_client.spec(*spec)
      return nil if contents.nil?
      contents.unshift(spec.first)
      contents[3].map! {|d| Gem::Dependency.new(*d) }
      EndpointSpecification.new(*contents)
    end

specs(gem_names) click to toggle source

    # File lib/bundler/fetcher/compact_index.rb, line 29
    def specs(gem_names)
      specs_for_names(gem_names)
    end

specs_for_names(gem_names) click to toggle source

    # File lib/bundler/fetcher/compact_index.rb, line 34
    def specs_for_names(gem_names)
      gem_info = []
      complete_gems = []
      remaining_gems = gem_names.dup

      until remaining_gems.empty?
        log_specs "Looking up gems #{remaining_gems.inspect}"

        deps = compact_index_client.dependencies(remaining_gems)
        next_gems = deps.map {|d| d[3].map(&:first).flatten(1) }.flatten(1).uniq
        deps.each {|dep| gem_info << dep }
        complete_gems.concat(deps.map(&:first)).uniq!
        remaining_gems = next_gems - complete_gems
      end
      @bundle_worker.stop if @bundle_worker
      @bundle_worker = nil # reset it.  Not sure if necessary

      gem_info
    end

### Private Instance Methods

bundle_worker(func = nil) click to toggle source

    # File lib/bundler/fetcher/compact_index.rb, line 97
    def bundle_worker(func = nil)
      @bundle_worker ||= begin
        worker_name = "Compact Index (#{display_uri.host})"
        Bundler::Worker.new(Bundler.current_ruby.rbx? ? 1 : 25, worker_name, func)
      end
      @bundle_worker.tap do |worker|
        worker.instance_variable_set(:@func, func) if func
      end
    end

cache_path() click to toggle source

    # File lib/bundler/fetcher/compact_index.rb, line 107
    def cache_path
      Bundler.user_cache.join("compact_index", remote.cache_slug)
    end

client_fetcher() click to toggle source

    # File lib/bundler/fetcher/compact_index.rb, line 111
    def client_fetcher
      ClientFetcher.new(self, Bundler.ui)
    end

compact_index_client() click to toggle source

    # File lib/bundler/fetcher/compact_index.rb, line 82
    def compact_index_client
      @compact_index_client ||= begin
        SharedHelpers.filesystem_access(cache_path) do
          CompactIndexClient.new(cache_path, client_fetcher)
        end.tap do |client|
          client.in_parallel = lambda do |inputs, &blk|
            func = lambda {|object, _index| blk.call(object) }
            worker = bundle_worker(func)
            inputs.each {|input| worker.enq(input) }
            inputs.map { worker.deq }
          end
        end
      end
    end