Merge pull request #2848 from reitermarkus/refactoring
Refactor SVN and cURL download strategies.
This commit is contained in:
commit
6ef49d8b86
@ -143,7 +143,15 @@ module Hbc
|
|||||||
|
|
||||||
def check_appcast_http_code
|
def check_appcast_http_code
|
||||||
odebug "Verifying appcast returns 200 HTTP response code"
|
odebug "Verifying appcast returns 200 HTTP response code"
|
||||||
result = @command.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", URL::FAKE_USER_AGENT, "--output", "/dev/null", "--write-out", "%{http_code}", cask.appcast], print_stderr: false)
|
|
||||||
|
curl_executable, *args = curl_args(
|
||||||
|
"--compressed", "--location", "--fail",
|
||||||
|
"--write-out", "%{http_code}",
|
||||||
|
"--output", "/dev/null",
|
||||||
|
cask.appcast,
|
||||||
|
user_agent: :fake
|
||||||
|
)
|
||||||
|
result = @command.run(curl_executable, args: args, print_stderr: false)
|
||||||
if result.success?
|
if result.success?
|
||||||
http_code = result.stdout.chomp
|
http_code = result.stdout.chomp
|
||||||
add_warning "unexpected HTTP response code retrieving appcast: #{http_code}" unless http_code == "200"
|
add_warning "unexpected HTTP response code retrieving appcast: #{http_code}" unless http_code == "200"
|
||||||
|
|||||||
@ -71,7 +71,7 @@ module Hbc
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
ohai "Downloading #{url}."
|
ohai "Downloading #{url}."
|
||||||
curl url, "-o", path
|
curl_download url, to: path
|
||||||
rescue ErrorDuringExecution
|
rescue ErrorDuringExecution
|
||||||
raise CaskUnavailableError.new(token, "Failed to download #{Formatter.url(url)}.")
|
raise CaskUnavailableError.new(token, "Failed to download #{Formatter.url(url)}.")
|
||||||
end
|
end
|
||||||
|
|||||||
@ -4,6 +4,7 @@ require "hbc/container/bzip2"
|
|||||||
require "hbc/container/cab"
|
require "hbc/container/cab"
|
||||||
require "hbc/container/criteria"
|
require "hbc/container/criteria"
|
||||||
require "hbc/container/dmg"
|
require "hbc/container/dmg"
|
||||||
|
require "hbc/container/directory"
|
||||||
require "hbc/container/executable"
|
require "hbc/container/executable"
|
||||||
require "hbc/container/generic_unar"
|
require "hbc/container/generic_unar"
|
||||||
require "hbc/container/gpg"
|
require "hbc/container/gpg"
|
||||||
@ -14,6 +15,7 @@ require "hbc/container/otf"
|
|||||||
require "hbc/container/pkg"
|
require "hbc/container/pkg"
|
||||||
require "hbc/container/seven_zip"
|
require "hbc/container/seven_zip"
|
||||||
require "hbc/container/sit"
|
require "hbc/container/sit"
|
||||||
|
require "hbc/container/svn_repository"
|
||||||
require "hbc/container/tar"
|
require "hbc/container/tar"
|
||||||
require "hbc/container/ttf"
|
require "hbc/container/ttf"
|
||||||
require "hbc/container/rar"
|
require "hbc/container/rar"
|
||||||
@ -43,6 +45,7 @@ module Hbc
|
|||||||
Xz, # pure xz
|
Xz, # pure xz
|
||||||
Gpg, # GnuPG signed data
|
Gpg, # GnuPG signed data
|
||||||
Executable,
|
Executable,
|
||||||
|
SvnRepository,
|
||||||
]
|
]
|
||||||
# for explicit use only (never autodetected):
|
# for explicit use only (never autodetected):
|
||||||
# Hbc::Container::Naked
|
# Hbc::Container::Naked
|
||||||
|
|||||||
@ -13,9 +13,11 @@ module Hbc
|
|||||||
end
|
end
|
||||||
|
|
||||||
def magic_number(regex)
|
def magic_number(regex)
|
||||||
|
return false if path.directory?
|
||||||
|
|
||||||
# 262: length of the longest regex (currently: Hbc::Container::Tar)
|
# 262: length of the longest regex (currently: Hbc::Container::Tar)
|
||||||
@magic_number ||= File.open(@path, "rb") { |f| f.read(262) }
|
@magic_number ||= File.open(path, "rb") { |f| f.read(262) }
|
||||||
@magic_number =~ regex
|
@magic_number.match?(regex)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
24
Library/Homebrew/cask/lib/hbc/container/directory.rb
Normal file
24
Library/Homebrew/cask/lib/hbc/container/directory.rb
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
require "hbc/container/base"
|
||||||
|
|
||||||
|
module Hbc
|
||||||
|
class Container
|
||||||
|
class Directory < Base
|
||||||
|
def self.me?(*)
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def extract
|
||||||
|
@path.children.each do |child|
|
||||||
|
next if skip_path?(child)
|
||||||
|
FileUtils.cp child, @cask.staged_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def skip_path?(*)
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -8,7 +8,7 @@ module Hbc
|
|||||||
return true if criteria.magic_number(/^#!\s*\S+/)
|
return true if criteria.magic_number(/^#!\s*\S+/)
|
||||||
|
|
||||||
begin
|
begin
|
||||||
MachO.open(criteria.path).header.executable?
|
criteria.path.file? && MachO.open(criteria.path).header.executable?
|
||||||
rescue MachO::MagicError
|
rescue MachO::MagicError
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|||||||
15
Library/Homebrew/cask/lib/hbc/container/svn_repository.rb
Normal file
15
Library/Homebrew/cask/lib/hbc/container/svn_repository.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
require "hbc/container/directory"
|
||||||
|
|
||||||
|
module Hbc
|
||||||
|
class Container
|
||||||
|
class SvnRepository < Directory
|
||||||
|
def self.me?(criteria)
|
||||||
|
criteria.path.join(".svn").directory?
|
||||||
|
end
|
||||||
|
|
||||||
|
def skip_path?(path)
|
||||||
|
path.basename.to_s == ".svn"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -10,7 +10,7 @@ module Hbc
|
|||||||
class AbstractDownloadStrategy
|
class AbstractDownloadStrategy
|
||||||
attr_reader :cask, :name, :url, :uri_object, :version
|
attr_reader :cask, :name, :url, :uri_object, :version
|
||||||
|
|
||||||
def initialize(cask, command = SystemCommand)
|
def initialize(cask, command: SystemCommand)
|
||||||
@cask = cask
|
@cask = cask
|
||||||
@command = command
|
@command = command
|
||||||
# TODO: this excess of attributes is a function of integrating
|
# TODO: this excess of attributes is a function of integrating
|
||||||
@ -33,8 +33,8 @@ module Hbc
|
|||||||
class HbVCSDownloadStrategy < AbstractDownloadStrategy
|
class HbVCSDownloadStrategy < AbstractDownloadStrategy
|
||||||
REF_TYPES = [:branch, :revision, :revisions, :tag].freeze
|
REF_TYPES = [:branch, :revision, :revisions, :tag].freeze
|
||||||
|
|
||||||
def initialize(cask, command = SystemCommand)
|
def initialize(*args, **options)
|
||||||
super
|
super(*args, **options)
|
||||||
@ref_type, @ref = extract_ref
|
@ref_type, @ref = extract_ref
|
||||||
@clone = Hbc.cache.join(cache_filename)
|
@clone = Hbc.cache.join(cache_filename)
|
||||||
end
|
end
|
||||||
@ -64,11 +64,6 @@ module Hbc
|
|||||||
end
|
end
|
||||||
|
|
||||||
class CurlDownloadStrategy < AbstractDownloadStrategy
|
class CurlDownloadStrategy < AbstractDownloadStrategy
|
||||||
# TODO: should be part of url object
|
|
||||||
def mirrors
|
|
||||||
@mirrors ||= []
|
|
||||||
end
|
|
||||||
|
|
||||||
def tarball_path
|
def tarball_path
|
||||||
@tarball_path ||= Hbc.cache.join("#{name}--#{version}#{ext}")
|
@tarball_path ||= Hbc.cache.join("#{name}--#{version}#{ext}")
|
||||||
end
|
end
|
||||||
@ -95,13 +90,8 @@ module Hbc
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def downloaded_size
|
|
||||||
temporary_path.size? || 0
|
|
||||||
end
|
|
||||||
|
|
||||||
def _fetch
|
def _fetch
|
||||||
odebug "Calling curl with args #{cask_curl_args}"
|
curl_download url, *cask_curl_args, to: temporary_path, user_agent: uri_object.user_agent
|
||||||
curl(*cask_curl_args)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch
|
def fetch
|
||||||
@ -131,33 +121,12 @@ module Hbc
|
|||||||
ignore_interrupts { temporary_path.rename(tarball_path) }
|
ignore_interrupts { temporary_path.rename(tarball_path) }
|
||||||
end
|
end
|
||||||
tarball_path
|
tarball_path
|
||||||
rescue CurlDownloadStrategyError
|
|
||||||
raise if mirrors.empty?
|
|
||||||
puts "Trying a mirror..."
|
|
||||||
@url = mirrors.shift
|
|
||||||
retry
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def cask_curl_args
|
def cask_curl_args
|
||||||
default_curl_args.tap do |args|
|
cookies_args + referer_args
|
||||||
args.concat(user_agent_args)
|
|
||||||
args.concat(cookies_args)
|
|
||||||
args.concat(referer_args)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def default_curl_args
|
|
||||||
[url, "-C", downloaded_size, "-o", temporary_path]
|
|
||||||
end
|
|
||||||
|
|
||||||
def user_agent_args
|
|
||||||
if uri_object.user_agent
|
|
||||||
["-A", uri_object.user_agent]
|
|
||||||
else
|
|
||||||
[]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def cookies_args
|
def cookies_args
|
||||||
@ -191,8 +160,7 @@ module Hbc
|
|||||||
|
|
||||||
class CurlPostDownloadStrategy < CurlDownloadStrategy
|
class CurlPostDownloadStrategy < CurlDownloadStrategy
|
||||||
def cask_curl_args
|
def cask_curl_args
|
||||||
super
|
super.concat(post_args)
|
||||||
default_curl_args.concat(post_args)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def post_args
|
def post_args
|
||||||
@ -225,8 +193,8 @@ module Hbc
|
|||||||
|
|
||||||
# super does not provide checks for already-existing downloads
|
# super does not provide checks for already-existing downloads
|
||||||
def fetch
|
def fetch
|
||||||
if tarball_path.exist?
|
if cached_location.directory?
|
||||||
puts "Already downloaded: #{tarball_path}"
|
puts "Already downloaded: #{cached_location}"
|
||||||
else
|
else
|
||||||
@url = @url.sub(/^svn\+/, "") if @url =~ %r{^svn\+http://}
|
@url = @url.sub(/^svn\+/, "") if @url =~ %r{^svn\+http://}
|
||||||
ohai "Checking out #{@url}"
|
ohai "Checking out #{@url}"
|
||||||
@ -252,9 +220,8 @@ module Hbc
|
|||||||
else
|
else
|
||||||
fetch_repo @clone, @url
|
fetch_repo @clone, @url
|
||||||
end
|
end
|
||||||
compress
|
|
||||||
end
|
end
|
||||||
tarball_path
|
cached_location
|
||||||
end
|
end
|
||||||
|
|
||||||
# This primary reason for redefining this method is the trust_cert
|
# This primary reason for redefining this method is the trust_cert
|
||||||
@ -288,10 +255,6 @@ module Hbc
|
|||||||
print_stderr: false)
|
print_stderr: false)
|
||||||
end
|
end
|
||||||
|
|
||||||
def tarball_path
|
|
||||||
@tarball_path ||= cached_location.dirname.join(cached_location.basename.to_s + "-#{@cask.version}.tar")
|
|
||||||
end
|
|
||||||
|
|
||||||
def shell_quote(str)
|
def shell_quote(str)
|
||||||
# Oh god escaping shell args.
|
# Oh god escaping shell args.
|
||||||
# See http://notetoself.vrensk.com/2008/08/escaping-single-quotes-in-ruby-harder-than-expected/
|
# See http://notetoself.vrensk.com/2008/08/escaping-single-quotes-in-ruby-harder-than-expected/
|
||||||
@ -304,35 +267,5 @@ module Hbc
|
|||||||
yield name, url
|
yield name, url
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
# TODO/UPDATE: the tar approach explained below is fragile
|
|
||||||
# against challenges such as case-sensitive filesystems,
|
|
||||||
# and must be re-implemented.
|
|
||||||
#
|
|
||||||
# Seems nutty: we "download" the contents into a tape archive.
|
|
||||||
# Why?
|
|
||||||
# * A single file is tractable to the rest of the Cask toolchain,
|
|
||||||
# * An alternative would be to create a Directory container type.
|
|
||||||
# However, some type of file-serialization trick would still be
|
|
||||||
# needed in order to enable calculating a single checksum over
|
|
||||||
# a directory. So, in that alternative implementation, the
|
|
||||||
# special cases would propagate outside this class, including
|
|
||||||
# the use of tar or equivalent.
|
|
||||||
# * SubversionDownloadStrategy.cached_location is not versioned
|
|
||||||
# * tarball_path provides a needed return value for our overridden
|
|
||||||
# fetch method.
|
|
||||||
# * We can also take this private opportunity to strip files from
|
|
||||||
# the download which are protocol-specific.
|
|
||||||
|
|
||||||
def compress
|
|
||||||
Dir.chdir(cached_location) do
|
|
||||||
@command.run!("/usr/bin/tar",
|
|
||||||
args: ['-s/^\.//', "--exclude", ".svn", "-cf", Pathname.new(tarball_path), "--", "."],
|
|
||||||
print_stderr: false)
|
|
||||||
end
|
|
||||||
clear_cache
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -12,7 +12,11 @@ module Hbc
|
|||||||
end
|
end
|
||||||
|
|
||||||
def calculate_checkpoint
|
def calculate_checkpoint
|
||||||
result = SystemCommand.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", URL::FAKE_USER_AGENT, "--fail", @uri], print_stderr: false)
|
curl_executable, *args = curl_args(
|
||||||
|
"--compressed", "--location", "--fail", @uri,
|
||||||
|
user_agent: :fake
|
||||||
|
)
|
||||||
|
result = SystemCommand.run(curl_executable, args: args, print_stderr: false)
|
||||||
|
|
||||||
checkpoint = if result.success?
|
checkpoint = if result.success?
|
||||||
processed_appcast_text = result.stdout.gsub(%r{<pubDate>[^<]*</pubDate>}m, "")
|
processed_appcast_text = result.stdout.gsub(%r{<pubDate>[^<]*</pubDate>}m, "")
|
||||||
|
|||||||
@ -112,11 +112,7 @@ module Hbc
|
|||||||
processed_output[:stderr],
|
processed_output[:stderr],
|
||||||
processed_status.exitstatus)
|
processed_status.exitstatus)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module Hbc
|
|
||||||
class SystemCommand
|
|
||||||
class Result
|
class Result
|
||||||
attr_accessor :command, :stdout, :stderr, :exit_status
|
attr_accessor :command, :stdout, :stderr, :exit_status
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
module Hbc
|
module Hbc
|
||||||
class URL
|
class URL
|
||||||
FAKE_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10) https://caskroom.github.io".freeze
|
attr_reader :using, :revision, :trust_cert, :uri, :cookies, :referer, :data, :user_agent
|
||||||
|
|
||||||
attr_reader :using, :revision, :trust_cert, :uri, :cookies, :referer, :data
|
|
||||||
|
|
||||||
extend Forwardable
|
extend Forwardable
|
||||||
def_delegators :uri, :path, :scheme, :to_s
|
def_delegators :uri, :path, :scheme, :to_s
|
||||||
@ -17,7 +15,7 @@ module Hbc
|
|||||||
|
|
||||||
def initialize(uri, options = {})
|
def initialize(uri, options = {})
|
||||||
@uri = Hbc::UnderscoreSupportingURI.parse(uri)
|
@uri = Hbc::UnderscoreSupportingURI.parse(uri)
|
||||||
@user_agent = options[:user_agent]
|
@user_agent = options.fetch(:user_agent, :default)
|
||||||
@cookies = options[:cookies]
|
@cookies = options[:cookies]
|
||||||
@referer = options[:referer]
|
@referer = options[:referer]
|
||||||
@using = options[:using]
|
@using = options[:using]
|
||||||
@ -25,10 +23,5 @@ module Hbc
|
|||||||
@trust_cert = options[:trust_cert]
|
@trust_cert = options[:trust_cert]
|
||||||
@data = options[:data]
|
@data = options[:data]
|
||||||
end
|
end
|
||||||
|
|
||||||
def user_agent
|
|
||||||
return FAKE_USER_AGENT if @user_agent == :fake
|
|
||||||
@user_agent
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -33,7 +33,7 @@ module Hbc
|
|||||||
meta_dir = cached || cask.metadata_subdir("gpg", :now, true)
|
meta_dir = cached || cask.metadata_subdir("gpg", :now, true)
|
||||||
sig_path = meta_dir.join("signature.asc")
|
sig_path = meta_dir.join("signature.asc")
|
||||||
|
|
||||||
curl(cask.gpg.signature, "-o", sig_path.to_s) unless cached || force
|
curl_download cask.gpg.signature, to: sig_path unless cached || force
|
||||||
|
|
||||||
sig_path
|
sig_path
|
||||||
end
|
end
|
||||||
|
|||||||
@ -242,12 +242,10 @@ class FormulaAuditor
|
|||||||
|
|
||||||
def self.http_content_headers_and_checksum(url, hash_needed: false, user_agent: :default)
|
def self.http_content_headers_and_checksum(url, hash_needed: false, user_agent: :default)
|
||||||
max_time = hash_needed ? "600" : "25"
|
max_time = hash_needed ? "600" : "25"
|
||||||
args = curl_args(
|
output, = curl_output(
|
||||||
extra_args: ["--connect-timeout", "15", "--include", "--max-time", max_time, url],
|
"--connect-timeout", "15", "--include", "--max-time", max_time, "--location", url,
|
||||||
show_output: true,
|
user_agent: user_agent
|
||||||
user_agent: user_agent,
|
|
||||||
)
|
)
|
||||||
output = Open3.popen3(*args) { |_, stdout, _, _| stdout.read }
|
|
||||||
|
|
||||||
status_code = :unknown
|
status_code = :unknown
|
||||||
while status_code == :unknown || status_code.to_s.start_with?("3")
|
while status_code == :unknown || status_code.to_s.start_with?("3")
|
||||||
|
|||||||
@ -25,9 +25,9 @@ module Homebrew
|
|||||||
"public_download_numbers": true,
|
"public_download_numbers": true,
|
||||||
"public_stats": true}
|
"public_stats": true}
|
||||||
EOS
|
EOS
|
||||||
curl "--silent", "--fail", "-u#{bintray_user}:#{bintray_key}",
|
curl "--silent", "--fail", "--user", "#{bintray_user}:#{bintray_key}",
|
||||||
"-H", "Content-Type: application/json",
|
"--header", "Content-Type: application/json",
|
||||||
"-d", package_blob, bintray_repo_url
|
"--data", package_blob, bintray_repo_url
|
||||||
puts
|
puts
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -40,8 +40,8 @@ module Homebrew
|
|||||||
content_url = "https://api.bintray.com/content/homebrew/mirror"
|
content_url = "https://api.bintray.com/content/homebrew/mirror"
|
||||||
content_url += "/#{bintray_package}/#{f.pkg_version}/#{filename}"
|
content_url += "/#{bintray_package}/#{f.pkg_version}/#{filename}"
|
||||||
content_url += "?publish=1"
|
content_url += "?publish=1"
|
||||||
curl "--silent", "--fail", "-u#{bintray_user}:#{bintray_key}",
|
curl "--silent", "--fail", "--user", "#{bintray_user}:#{bintray_key}",
|
||||||
"-T", download, content_url
|
"--upload-file", download, content_url
|
||||||
puts
|
puts
|
||||||
ohai "Mirrored #{filename}!"
|
ohai "Mirrored #{filename}!"
|
||||||
end
|
end
|
||||||
|
|||||||
@ -228,7 +228,7 @@ module Homebrew
|
|||||||
"https://github.com/BrewTestBot/homebrew-#{tap.repo}/compare/homebrew:master...pr-#{issue}"
|
"https://github.com/BrewTestBot/homebrew-#{tap.repo}/compare/homebrew:master...pr-#{issue}"
|
||||||
end
|
end
|
||||||
|
|
||||||
curl "--silent", "--fail", "-o", "/dev/null", "-I", bottle_commit_url
|
curl "--silent", "--fail", "--output", "/dev/null", "--head", bottle_commit_url
|
||||||
|
|
||||||
safe_system "git", "checkout", "--quiet", "-B", bottle_branch, orig_revision
|
safe_system "git", "checkout", "--quiet", "-B", bottle_branch, orig_revision
|
||||||
pull_patch bottle_commit_url, "bottle commit"
|
pull_patch bottle_commit_url, "bottle commit"
|
||||||
@ -303,7 +303,7 @@ module Homebrew
|
|||||||
extra_msg = @description ? "(#{@description})" : nil
|
extra_msg = @description ? "(#{@description})" : nil
|
||||||
ohai "Fetching patch #{extra_msg}"
|
ohai "Fetching patch #{extra_msg}"
|
||||||
puts "Patch: #{patch_url}"
|
puts "Patch: #{patch_url}"
|
||||||
curl patch_url, "-s", "-o", patchpath
|
curl_download patch_url, to: patchpath
|
||||||
end
|
end
|
||||||
|
|
||||||
def apply_patch
|
def apply_patch
|
||||||
@ -433,10 +433,10 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
version = info.pkg_version
|
version = info.pkg_version
|
||||||
ohai "Publishing on Bintray: #{package} #{version}"
|
ohai "Publishing on Bintray: #{package} #{version}"
|
||||||
curl "-w", '\n', "--silent", "--fail",
|
curl "--write-out", '\n', "--silent", "--fail",
|
||||||
"-u#{creds[:user]}:#{creds[:key]}", "-X", "POST",
|
"--user", "#{creds[:user]}:#{creds[:key]}", "--request", "POST",
|
||||||
"-H", "Content-Type: application/json",
|
"--header", "Content-Type: application/json",
|
||||||
"-d", '{"publish_wait_for_secs": 0}',
|
"--data", '{"publish_wait_for_secs": 0}',
|
||||||
"https://api.bintray.com/content/homebrew/#{repo}/#{package}/#{version}/publish"
|
"https://api.bintray.com/content/homebrew/#{repo}/#{package}/#{version}/publish"
|
||||||
true
|
true
|
||||||
rescue => e
|
rescue => e
|
||||||
@ -587,7 +587,7 @@ module Homebrew
|
|||||||
# We're in the cache; make sure to force re-download
|
# We're in the cache; make sure to force re-download
|
||||||
loop do
|
loop do
|
||||||
begin
|
begin
|
||||||
curl url, "-o", filename
|
curl_download url, to: filename
|
||||||
break
|
break
|
||||||
rescue
|
rescue
|
||||||
if retry_count >= max_curl_retries
|
if retry_count >= max_curl_retries
|
||||||
@ -606,7 +606,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
|
|
||||||
def check_bintray_mirror(name, url)
|
def check_bintray_mirror(name, url)
|
||||||
headers = curl_output("--connect-timeout", "15", "--head", url)[0]
|
headers, = curl_output("--connect-timeout", "15", "--location", "--head", url)
|
||||||
status_code = headers.scan(%r{^HTTP\/.* (\d+)}).last.first
|
status_code = headers.scan(%r{^HTTP\/.* (\d+)}).last.first
|
||||||
return if status_code.start_with?("2")
|
return if status_code.start_with?("2")
|
||||||
opoo "The Bintray mirror #{url} is not reachable (HTTP status code #{status_code})."
|
opoo "The Bintray mirror #{url} is not reachable (HTTP status code #{status_code})."
|
||||||
|
|||||||
@ -375,75 +375,59 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy
|
|||||||
ohai "Downloading from #{url}"
|
ohai "Downloading from #{url}"
|
||||||
end
|
end
|
||||||
|
|
||||||
urls = actual_urls(url)
|
curl_download resolved_url(url), to: temporary_path
|
||||||
unless urls.empty?
|
|
||||||
ohai "Downloading from #{urls.last}"
|
|
||||||
if !ENV["HOMEBREW_NO_INSECURE_REDIRECT"].nil? && url.start_with?("https://") &&
|
|
||||||
urls.any? { |u| !u.start_with? "https://" }
|
|
||||||
puts "HTTPS to HTTP redirect detected & HOMEBREW_NO_INSECURE_REDIRECT is set."
|
|
||||||
raise CurlDownloadStrategyError, url
|
|
||||||
end
|
|
||||||
url = urls.last
|
|
||||||
end
|
|
||||||
|
|
||||||
curl url, "-C", downloaded_size, "-o", temporary_path
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Curl options to be always passed to curl,
|
# Curl options to be always passed to curl,
|
||||||
# with raw head calls (`curl -I`) or with actual `fetch`.
|
# with raw head calls (`curl --head`) or with actual `fetch`.
|
||||||
def _curl_opts
|
def _curl_opts
|
||||||
copts = []
|
return ["--user" << meta.fetch(:user)] if meta.key?(:user)
|
||||||
copts << "--user" << meta.fetch(:user) if meta.key?(:user)
|
[]
|
||||||
copts
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def actual_urls(url)
|
def resolved_url(url)
|
||||||
urls = []
|
redirect_url, _, status = curl_output(
|
||||||
curl_args = _curl_opts << "-I" << "-L" << url
|
*_curl_opts, "--silent", "--head",
|
||||||
Utils.popen_read("curl", *curl_args).scan(/^Location: (.+)$/).map do |m|
|
"--write-out", "%{redirect_url}",
|
||||||
urls << URI.join(urls.last || url, m.first.chomp).to_s
|
"--output", "/dev/null",
|
||||||
|
url.to_s
|
||||||
|
)
|
||||||
|
|
||||||
|
return url unless status.success?
|
||||||
|
return url if redirect_url.empty?
|
||||||
|
|
||||||
|
ohai "Downloading from #{redirect_url}"
|
||||||
|
if ENV["HOMEBREW_NO_INSECURE_REDIRECT"] &&
|
||||||
|
url.start_with?("https://") && !redirect_url.start_with?("https://")
|
||||||
|
puts "HTTPS to HTTP redirect detected & HOMEBREW_NO_INSECURE_REDIRECT is set."
|
||||||
|
raise CurlDownloadStrategyError, url
|
||||||
end
|
end
|
||||||
urls
|
|
||||||
|
redirect_url
|
||||||
end
|
end
|
||||||
|
|
||||||
def downloaded_size
|
def curl(*args, **options)
|
||||||
temporary_path.size? || 0
|
|
||||||
end
|
|
||||||
|
|
||||||
def curl(*args)
|
|
||||||
args.concat _curl_opts
|
args.concat _curl_opts
|
||||||
args << "--connect-timeout" << "5" unless mirrors.empty?
|
args << "--connect-timeout" << "5" unless mirrors.empty?
|
||||||
super
|
super(*args, **options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Detect and download from Apache Mirror
|
# Detect and download from Apache Mirror
|
||||||
class CurlApacheMirrorDownloadStrategy < CurlDownloadStrategy
|
class CurlApacheMirrorDownloadStrategy < CurlDownloadStrategy
|
||||||
def apache_mirrors
|
def apache_mirrors
|
||||||
rd, wr = IO.pipe
|
mirrors, = Open3.capture3(
|
||||||
buf = ""
|
*curl_args(*_curl_opts, "--silent", "--location", "#{@url}&asjson=1"),
|
||||||
|
)
|
||||||
|
|
||||||
pid = fork do
|
JSON.parse(mirrors)
|
||||||
ENV.delete "HOMEBREW_CURL_VERBOSE"
|
|
||||||
rd.close
|
|
||||||
$stdout.reopen(wr)
|
|
||||||
$stderr.reopen(wr)
|
|
||||||
curl "#{@url}&asjson=1"
|
|
||||||
end
|
|
||||||
wr.close
|
|
||||||
|
|
||||||
rd.readline if ARGV.verbose? # Remove Homebrew output
|
|
||||||
buf << rd.read until rd.eof?
|
|
||||||
rd.close
|
|
||||||
Process.wait(pid)
|
|
||||||
buf
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def _fetch
|
def _fetch
|
||||||
return super if @tried_apache_mirror
|
return super if @tried_apache_mirror
|
||||||
@tried_apache_mirror = true
|
@tried_apache_mirror = true
|
||||||
|
|
||||||
mirrors = JSON.parse(apache_mirrors)
|
mirrors = apache_mirrors
|
||||||
path_info = mirrors.fetch("path_info")
|
path_info = mirrors.fetch("path_info")
|
||||||
@url = mirrors.fetch("preferred") + path_info
|
@url = mirrors.fetch("preferred") + path_info
|
||||||
@mirrors |= %W[https://archive.apache.org/dist/#{path_info}]
|
@mirrors |= %W[https://archive.apache.org/dist/#{path_info}]
|
||||||
@ -460,7 +444,7 @@ end
|
|||||||
class CurlPostDownloadStrategy < CurlDownloadStrategy
|
class CurlPostDownloadStrategy < CurlDownloadStrategy
|
||||||
def _fetch
|
def _fetch
|
||||||
base_url, data = @url.split("?")
|
base_url, data = @url.split("?")
|
||||||
curl base_url, "-d", data, "-C", downloaded_size, "-o", temporary_path
|
curl_download base_url, "--data", data, to: temporary_path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -530,7 +514,7 @@ class S3DownloadStrategy < CurlDownloadStrategy
|
|||||||
s3url = obj.public_url
|
s3url = obj.public_url
|
||||||
end
|
end
|
||||||
|
|
||||||
curl s3url, "-C", downloaded_size, "-o", temporary_path
|
curl_download s3url, to: temporary_path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -566,7 +550,7 @@ class GitHubPrivateRepositoryDownloadStrategy < CurlDownloadStrategy
|
|||||||
end
|
end
|
||||||
|
|
||||||
def _fetch
|
def _fetch
|
||||||
curl download_url, "-C", downloaded_size, "-o", temporary_path
|
curl_download download_url, to: temporary_path
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -615,7 +599,7 @@ class GitHubPrivateRepositoryReleaseDownloadStrategy < GitHubPrivateRepositoryDo
|
|||||||
def _fetch
|
def _fetch
|
||||||
# HTTP request header `Accept: application/octet-stream` is required.
|
# HTTP request header `Accept: application/octet-stream` is required.
|
||||||
# Without this, the GitHub API will respond with metadata, not binary.
|
# Without this, the GitHub API will respond with metadata, not binary.
|
||||||
curl download_url, "-C", downloaded_size, "-o", temporary_path, "-H", "Accept: application/octet-stream"
|
curl_download download_url, "--header", "Accept: application/octet-stream", to: temporary_path
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -915,18 +899,27 @@ class GitHubGitDownloadStrategy < GitDownloadStrategy
|
|||||||
def github_last_commit
|
def github_last_commit
|
||||||
return if ENV["HOMEBREW_NO_GITHUB_API"]
|
return if ENV["HOMEBREW_NO_GITHUB_API"]
|
||||||
|
|
||||||
output, _, status = curl_output "-H", "Accept: application/vnd.github.v3.sha", \
|
output, _, status = curl_output(
|
||||||
"-I", "https://api.github.com/repos/#{@user}/#{@repo}/commits/#{@ref}"
|
"--silent", "--head", "--location",
|
||||||
|
"-H", "Accept: application/vnd.github.v3.sha",
|
||||||
|
"https://api.github.com/repos/#{@user}/#{@repo}/commits/#{@ref}"
|
||||||
|
)
|
||||||
|
|
||||||
commit = output[/^ETag: \"(\h+)\"/, 1] if status.success?
|
return unless status.success?
|
||||||
|
|
||||||
|
commit = output[/^ETag: \"(\h+)\"/, 1]
|
||||||
version.update_commit(commit) if commit
|
version.update_commit(commit) if commit
|
||||||
commit
|
commit
|
||||||
end
|
end
|
||||||
|
|
||||||
def multiple_short_commits_exist?(commit)
|
def multiple_short_commits_exist?(commit)
|
||||||
return if ENV["HOMEBREW_NO_GITHUB_API"]
|
return if ENV["HOMEBREW_NO_GITHUB_API"]
|
||||||
output, _, status = curl_output "-H", "Accept: application/vnd.github.v3.sha", \
|
|
||||||
"-I", "https://api.github.com/repos/#{@user}/#{@repo}/commits/#{commit}"
|
output, _, status = curl_output(
|
||||||
|
"--silent", "--head", "--location",
|
||||||
|
"-H", "Accept: application/vnd.github.v3.sha",
|
||||||
|
"https://api.github.com/repos/#{@user}/#{@repo}/commits/#{commit}"
|
||||||
|
)
|
||||||
|
|
||||||
!(status.success? && output && output[/^Status: (200)/, 1] == "200")
|
!(status.success? && output && output[/^Status: (200)/, 1] == "200")
|
||||||
end
|
end
|
||||||
@ -1159,15 +1152,13 @@ class DownloadStrategyDetector
|
|||||||
SubversionDownloadStrategy
|
SubversionDownloadStrategy
|
||||||
when %r{^cvs://}
|
when %r{^cvs://}
|
||||||
CVSDownloadStrategy
|
CVSDownloadStrategy
|
||||||
when %r{^https?://(.+?\.)?googlecode\.com/hg}
|
when %r{^hg://}, %r{^https?://(.+?\.)?googlecode\.com/hg}
|
||||||
MercurialDownloadStrategy
|
|
||||||
when %r{^hg://}
|
|
||||||
MercurialDownloadStrategy
|
MercurialDownloadStrategy
|
||||||
when %r{^bzr://}
|
when %r{^bzr://}
|
||||||
BazaarDownloadStrategy
|
BazaarDownloadStrategy
|
||||||
when %r{^fossil://}
|
when %r{^fossil://}
|
||||||
FossilDownloadStrategy
|
FossilDownloadStrategy
|
||||||
when %r{^http://svn\.apache\.org/repos/}, %r{^svn\+http://}
|
when %r{^svn\+http://}, %r{^http://svn\.apache\.org/repos/}
|
||||||
SubversionDownloadStrategy
|
SubversionDownloadStrategy
|
||||||
when %r{^https?://(.+?\.)?sourceforge\.net/hgweb/}
|
when %r{^https?://(.+?\.)?sourceforge\.net/hgweb/}
|
||||||
MercurialDownloadStrategy
|
MercurialDownloadStrategy
|
||||||
|
|||||||
@ -165,7 +165,7 @@ module Formulary
|
|||||||
def load_file
|
def load_file
|
||||||
HOMEBREW_CACHE_FORMULA.mkpath
|
HOMEBREW_CACHE_FORMULA.mkpath
|
||||||
FileUtils.rm_f(path)
|
FileUtils.rm_f(path)
|
||||||
curl url, "-o", path
|
curl_download url, to: path
|
||||||
super
|
super
|
||||||
rescue MethodDeprecatedError => e
|
rescue MethodDeprecatedError => e
|
||||||
if url =~ %r{github.com/([\w-]+)/homebrew-([\w-]+)/}
|
if url =~ %r{github.com/([\w-]+)/homebrew-([\w-]+)/}
|
||||||
|
|||||||
@ -27,8 +27,11 @@ describe "download strategies", :cask do
|
|||||||
|
|
||||||
expect(downloader).to have_received(:curl).with(
|
expect(downloader).to have_received(:curl).with(
|
||||||
cask.url.to_s,
|
cask.url.to_s,
|
||||||
"-C", 0,
|
"--location",
|
||||||
"-o", kind_of(Pathname)
|
"--remote-time",
|
||||||
|
"--continue-at", "-",
|
||||||
|
"--output", kind_of(Pathname),
|
||||||
|
user_agent: :default
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -36,25 +39,25 @@ describe "download strategies", :cask do
|
|||||||
let(:url_options) { { user_agent: "Mozilla/25.0.1" } }
|
let(:url_options) { { user_agent: "Mozilla/25.0.1" } }
|
||||||
|
|
||||||
it "adds the appropriate curl args" do
|
it "adds the appropriate curl args" do
|
||||||
curl_args = []
|
expect(downloader).to receive(:safe_system) { |*args|
|
||||||
allow(downloader).to receive(:curl) { |*args| curl_args = args }
|
expect(args.each_cons(2)).to include(["--user-agent", "Mozilla/25.0.1"])
|
||||||
|
}
|
||||||
|
|
||||||
downloader.fetch
|
downloader.fetch
|
||||||
|
|
||||||
expect(curl_args.each_cons(2)).to include(["-A", "Mozilla/25.0.1"])
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with a generalized fake user agent" do
|
context "with a generalized fake user agent" do
|
||||||
|
alias_matcher :a_string_matching, :match
|
||||||
|
|
||||||
let(:url_options) { { user_agent: :fake } }
|
let(:url_options) { { user_agent: :fake } }
|
||||||
|
|
||||||
it "adds the appropriate curl args" do
|
it "adds the appropriate curl args" do
|
||||||
curl_args = []
|
expect(downloader).to receive(:safe_system) { |*args|
|
||||||
allow(downloader).to receive(:curl) { |*args| curl_args = args }
|
expect(args.each_cons(2).to_a).to include(["--user-agent", a_string_matching(/Mozilla.*Mac OS X 10.*AppleWebKit/)])
|
||||||
|
}
|
||||||
|
|
||||||
downloader.fetch
|
downloader.fetch
|
||||||
|
|
||||||
expect(curl_args.each_cons(2)).to include(["-A", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10) https://caskroom.github.io"])
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -138,7 +141,7 @@ describe "download strategies", :cask do
|
|||||||
describe Hbc::SubversionDownloadStrategy do
|
describe Hbc::SubversionDownloadStrategy do
|
||||||
let(:url_options) { { using: :svn } }
|
let(:url_options) { { using: :svn } }
|
||||||
let(:fake_system_command) { class_double(Hbc::SystemCommand) }
|
let(:fake_system_command) { class_double(Hbc::SystemCommand) }
|
||||||
let(:downloader) { Hbc::SubversionDownloadStrategy.new(cask, fake_system_command) }
|
let(:downloader) { Hbc::SubversionDownloadStrategy.new(cask, command: fake_system_command) }
|
||||||
before do
|
before do
|
||||||
allow(fake_system_command).to receive(:run!)
|
allow(fake_system_command).to receive(:run!)
|
||||||
end
|
end
|
||||||
@ -147,7 +150,7 @@ describe "download strategies", :cask do
|
|||||||
allow(downloader).to receive(:compress)
|
allow(downloader).to receive(:compress)
|
||||||
allow(downloader).to receive(:fetch_repo)
|
allow(downloader).to receive(:fetch_repo)
|
||||||
|
|
||||||
expect(downloader.fetch).to equal(downloader.tarball_path)
|
expect(downloader.fetch).to equal(downloader.cached_location)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "calls fetch_repo with default arguments for a simple Cask" do
|
it "calls fetch_repo with default arguments for a simple Cask" do
|
||||||
@ -237,44 +240,5 @@ describe "download strategies", :cask do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "runs tar to serialize svn downloads" do
|
|
||||||
# sneaky stub to remake the directory, since homebrew code removes it
|
|
||||||
# before tar is called
|
|
||||||
allow(downloader).to receive(:fetch_repo) {
|
|
||||||
downloader.cached_location.mkdir
|
|
||||||
}
|
|
||||||
|
|
||||||
downloader.fetch
|
|
||||||
|
|
||||||
expect(fake_system_command).to have_received(:run!).with(
|
|
||||||
"/usr/bin/tar",
|
|
||||||
hash_including(args: [
|
|
||||||
'-s/^\\.//',
|
|
||||||
"--exclude",
|
|
||||||
".svn",
|
|
||||||
"-cf",
|
|
||||||
downloader.tarball_path,
|
|
||||||
"--",
|
|
||||||
".",
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# does not work yet, because (for unknown reasons), the tar command
|
|
||||||
# returns an error code when running under the test suite
|
|
||||||
# it 'creates a tarball matching the expected checksum' do
|
|
||||||
# cask = Hbc::CaskLoader.load('svn-download-check-cask')
|
|
||||||
# downloader = Hbc::SubversionDownloadStrategy.new(cask)
|
|
||||||
# # special mocking required for tar to have something to work with
|
|
||||||
# def downloader.fetch_repo(target, url, revision = nil, ignore_externals=false)
|
|
||||||
# target.mkpath
|
|
||||||
# FileUtils.touch(target.join('empty_file.txt'))
|
|
||||||
# File.utime(1000,1000,target.join('empty_file.txt'))
|
|
||||||
# end
|
|
||||||
# expect(downloader.fetch).to equal(downloader.tarball_path)
|
|
||||||
# d = Hbc::Download.new(cask)
|
|
||||||
# d.send(:_check_sums, downloader.tarball_path, cask.sums)
|
|
||||||
# end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -33,13 +33,18 @@ describe Hbc::DSL::Appcast do
|
|||||||
|
|
||||||
describe "#calculate_checkpoint" do
|
describe "#calculate_checkpoint" do
|
||||||
before do
|
before do
|
||||||
expect(Hbc::SystemCommand).to receive(:run).with(*cmd_args).and_return(cmd_result)
|
expect(Hbc::SystemCommand).to receive(:run) do |executable, **options|
|
||||||
|
expect(executable).to eq "/usr/bin/curl"
|
||||||
|
expect(options[:args]).to include(*cmd_args)
|
||||||
|
expect(options[:print_stderr]).to be false
|
||||||
|
cmd_result
|
||||||
|
end
|
||||||
allow(cmd_result).to receive(:success?).and_return(cmd_success)
|
allow(cmd_result).to receive(:success?).and_return(cmd_success)
|
||||||
allow(cmd_result).to receive(:stdout).and_return(cmd_stdout)
|
allow(cmd_result).to receive(:stdout).and_return(cmd_stdout)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when server returns a successful HTTP status" do
|
context "when server returns a successful HTTP status" do
|
||||||
let(:cmd_args) { ["/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", Hbc::URL::FAKE_USER_AGENT, "--fail", uri], print_stderr: false] }
|
let(:cmd_args) { [HOMEBREW_USER_AGENT_FAKE_SAFARI, "--compressed", "--location", "--fail", uri] }
|
||||||
let(:cmd_result) { double("Hbc::SystemCommand::Result") }
|
let(:cmd_result) { double("Hbc::SystemCommand::Result") }
|
||||||
let(:cmd_success) { true }
|
let(:cmd_success) { true }
|
||||||
let(:cmd_stdout) { "hello world" }
|
let(:cmd_stdout) { "hello world" }
|
||||||
@ -56,7 +61,7 @@ describe Hbc::DSL::Appcast do
|
|||||||
end
|
end
|
||||||
|
|
||||||
context "when server returns a non-successful HTTP status" do
|
context "when server returns a non-successful HTTP status" do
|
||||||
let(:cmd_args) { ["/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", Hbc::URL::FAKE_USER_AGENT, "--fail", uri], print_stderr: false] }
|
let(:cmd_args) { [HOMEBREW_USER_AGENT_FAKE_SAFARI, "--compressed", "--location", "--fail", uri] }
|
||||||
let(:cmd_result) { double("Hbc::SystemCommand::Result") }
|
let(:cmd_result) { double("Hbc::SystemCommand::Result") }
|
||||||
let(:cmd_success) { false }
|
let(:cmd_success) { false }
|
||||||
let(:cmd_stdout) { "some error message from the server" }
|
let(:cmd_stdout) { "some error message from the server" }
|
||||||
|
|||||||
@ -1,42 +1,46 @@
|
|||||||
require "pathname"
|
require "pathname"
|
||||||
require "open3"
|
require "open3"
|
||||||
|
|
||||||
def curl_args(options = {})
|
def curl_executable
|
||||||
curl = Pathname.new ENV["HOMEBREW_CURL"]
|
curl = Pathname.new ENV["HOMEBREW_CURL"]
|
||||||
curl = Pathname.new "/usr/bin/curl" unless curl.exist?
|
curl = Pathname.new "/usr/bin/curl" unless curl.exist?
|
||||||
raise "#{curl} is not executable" unless curl.exist? && curl.executable?
|
return curl if curl.executable?
|
||||||
|
raise "#{curl} is not executable"
|
||||||
|
end
|
||||||
|
|
||||||
|
def curl_args(*extra_args, show_output: false, user_agent: :default)
|
||||||
args = [
|
args = [
|
||||||
curl.to_s,
|
curl_executable.to_s,
|
||||||
"--remote-time",
|
"--fail",
|
||||||
"--location",
|
"--show-error",
|
||||||
]
|
]
|
||||||
|
|
||||||
case options[:user_agent]
|
args << "--user-agent" << case user_agent
|
||||||
when :browser
|
when :browser, :fake
|
||||||
args << "--user-agent" << HOMEBREW_USER_AGENT_FAKE_SAFARI
|
HOMEBREW_USER_AGENT_FAKE_SAFARI
|
||||||
|
when :default
|
||||||
|
HOMEBREW_USER_AGENT_CURL
|
||||||
else
|
else
|
||||||
args << "--user-agent" << HOMEBREW_USER_AGENT_CURL
|
user_agent
|
||||||
end
|
end
|
||||||
|
|
||||||
unless options[:show_output]
|
unless show_output
|
||||||
args << "--progress-bar" unless ARGV.verbose?
|
args << "--progress-bar" unless ARGV.verbose?
|
||||||
args << "--verbose" if ENV["HOMEBREW_CURL_VERBOSE"]
|
args << "--verbose" if ENV["HOMEBREW_CURL_VERBOSE"]
|
||||||
args << "--fail"
|
|
||||||
args << "--silent" if !$stdout.tty? || ENV["TRAVIS"]
|
args << "--silent" if !$stdout.tty? || ENV["TRAVIS"]
|
||||||
end
|
end
|
||||||
|
|
||||||
args += options[:extra_args] if options[:extra_args]
|
args + extra_args
|
||||||
args
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def curl(*args)
|
def curl(*args)
|
||||||
safe_system(*curl_args(extra_args: args))
|
safe_system(*curl_args(*args))
|
||||||
end
|
end
|
||||||
|
|
||||||
def curl_output(*args)
|
def curl_download(*args, to: nil, **options)
|
||||||
curl_args = curl_args(extra_args: args, show_output: true)
|
curl(*args, "--location", "--remote-time", "--continue-at", "-", "--output", to, **options)
|
||||||
Open3.popen3(*curl_args) do |_, stdout, stderr, wait_thread|
|
end
|
||||||
[stdout.read, stderr.read, wait_thread.value]
|
|
||||||
end
|
def curl_output(*args, **options)
|
||||||
|
Open3.capture3(*curl_args(*args, show_output: true, **options))
|
||||||
end
|
end
|
||||||
|
|||||||
@ -166,7 +166,7 @@ module GitHub
|
|||||||
|
|
||||||
args += ["--dump-header", headers_tmpfile.path]
|
args += ["--dump-header", headers_tmpfile.path]
|
||||||
|
|
||||||
output, errors, status = curl_output(url.to_s, *args)
|
output, errors, status = curl_output(url.to_s, "--location", *args)
|
||||||
output, _, http_code = output.rpartition("\n")
|
output, _, http_code = output.rpartition("\n")
|
||||||
output, _, http_code = output.rpartition("\n") if http_code == "000"
|
output, _, http_code = output.rpartition("\n") if http_code == "000"
|
||||||
headers = headers_tmpfile.read
|
headers = headers_tmpfile.read
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user