brew/Library/Homebrew/bintray.rb

150 lines
5.1 KiB
Ruby
Raw Normal View History

2020-03-30 19:35:54 +11:00
# frozen_string_literal: true
require "utils/curl"
require "json"
class Bintray
API_URL = "https://api.bintray.com"
class Error < RuntimeError
end
def inspect
"#<Bintray: user=#{@bintray_user} org=#{@bintray_org} key=***>"
end
def initialize(user: ENV["HOMEBREW_BINTRAY_USER"], key: ENV["HOMEBREW_BINTRAY_KEY"], org: "homebrew", clear: true)
@bintray_user = user
@bintray_key = key
@bintray_org = org
2020-03-30 19:35:54 +11:00
if !@bintray_user || !@bintray_key
unless Homebrew.args.dry_run?
raise UsageError, "Missing HOMEBREW_BINTRAY_USER or HOMEBREW_BINTRAY_KEY variables!"
end
2020-03-30 19:35:54 +11:00
end
raise UsageError, "Must set a Bintray organisation!" unless @bintray_org
2020-03-30 19:35:54 +11:00
ENV["HOMEBREW_FORCE_HOMEBREW_ON_LINUX"] = "1" if @bintray_org == "homebrew" && !OS.mac?
ENV.delete "HOMEBREW_BINTRAY_KEY" if clear
2020-03-30 19:35:54 +11:00
end
def open_api(url, *extra_curl_args, auth: true)
args = extra_curl_args
args += ["--user", "#{@bintray_user}:#{@bintray_key}"] if auth
args += ["--output", "/dev/null"] unless Homebrew.args.verbose?
2020-03-30 19:35:54 +11:00
curl(*args, url,
show_output: Homebrew.args.verbose?,
secrets: @bintray_key)
end
def upload(local_file, repo:, package:, version:, remote_file:, sha256: nil)
url = "#{API_URL}/content/#{@bintray_org}/#{repo}/#{package}/#{version}/#{remote_file}"
args = ["--upload-file", local_file]
args += ["--header", "X-Checksum-Sha2: #{sha256}"] unless sha256.blank?
open_api url, *args
end
def publish(repo:, package:, version:)
url = "#{API_URL}/content/#{@bintray_org}/#{repo}/#{package}/#{version}/publish"
open_api url, "--request", "POST"
end
def official_org?(org: @bintray_org)
%w[homebrew linuxbrew].include? org
end
def create_package(repo:, package:, **extra_data_args)
2020-04-21 14:21:34 +01:00
url = "#{API_URL}/packages/#{@bintray_org}/#{repo}"
2020-03-30 19:35:54 +11:00
data = { name: package, public_download_numbers: true }
data[:public_stats] = official_org?
data.merge! extra_data_args
2020-04-21 14:21:34 +01:00
open_api url, "--header", "Content-Type: application/json", "--request", "POST", "--data", data.to_json
2020-03-30 19:35:54 +11:00
end
def package_exists?(repo:, package:)
url = "#{API_URL}/packages/#{@bintray_org}/#{repo}/#{package}"
2020-04-21 14:21:34 +01:00
begin
open_api url, "--fail", "--silent", auth: false
2020-04-21 14:21:34 +01:00
rescue ErrorDuringExecution => e
2020-04-22 19:23:41 +01:00
stderr = e.output
.select { |type,| type == :stderr }
2020-04-21 14:21:34 +01:00
.map { |_, line| line }
.join
raise if e.status.exitstatus != 22 && !stderr.include?("404 Not Found")
false
else
true
end
2020-03-30 19:35:54 +11:00
end
def file_published?(repo:, remote_file:)
url = "https://dl.bintray.com/#{@bintray_org}/#{repo}/#{remote_file}"
begin
curl "--fail", "--silent", "--head", "--output", "/dev/null", url
2020-03-30 19:35:54 +11:00
rescue ErrorDuringExecution => e
2020-04-22 19:23:41 +01:00
stderr = e.output
.select { |type,| type == :stderr }
2020-03-30 19:35:54 +11:00
.map { |_, line| line }
.join
raise if e.status.exitstatus != 22 && !stderr.include?("404 Not Found")
false
else
true
end
end
def upload_bottle_json(json_files, publish_package: false)
bottles_hash = json_files.reduce({}) do |hash, json_file|
hash.deep_merge(JSON.parse(IO.read(json_file)))
end
formula_packaged = {}
bottles_hash.each do |formula_name, bottle_hash|
2020-05-10 00:30:32 +01:00
version = ERB::Util.url_encode(bottle_hash["formula"]["pkg_version"])
2020-03-30 19:35:54 +11:00
bintray_package = bottle_hash["bintray"]["package"]
bintray_repo = bottle_hash["bintray"]["repository"]
bottle_hash["bottle"]["tags"].each do |_tag, tag_hash|
2020-05-10 00:30:32 +01:00
filename = tag_hash["filename"] # URL encoded in Bottle::Filename#bintray
2020-03-30 19:35:54 +11:00
sha256 = tag_hash["sha256"]
odebug "Checking remote file #{@bintray_org}/#{bintray_repo}/#{filename}"
2020-03-30 19:35:54 +11:00
if file_published? repo: bintray_repo, remote_file: filename
raise Error, <<~EOS
#{filename} is already published.
Please remove it manually from:
https://bintray.com/#{@bintray_org}/#{bintray_repo}/#{bintray_package}/view#files
Or run:
curl -X DELETE -u $HOMEBREW_BINTRAY_USER:$HOMEBREW_BINTRAY_KEY \\
https://api.bintray.com/content/#{@bintray_org}/#{bintray_repo}/#{filename}
EOS
end
if !formula_packaged[formula_name] && !package_exists?(repo: bintray_repo, package: bintray_package)
2020-04-21 14:21:34 +01:00
odebug "Creating package #{@bintray_org}/#{bintray_repo}/#{bintray_package}"
2020-03-30 19:35:54 +11:00
create_package repo: bintray_repo, package: bintray_package
formula_packaged[formula_name] = true
end
2020-05-10 00:30:32 +01:00
odebug "Uploading #{@bintray_org}/#{bintray_repo}/#{bintray_package}/#{version}/#{filename}"
2020-03-30 19:35:54 +11:00
upload(tag_hash["local_filename"],
repo: bintray_repo,
package: bintray_package,
version: version,
remote_file: filename,
sha256: sha256)
end
if publish_package
odebug "Publishing #{@bintray_org}/#{bintray_repo}/#{bintray_package}/#{version}"
publish repo: bintray_repo, package: bintray_package, version: version
end
2020-03-30 19:35:54 +11:00
end
end
end