Module: Gems::API::VersionEndpoints

Included in:
Gems::API
Defined in:
lib/gems/api/version_endpoints.rb

Overview

The version endpoints, which look up the versions of a gem

Instance Method Summary collapse

Instance Method Details

#attestations(gem_name, version = nil, platform: nil) ⇒ Array<Hash>

Returns the sigstore attestations published with a gem version

Examples:

Gems.attestations("rails", "8.1.3.1").first["mediaType"]
Gems.attestations "nokogiri", "1.15.0", platform: "java"
Gems.attestations Gems.rubygem("rails")

Parameters:

  • gem_name (String, Gem, Version) —

    The name of a gem, or a gem or version. A gem or version stands in for the version argument too, so that reading the attestations of a version reads that version.

  • version (String, Version, Gem, nil) (defaults to: nil) —

    The requested version of the gem (defaults to the version given as the gem, or to the latest version).

  • platform (String, nil) (defaults to: nil) —

    The platform of the version, such as "java" or "x86_64-linux"; defaults to the platform of a gem or version object, or "ruby".

Returns:

  • (Array<Hash>) —

    the sigstore bundles, empty for versions pushed without attestations

Raises:

  • (NoLatestVersion) —

    if no version is given and the gem has no published version

  • (ArgumentError) —

    if the version was built for a Ruby ABI, which the endpoint looks up by a full name RubyGems.org answers with only for the versions DownloadEndpoints#most_downloaded returns

Requires Authentication:

  • false



126
127
128
129
# File 'lib/gems/api/version_endpoints.rb', line 126

def attestations(gem_name, version = nil, platform: nil)
  version = version_of(gem_name, version) || latest_version(gem_name)
  parse_json(get("/api/v1/attestations/#{escape(full_name_of(gem_name, version, platform))}.json"))
end

#contents(gem_name, version = nil, platform: nil, ruby_abi: nil) ⇒ Hash{String => Hash{String => String}}

Returns the SHA-256 checksum of every file packaged in a specific gem version

Only versions pushed after RubyGems.org started recording file manifests have this data.

Examples:

Gems.contents("rails", "8.1.3.1")["README.md"]["sha256"]
Gems.contents Gems.rubygem("rails")

Parameters:

  • gem_name (String, Gem, Version) —

    The name of a gem, or a gem or version. A gem or version stands in for the version argument too, so that reading the contents of a version reads that version.

  • version (String, Version, Gem, nil) (defaults to: nil) —

    The requested version of the gem (defaults to the version given as the gem, or to the latest version).

  • platform (String, nil) (defaults to: nil) —

    The platform of the version, such as "java" or "x86_64-linux"; defaults to the platform of a gem or version object, or "ruby".

  • ruby_abi (String, nil) (defaults to: nil) —

    The Ruby ABI a version of the platform was built for, such as "3.4"; defaults to the Ruby ABI of a gem or version object, or to the version built for none.

Returns:

  • (Hash{String => Hash{String => String}}) —

    the checksums of each file, keyed by path

Raises:

  • (NoLatestVersion) —

    if no version is given and the gem has no published version

Requires Authentication:

  • false



99
100
101
102
103
104
# File 'lib/gems/api/version_endpoints.rb', line 99

def contents(gem_name, version = nil, platform: nil, ruby_abi: nil)
  version = version_of(gem_name, version)
  number = number_of(version) || latest_version(gem_name)
  path = "/api/v2/rubygems/#{escape(name_of(gem_name))}/versions/#{escape(number)}/contents.json"
  parse_json(get(path, build_params(version, platform, ruby_abi)))
end

#latest_version(gem_name) ⇒ String

Returns the latest version number of a gem

Examples:

Gems.latest_version "coulda"

Parameters:

  • gem_name (String, Gem, Version) —

    The name of a gem, or a gem or version.

Returns:

  • (String) —

    the latest version number

Raises:

Requires Authentication:

  • false



43
44
45
46
47
48
49
50
# File 'lib/gems/api/version_endpoints.rb', line 43

def latest_version(gem_name)
  response = get("/api/v1/versions/#{escape(name_of(gem_name))}/latest.json")
  version = parse_json(response) { |json| json.fetch("version") }
  # The endpoint answers 200 with "unknown" rather than 404 for a gem with no published version
  raise NoLatestVersion, "#{name_of(gem_name)} has no latest version" if version.eql?("unknown")

  version
