123456789_123456789_123456789_123456789_123456789_

Class: Gem::Resolver::APISpecification

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
Instance Chain:
Inherits: Gem::Resolver::Specification
Defined in: lib/rubygems/resolver/api_specification.rb

Overview

Represents a specification retrieved via the Compact Index API.

This is used to avoid loading the full Specification object when all we need is the name, version, and dependencies.

Class Method Summary

Specification - Inherited

.new

Sets default instance variables for the specification.

Instance Attribute Summary

Specification - Inherited

#content_address

The content address of this specification.

#created_at

The time this gem version was published, when the source provides it (compact index v2), nil otherwise.

#dependencies

The dependencies of the gem for this specification.

#installable_platform?

Returns true if this specification is installable on this platform.

#name

The name of the gem for this specification.

#platform

The platform this gem works on.

#required_ruby_version

The required_ruby_version constraint for this specification.

#required_rubygems_version

The required_ruby_version constraint for this specification.

#set

The set this specification came from.

#source

The source for this specification.

#spec
#version

The version of the gem for this specification.

#local?

Instance Method Summary

Specification - Inherited

#download,
#full_name

The name and version of the specification.

#install

Installs this specification using the ::Gem::Installer options.

#fetch_development_dependencies

Fetches development dependencies if the source does not provide them by default (see APISpecification).

Constructor Details

.new(set, api_data) ⇒ APISpecification

[ GitHub ]

  
# File 'lib/rubygems/resolver/api_specification.rb', line 16

def self.new(set, api_data)
  cache_key = [set, api_data]
  cache = @@cache[cache_key]
  return cache if cache
  @@cache[cache_key] = super
end

#initialize(set, api_data) ⇒ APISpecification

Creates an APISpecification for the given set from the Compact Index API api_data.

See https://guides.rubygems.org/rubygems-org-compact-index-api for the format of the api_data.

[ GitHub ]

  
# File 'lib/rubygems/resolver/api_specification.rb', line 30

def initialize(set, api_data)
  super()

  @set = set
  @name = api_data[:name]
  @version = Gem::Version.new(api_data[:number]).freeze
  @dependencies = api_data[:dependencies].map do |name, ver|
    Gem::Dependency.new(name, ver.split(/\s*,\s*/)).freeze
  end.freeze
  @required_ruby_version = Gem::Requirement.new(api_data.dig(:requirements, :ruby)).freeze
  @required_rubygems_version = Gem::Requirement.new(api_data.dig(:requirements, :rubygems)).freeze
  @created_at = parse_created_at(api_data.dig(:requirements, :created_at))&.freeze
  assign_platform(api_data)
end

Instance Attribute Details

#installable_platform?Boolean (readonly)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/resolver/api_specification.rb', line 65

def installable_platform? # :nodoc:
  Gem::Platform.match_gem? @platform, @name
end

Instance Method Details

#==(other)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/resolver/api_specification.rb', line 45

def ==(other) # :nodoc:
  self.class === other &&
    @set          == other.set &&
    @name         == other.name &&
    @version      == other.version &&
    @platform     == other.platform &&
    @content_address == other.content_address
end

#assign_platform(api_data) (private)

[ GitHub ]

  
# File 'lib/rubygems/resolver/api_specification.rb', line 119

def assign_platform(api_data)
  suffix = api_data[:suffix]
  required_platform = required_platform_from(api_data.dig(:requirements, :platform))

  if Gem::ContentAddress.content_addressed_row?(suffix, required_platform, @required_ruby_version)
    @content_address = suffix.freeze
    @platform = required_platform.freeze
    @original_platform = required_platform.to_s.freeze
  else
    @content_address = nil
    @platform = Gem::Platform.new(suffix).freeze
    @original_platform = suffix.freeze
  end
end

#fetch_development_dependencies

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/resolver/api_specification.rb', line 58

def fetch_development_dependencies # :nodoc:
  suffix = @content_address || @platform
  spec = source.fetch_spec Gem::NameTuple.new @name, @version, suffix

  @dependencies = spec.dependencies
end

#hash

[ GitHub ]

  
# File 'lib/rubygems/resolver/api_specification.rb', line 54

def hash
  @set.hash ^ @name.hash ^ @version.hash ^ @platform.hash ^ @content_address.hash
end

#parse_created_at(value) (private)

[ GitHub ]

  
# File 'lib/rubygems/resolver/api_specification.rb', line 141

def parse_created_at(value)
  value = value.first if value.is_a?(Array)

  Gem::Cooldown.parse_created_at(value)
end

#pretty_print(q)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/resolver/api_specification.rb', line 69

def pretty_print(q) # :nodoc:
  q.group 2, "[APISpecification", "]" do
    q.breakable
    q.text "name: #{name}"

    q.breakable
    q.text "version: #{version}"

    q.breakable
    q.text "platform: #{platform}"

    q.breakable
    q.text "dependencies:"
    q.breakable
    q.pp @dependencies

    q.breakable
    q.text "set uri: #{@set.dep_uri}"
  end
end

#required_platform_from(requirement) (private)

[ GitHub ]

  
# File 'lib/rubygems/resolver/api_specification.rb', line 134

def required_platform_from(requirement)
  platform = Array(requirement).last
  return if platform.nil? || platform.empty?

  Gem::Platform.new(platform)
end

#source

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/resolver/api_specification.rb', line 113

def source # :nodoc:
  @set.source
end

#spec

This method is for internal use only.

A ::Gem::Specification stub built from the Compact Index data for this specification. The compact index carries everything needed to download and install the gem, so the Marshal gemspec is not fetched. Development dependencies are not included; see #fetch_development_dependencies.

[ GitHub ]

  
# File 'lib/rubygems/resolver/api_specification.rb', line 97

def spec # :nodoc:
  @spec ||= Gem::Specification.new do |s|
    s.name     = @name
    s.version  = @version
    s.platform = @platform
    s.original_platform = @original_platform
    s.required_ruby_version = @required_ruby_version
    s.required_rubygems_version = @required_rubygems_version
    s.content_address = @content_address

    @dependencies.each do |dependency|
      s.add_runtime_dependency dependency.name, *dependency.requirement.as_list
    end
  end
end