module Gems::API::GemEndpoints

The gem endpoints, which look up, search for, push, and yank gems @api public

Public Instance Methods

Returns the names of gems matching the query, for populating a search box

@api public @authenticated false @param query [String] The query to autocomplete. @param page [Integer, nil] The page of names to return. @return [Array<String>] @example

Gems.autocomplete "nokogiri"

@example

Gems.autocomplete "nokogiri", page: 2
# File lib/gems/api/gem_endpoints.rb, line 78
def autocomplete(query, page: nil)
  parse_json(get("/api/v1/search/autocomplete", {query:, page:}.compact))
end

List all gems that you own, or that the given user owns

The gems of a user given by handle are public; the gems of the account the credentials belong to, which is what listing without a user asks for, are not.

@api public @authenticated true without a user, false with one @param user_handle [String, Integer, Owner, Profile, nil] The handle or ID of a user, or an owner or profile. @return [Array<Gem>] @example

Gems.owned_gems
# File lib/gems/api/gem_endpoints.rb, line 93
def owned_gems(user_handle = nil)
  path = if user_handle
    "/api/v1/owners/#{escape(slug_of(user_handle))}/gems.json"
  else
    "/api/v1/gems.json"
  end
  Gem.list(parse_json(get(path)))
end

Submit a gem to RubyGems.org or another host

@api public @authenticated true @param gem [String, Pathname, File] The path of a built gem, or the open file. @param host [String, nil] A RubyGems compatible host to use (defaults to the client’s host). @param attestations [Array<String, Pathname, File>, String, Pathname, File, nil] The paths of the

attestations to push, or the open files, one of either, or `nil`.

@return [String] the message the endpoint answers with @example

Gems.push "pkg/gemcutter-0.2.1.gem"

@example

Gems.push File.new("pkg/gemcutter-0.2.1.gem"), host: "https://gems.example.com"

@example

Gems.push "pkg/gemcutter-0.2.1.gem", attestations: "pkg/gemcutter-0.2.1.gem.sigstore.json"
# File lib/gems/api/gem_endpoints.rb, line 117
def push(gem, host: nil, attestations: nil)
  open_file(gem) do |file|
    body = attestations ? multipart_push_body(file, attestations) : file
    post("/api/v1/gems", body, host:)
  end
end

Returns an array of all the reverse dependencies to the given gem

@api public @authenticated false @param gem_name [String, Gem, Version] The name of a gem, or a gem or version @param only [String, Symbol, nil] Restrict the results to “development” or “runtime” dependencies, which

are the types {Dependency::TYPES} names.

@return [Array<String>] @raise [ArgumentError] if the type is not one the API defines @example

Gems.reverse_dependencies "money", only: "runtime"
# File lib/gems/api/gem_endpoints.rb, line 164
def reverse_dependencies(gem_name, only: nil)
  validate_type(only)
  parse_json(get("/api/v1/gems/#{escape(name_of(gem_name))}/reverse_dependencies.json", {only:}.compact))
end

Returns the full names of the versions that depend on the given gem

Where {#reverse_dependencies} names each gem that depends on the gem once, this names every indexed version of those gems that does, at every platform, such as “foreman-0.63.0-java”, with dependencies of both types.

@api public @authenticated false @param gem_name [String, Gem, Version] The name of a gem, or a gem or version @return [Array<String>] the full names of the versions @example

Gems.reverse_dependency_versions "dotenv"
# File lib/gems/api/gem_endpoints.rb, line 180
def reverse_dependency_versions(gem_name)
  parse_json(get("/api/v1/versions/#{escape(name_of(gem_name))}/reverse_dependencies.json"))
end

Returns some basic information about the given gem

@api public @authenticated false @param gem_name [String, Gem, Version] The name of a gem, or a gem or version. @return [Gem] @example

Gems.rubygem "rails"
# File lib/gems/api/gem_endpoints.rb, line 34
def rubygem(gem_name)
  Gem.new(parse_json(get("/api/v1/gems/#{escape(name_of(gem_name))}.json")))
end

Enumerates the active gems that match the query, a page at a time

A page is requested only when the gems of the page before it have been enumerated, and the enumeration ends with the first empty page.

@api public @authenticated false @param query [String] A term to search for. @yield [gem] each gem, when a block is given @return [Enumerator<Gem>] the gems @example

Gems.search_each("cucumber").first(100)
# File lib/gems/api/gem_endpoints.rb, line 63
def search_each(query, &block)
  each_page(block) { |page| search(query, page:) }
end

Remove a gem from RubyGems.org’s index

@api public @authenticated true @param gem_name [String, Gem, Version] The name of a gem, or a gem or version. A version stands in for the

version argument too, so that yanking a version yanks that version.

@param version [String, Version, nil] The version of a gem (defaults to the version given as the gem). There

is no default beyond that: a yank cannot be undone, so the version it removes is always named.

@param platform [String, nil] The platform of the gem; defaults to the platform of a version object. @param ruby_abi [String, nil] The Ruby ABI a version of the platform was built for, such as “3.4”; defaults to

the Ruby ABI of a version object, or to the version built for none.

@return [String] the message the endpoint answers with @raise [ArgumentError] if no version is given, as the version argument or as the gem @example

Gems.yank "gemcutter", "0.2.1", platform: "x86-darwin-10"

@example

Gems.yank "gemcutter", "0.2.1", platform: "x86_64-linux", ruby_abi: "3.4"

@example

Gems.yank Gems.version("gemcutter", "0.2.1")
# File lib/gems/api/gem_endpoints.rb, line 143
def yank(gem_name, version = nil, platform: nil, ruby_abi: nil)
  version = version_of(gem_name, version)
  platform ||= platform_of(version)
  ruby_abi ||= ruby_abi_of(version)
  number = number_of(version)
  raise ArgumentError, "No version of #{name_of(gem_name)} given to yank" if number.nil?

  delete("/api/v1/gems/yank", {gem_name: name_of(gem_name), version: number, platform:, ruby_abi:}.compact)
end