end

#timeframe_versions(from:, to: nil, page: nil) ⇒ Array<Gem>

Returns the gem versions created within a timeframe of up to seven days

The results are paginated, 30 versions at a time; use the page option until an empty list is returned.

Examples:

Gems.timeframe_versions from: Time.now - 86_400

Parameters:

  • from (Time, String) —

    The start of the timeframe, as a Time or an ISO 8601 string.

  • to (Time, String, nil) (defaults to: nil) —

    The end of the timeframe; defaults to now.

  • page (Integer, nil) (defaults to: nil) —

    The page of results to return.

Returns:

Requires Authentication:

  • false



143
144
145
146
# File 'lib/gems/api/version_endpoints.rb', line 143

def timeframe_versions(from:, to: nil, page: nil)
  params = {from: timestamp_of(from), to: timestamp_of(to), page:}.compact
  Gem.list(parse_json(get("/api/v1/timeframe_versions.json", params)))
end

#timeframe_versions_each(from:, to: nil) {|gem| ... } ⇒ Enumerator<Gem>

Enumerates the gem versions created within a timeframe, a page at a time

The timeframe may span up to seven days. A page is requested only when the versions of the page before it have been enumerated, and the enumeration ends with the first empty page.

Examples:

Gems.timeframe_versions_each(from: Time.now - 86_400).count

Parameters:

  • from (Time, String) —

    The start of the timeframe, as a Time or an ISO 8601 string.

  • to (Time, String, nil) (defaults to: nil) —

    The end of the timeframe; defaults to now.

Yields:

  • (gem) —

    each version, when a block is given

Returns:

  • (Enumerator<Gem>) —

    the versions

Requires Authentication:

  • false



161
162
163
# File 'lib/gems/api/version_endpoints.rb', line 161

def timeframe_versions_each(from:, to: nil, &block)
  each_page(block) { |page| timeframe_versions(from:, to:, page:) }
end

#version(gem_name, version = nil, platform: nil, ruby_abi: nil) ⇒ Version

Returns information about the given gem for a specific version

Examples:

Gems.version "rails", "7.0.6"
Gems.version "nokogiri", "1.15.0", platform: "java"
Gems.version Gems.rubygem("rails")

Parameters:

  • gem_name (String, Gem, Version) —

    The name of a gem, or a gem or version. A gem or version stands in for the version argument too, so that reading a version reads that version.

  • version (String, Version, Gem, nil) (defaults to: nil) —

    The requested version of the gem (defaults to the version given as the gem, or to the latest version).

  • platform (String, nil) (defaults to: nil) —

    The platform of the version, such as "java" or "x86_64-linux"; defaults to the platform of a gem or version object, or "ruby".

  • ruby_abi (String, nil) (defaults to: nil) —

    The Ruby ABI a version of the platform was built for, such as "3.4"; defaults to the Ruby ABI of a gem or version object, or to the version built for none.

Returns:

Raises:

  • (NoLatestVersion) —

    if no version is given and the gem has no published version

Requires Authentication:

  • false



72
73
74
75
76
77
# File 'lib/gems/api/version_endpoints.rb', line 72

def version(gem_name, version = nil, platform: nil, ruby_abi: nil)
  version = version_of(gem_name, version)
  number = number_of(version) || latest_version(gem_name)
  path = "/api/v2/rubygems/#{escape(name_of(gem_name))}/versions/#{escape(number)}.json"
  Version.new(parse_json(get(path, build_params(version, platform, ruby_abi))))
end

#versions(gem_name) ⇒ Array<Version>

Returns an array of gem version details

Examples:

Gems.versions "coulda"

Parameters:

  • gem_name (String, Gem, Version) —

    The name of a gem, or a gem or version.

Returns:

Requires Authentication:

  • false



29
30
31
32
# File 'lib/gems/api/version_endpoints.rb', line 29

def versions(gem_name)
  name = name_of(gem_name)
  Version.list(parse_json(get("/api/v1/versions/#{escape(name)}.json")).map { |version| version.merge("name" => name) })
end