Skip to content

Instantly share code, notes, and snippets.

@havenwood
Created December 22, 2019 23:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save havenwood/0a0bd1dd2d449d8f4678ec53d4641c72 to your computer and use it in GitHub Desktop.
Save havenwood/0a0bd1dd2d449d8f4678ec53d4641c72 to your computer and use it in GitHub Desktop.
Download the latest Ruby tarballs with async-http: https://github.com/socketry/async-http
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'async'
require 'async/barrier'
require 'async/http/client'
require 'async/http/endpoint'
require 'async/logger'
require 'optionparser'
options = ARGV.options do |command|
command.banner = "Usage: #{command.program_name} ruby_version"
command.version = '0.0.1'
command
end
options.freeze.permute!
ruby_version = ARGV.shift
raise ArgumentError, "missing argument: ruby_version\n#{options.banner}" unless ruby_version
host = 'https://cache.ruby-lang.org'
major, minor, *_rest = ruby_version.split('.')
dir = File.join('pub', 'ruby', "#{major}.#{minor}")
basename = "ruby-#{ruby_version}"
extensions = %w[tar.bz2 tar.gz tar.xz zip].freeze
Async do |task|
endpoint = Async::HTTP::Endpoint.parse(host)
client = Async::HTTP::Client.new(endpoint)
barrier = Async::Barrier.new
extensions.each do |extension|
file = "#{basename}.#{extension}"
path = File.join(dir, file)
url = File.join(host, path)
barrier.async do
Async.logger.info "Requesting `#{url}' ..."
response = client.get(path)
unless response.success?
Async.logger.error "Aborting, failed to download `#{url}' ..."
task.stop
raise "response for `#{file}' failed with error status `#{response.status}'"
end
Async.logger.info "Downloading `#{file}' ..."
response.save(file)
Async.logger.info "Finished `#{file}' ..."
end
end
barrier.wait
ensure
client&.close
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment