brew/Library/Homebrew/dev-cmd/pr-upload.rb

168 lines
5.8 KiB
Ruby
Raw Normal View History

2020-10-10 14:16:11 +02:00
# typed: false
2020-04-20 10:17:42 +02:00
# frozen_string_literal: true
require "cli/parser"
require "archive"
2020-04-20 10:17:42 +02:00
require "bintray"
module Homebrew
2020-10-20 12:03:48 +02:00
extend T::Sig
2020-04-20 10:17:42 +02:00
module_function
2020-10-20 12:03:48 +02:00
sig { returns(CLI::Parser) }
2020-04-20 10:17:42 +02:00
def pr_upload_args
Homebrew::CLI::Parser.new do
description <<~EOS
Apply the bottle commit and publish bottles to Bintray or GitHub Releases.
2020-04-20 10:17:42 +02:00
EOS
switch "--no-publish",
description: "Apply the bottle commit and upload the bottles, but don't publish them."
2020-07-06 17:41:07 +02:00
switch "--keep-old",
description: "If the formula specifies a rebuild version, " \
"attempt to preserve its value in the generated DSL."
2020-06-25 12:01:52 -04:00
switch "-n", "--dry-run",
2020-04-20 10:17:42 +02:00
description: "Print what would be done rather than doing it."
2020-10-03 12:33:47 -04:00
switch "--no-commit",
description: "Do not generate a new commit before uploading."
switch "--warn-on-upload-failure",
description: "Warn instead of raising an error if the bottle upload fails. "\
"Useful for repairing bottle uploads that previously failed."
flag "--archive-item=",
2021-02-23 11:22:55 -08:00
description: "Upload to the specified Internet Archive item (default: `homebrew`)."
2020-06-25 12:01:52 -04:00
flag "--bintray-org=",
description: "Upload to the specified Bintray organisation (default: `homebrew`)."
flag "--root-url=",
description: "Use the specified <URL> as the root of the bottle's URL instead of Homebrew's default."
2021-01-10 14:26:40 -05:00
named_args :none
2020-04-20 10:17:42 +02:00
end
end
def check_bottled_formulae(bottles_hash)
bottles_hash.each do |name, bottle_hash|
formula_path = HOMEBREW_REPOSITORY/bottle_hash["formula"]["path"]
2020-07-29 09:22:09 +02:00
formula_version = Formulary.factory(formula_path).pkg_version
bottle_version = PkgVersion.parse bottle_hash["formula"]["pkg_version"]
next if formula_version == bottle_version
odie "Bottles are for #{name} #{bottle_version} but formula is version #{formula_version}!"
end
end
def archive?(bottles_hash)
@archive ||= bottles_hash.values.all? do |bottle_hash|
bottle_hash["bottle"]["root_url"].start_with? "https://archive.org/"
end
end
def bintray?(bottles_hash)
@bintray ||= bottles_hash.values.all? do |bottle_hash|
bottle_hash["bottle"]["root_url"].match? %r{^https://[\w-]+\.bintray\.com/}
end
end
def github_releases?(bottles_hash)
@github_releases ||= bottles_hash.values.all? do |bottle_hash|
root_url = bottle_hash["bottle"]["root_url"]
url_match = root_url.match HOMEBREW_RELEASES_URL_REGEX
_, _, _, tag = *url_match
tag
end
end
2020-04-20 10:17:42 +02:00
def pr_upload
2020-07-23 01:22:25 +02:00
args = pr_upload_args.parse
2020-04-20 10:17:42 +02:00
2020-12-12 22:55:50 +01:00
json_files = Dir["*.bottle.json"]
odie "No bottle JSON files found in the current working directory" if json_files.empty?
bottles_hash = json_files.reduce({}) do |hash, json_file|
hash.deep_merge(JSON.parse(IO.read(json_file)))
end
bottle_args = ["bottle", "--merge", "--write"]
bottle_args << "--verbose" if args.verbose?
bottle_args << "--debug" if args.debug?
2020-07-06 17:41:07 +02:00
bottle_args << "--keep-old" if args.keep_old?
bottle_args << "--root-url=#{args.root_url}" if args.root_url
2020-10-03 12:33:47 -04:00
bottle_args << "--no-commit" if args.no_commit?
bottle_args += json_files
2020-04-20 10:17:42 +02:00
if args.dry_run?
service =
if archive?(bottles_hash)
2021-02-23 11:22:55 -08:00
"Internet Archive"
elsif bintray?(bottles_hash)
"Bintray"
elsif github_releases?(bottles_hash)
"GitHub Releases"
else
odie "Service specified by root_url is not recognized"
end
puts <<~EOS
brew #{bottle_args.join " "}
Upload bottles described by these JSON files to #{service}:
#{json_files.join("\n ")}
EOS
return
end
check_bottled_formulae(bottles_hash)
safe_system HOMEBREW_BREW_FILE, *bottle_args
# Check the bottle commits did not break `brew audit`
unless args.no_commit?
audit_args = ["audit", "--skip-style"]
audit_args << "--verbose" if args.verbose?
audit_args << "--debug" if args.debug?
2020-11-12 20:04:20 +01:00
audit_args += bottles_hash.keys
safe_system HOMEBREW_BREW_FILE, *audit_args
end
if archive?(bottles_hash)
2021-02-23 11:22:55 -08:00
# Handle uploading to the Internet Archive.
archive_item = args.archive_item || "homebrew"
archive = Archive.new(item: archive_item)
archive.upload_bottles(bottles_hash,
warn_on_error: args.warn_on_upload_failure?)
elsif bintray?(bottles_hash)
# Handle uploading to Bintray.
bintray_org = args.bintray_org || "homebrew"
bintray = Bintray.new(org: bintray_org)
bintray.upload_bottles(bottles_hash,
publish_package: !args.no_publish?,
warn_on_error: args.warn_on_upload_failure?)
elsif github_releases?(bottles_hash)
# Handle uploading to GitHub Releases.
bottles_hash.each_value do |bottle_hash|
root_url = bottle_hash["bottle"]["root_url"]
url_match = root_url.match HOMEBREW_RELEASES_URL_REGEX
_, user, repo, tag = *url_match
# Ensure a release is created.
release = begin
rel = GitHub.get_release user, repo, tag
odebug "Existing GitHub release \"#{tag}\" found"
rel
2021-02-15 21:48:21 +05:30
rescue GitHub::API::HTTPNotFoundError
odebug "Creating new GitHub release \"#{tag}\""
GitHub.create_or_update_release user, repo, tag
end
# Upload bottles as release assets.
bottle_hash["bottle"]["tags"].each_value do |tag_hash|
remote_file = tag_hash["filename"]
local_file = tag_hash["local_filename"]
odebug "Uploading #{remote_file}"
GitHub.upload_release_asset user, repo, release["id"], local_file: local_file, remote_file: remote_file
end
end
2020-04-20 10:17:42 +02:00
else
odie "Service specified by root_url is not recognized"
2020-04-20 10:17:42 +02:00
end
end
end