class HomebrewAutomation::Bintray::Client

A bare-bones Bintray API client that implements only the methods needed for Homebrew things.

Public Class Methods

new( username, api_key, http: RestClient, base_url: "https://bintray.com/api/v1" ) click to toggle source

@param username [String] Bintray username; for me this was not my email address @param api_key [String] Bearer-token-like key; generated in the Bintray web UI @param http [RestClient.Class] The RestClient class itself @param base_url [String] Include the https://; exclude the trailing slash.

# File lib/homebrew_automation/bintray/client.rb, line 20
def initialize(
    username,
    api_key,
    http: RestClient,
    base_url: "https://bintray.com/api/v1"
)
  @username = username
  @api_key = api_key
  @base_url = base_url
  @http = http  # allow injecting mocks for testing
end

Public Instance Methods

api_headers() click to toggle source

@return [Hash]

# File lib/homebrew_automation/bintray/client.rb, line 109
def api_headers
  { "Content-Type" => "application/json" }.update auth_headers
end
auth_headers() click to toggle source

Implement HTTP Basich Auth, as per RFC 7617.

Let's not bring in a library just for these two lines.

@return [Hash]

# File lib/homebrew_automation/bintray/client.rb, line 118
def auth_headers
  cred = Base64.strict_encode64("#{@username}:#{@api_key}")
  { Authorization: "Basic #{cred}" }
end
create_version(repo_name, package_name, version_name) click to toggle source

POST /packages/:subject/:repo/:package/versions

Redundant: Bintray seems to create nonexistant versions for you if you just try to upload files into it.

@param repo_name [String] @param package_name [String] @param version_name [String] @return [RestClient::Response]

# File lib/homebrew_automation/bintray/client.rb, line 41
def create_version(repo_name, package_name, version_name)
  safe_repo = URI.escape(repo_name)
  safe_pkg = URI.escape(package_name)
  @http.post(
    rel("/packages/#{safe_username}/#{safe_repo}/#{safe_pkg}/versions"),
    { name: version_name }.to_json,
    api_headers
  )
end
get_all_files_in_version(repo_name, package_name, version_name) click to toggle source

GET /packages/:subject/:repo/:package/versions/:version/files[?include_unpublished=0/1]

Useful when seeing what bottles have already been built.

@param repo_name [String] @param package_name [String] @param version_name [String] @return [RestClient::Response]

# File lib/homebrew_automation/bintray/client.rb, line 84
def get_all_files_in_version(repo_name, package_name, version_name)
  safe_repo = URI.escape(repo_name)
  safe_pkg = URI.escape(package_name)
  safe_ver = URI.escape(version_name)
  @http.get(
    rel("/packages/#{safe_username}/#{safe_repo}/#{safe_pkg}/versions/#{safe_ver}/files?include_unpublished=1"),
    auth_headers)
end
rel(slash_subpath) click to toggle source

Resolve a relative path into a URL using the current base_url

@param slash_subpath [String] @return [String]

# File lib/homebrew_automation/bintray/client.rb, line 104
def rel(slash_subpath)
  @base_url + slash_subpath
end
safe_username() click to toggle source

Bintray username, URI-escaped.

@return [String]

# File lib/homebrew_automation/bintray/client.rb, line 96
def safe_username
  URI.escape(@username)
end
upload_file(repo_name, package_name, version_name, filename, content, publish: 1) click to toggle source

PUT /content/:subject/:repo/:package/:version/:file_path[?publish=0/1][?override=0/1][?explode=0/1]

Bintray seems to expect the byte sequence of the file to be written straight out into the HTTP request body, optionally via Transfer-Encoding: chunked. So we pass the content String straight through to RestClient

@param repo_name [String] @param package_name [String] @param version_name [String] @param filename [String] The filename within one Bintray repository, e.g. hack-assembler-0.1.1.17.high_sierra.bottle.tar.gz @param content [String] The bytes for the file, e.g. from a File.read @return [RestClient::Response]

# File lib/homebrew_automation/bintray/client.rb, line 63
def upload_file(repo_name, package_name, version_name, filename, content, publish: 1)
  safe_repo = URI.escape(repo_name)
  safe_pkg = URI.escape(package_name)
  safe_ver = URI.escape(version_name)
  safe_filename = URI.escape(filename)
  safe_publish = URI.escape(publish.to_s)
  @http.put(
    rel("/content/#{safe_username}/#{safe_repo}/#{safe_pkg}/#{safe_ver}/#{safe_filename}?publish=#{safe_publish}"),
    content,
    auth_headers
  )
end