diff --git a/content/css/docs.css b/content/css/docs.css index 85f16bb8..5304a7f7 100644 --- a/content/css/docs.css +++ b/content/css/docs.css @@ -233,8 +233,9 @@ footer { } .downloads .checksum { - color: #aaa; - font-style: italic; + font-family: monospace; + font-size: .6em; + vertical-align: bottom; } /* Docs-related styles. */ diff --git a/content/download.html b/content/download.html index 8da12a8e..14b16461 100644 --- a/content/download.html +++ b/content/download.html @@ -29,11 +29,6 @@ title: Download the installation instructions.

- -
Operating system <%= dropdown(:os, Downloads.operating_systems, :popular, popular: %w(darwin linux windows)) %> @@ -64,13 +59,13 @@ title: Download - <% release.assets.each do |asset| %> - - <%= asset.name %> - <%= asset.os %> - <%= asset.arch %> - <%= format_bytes asset.size %> - not available yet + <% release.binaries.each do |binary| %> + + <%= binary.name %> + <%= binary.os %> + <%= binary.arch %> + <%= format_bytes binary.size %> + <%= Downloads.checksum(release, binary.name) %> <% end %> diff --git a/lib/helpers/download.rb b/lib/helpers/download.rb index 9e7601f6..69d6128a 100644 --- a/lib/helpers/download.rb +++ b/lib/helpers/download.rb @@ -1,9 +1,11 @@ +require 'fileutils' require 'json' +require 'open-uri' module Downloads # repositories returns a list of all repositories with releases. def self.repositories - @repositories ||= begin + @_repositories ||= begin repos = Dir.glob('downloads/*').map { |dir| Repository.new(dir) } repos.sort_by { |r| r.name == 'prometheus' ? '0' : r.name } end @@ -13,7 +15,7 @@ module Downloads # provided for. def self.operating_systems repositories.inject([]) do |list, repo| - list += repo.releases.map { |r| r.assets.map(&:os) }.flatten + list += repo.releases.map { |r| r.binaries.map(&:os) }.flatten end.uniq.sort end @@ -21,10 +23,38 @@ module Downloads # provided for. def self.architectures repositories.inject([]) do |list, repo| - list += repo.releases.map { |r| r.assets.map(&:arch) }.flatten + list += repo.releases.map { |r| r.binaries.map(&:arch) }.flatten end.uniq.sort end + # checksum returns the checksum for a given filename of a given release. It + # might try to download the sha256sums.txt from the given release if available + # and not already cached. + def self.checksum(release, name) + @_checksums ||= {} + @_checksums[release.id] ||= begin + asset = release.assets.find { |a| a['name'] == 'sha256sums.txt' } + + if asset + cache = ['downloads', '.cache', release.id, 'sha256sums.txt'].join('/') + unless File.exists?(cache) + FileUtils.mkdir_p(File.dirname(cache)) + File.open(cache, 'wb') do |file| + file.write(URI.parse(asset['browser_download_url']).read) + end + end + + File.readlines(cache).each_with_object({}) do |line, memo| + checksum, filename = line.split(/\s+/) + memo[filename] = checksum + end + else + {} + end + end + @_checksums[release.id][name] + end + class Repository def initialize(dir) @repo = JSON.parse(File.read(File.join(dir, 'repo.json'))) @@ -66,6 +96,10 @@ module Downloads @data = data end + def id + @data['id'] + end + def name @data['name'] end @@ -79,11 +113,17 @@ module Downloads end def assets - @data['assets'].map { |d| Asset.new(d) } + @data['assets'] + end + + def binaries + assets. + select { |d| d['name'] && %w[.tar.gz .zip].any? { |ext| d['name'].end_with?(ext) } }. + map { |d| Binary.new(d) } end end - class Asset + class Binary def initialize(data) @data = data end