Skip to content

Commit

Permalink
Implement Downloadable for more types.
Browse files Browse the repository at this point in the history
  • Loading branch information
reitermarkus committed Jul 30, 2024
1 parent 746303a commit 8bb8b5a
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 33 deletions.
4 changes: 4 additions & 0 deletions Library/Homebrew/cmd/fetch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ def run

sleep 0.05

Check warning on line 297 in Library/Homebrew/cmd/fetch.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/cmd/fetch.rb#L297

Added line #L297 was not covered by tests
rescue Interrupt
remaining_downloads.each do |_, future|

Check warning on line 299 in Library/Homebrew/cmd/fetch.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/cmd/fetch.rb#L299

Added line #L299 was not covered by tests
# FIXME: Implement cancellation of running downloads.
end

print "\n" * previous_pending_line_count
$stdout.flush
raise

Check warning on line 305 in Library/Homebrew/cmd/fetch.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/cmd/fetch.rb#L303-L305

Added lines #L303 - L305 were not covered by tests
Expand Down
1 change: 0 additions & 1 deletion Library/Homebrew/cmd/install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,6 @@ def run
end

if casks.any?

if args.dry_run?
if (casks_to_install = casks.reject(&:installed?).presence)
ohai "Would install #{::Utils.pluralize("cask", casks_to_install.count, include_count: true)}:"
Expand Down
8 changes: 0 additions & 8 deletions Library/Homebrew/download_strategy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -710,14 +710,6 @@ def stage
end
end

# Strategy for extracting local binary packages.
class LocalBottleDownloadStrategy < AbstractFileDownloadStrategy
def initialize(path) # rubocop:disable Lint/MissingSuper
@cached_location = path
extend Pourable
end
end

# Strategy for downloading a Subversion repository.
#
# @api public
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/downloadable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def verify_download_integrity(filename)

sig { overridable.returns(String) }
def download_name
File.basename(determine_url.to_s)
@download_name ||= File.basename(determine_url.to_s)

Check warning on line 129 in Library/Homebrew/downloadable.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/downloadable.rb#L129

Added line #L129 was not covered by tests
end

private
Expand Down
2 changes: 2 additions & 0 deletions Library/Homebrew/formula.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2773,10 +2773,12 @@ def on_system_blocks_exist?
).returns(Pathname)
}
def fetch(verify_download_integrity: true, timeout: nil, quiet: false)
odeprecated "Formula#fetch", "Resource#fetch on Formula#resource"
active_spec.fetch(verify_download_integrity:, timeout:, quiet:)

Check warning on line 2777 in Library/Homebrew/formula.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/formula.rb#L2776-L2777

Added lines #L2776 - L2777 were not covered by tests
end

def verify_download_integrity(filename)
odeprecated "Formula#verify_download_integrity", "Resource#verify_download_integrity on Formula#resource"

Check warning on line 2781 in Library/Homebrew/formula.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/formula.rb#L2781

Added line #L2781 was not covered by tests
active_spec.verify_download_integrity(filename)
end

Expand Down
4 changes: 2 additions & 2 deletions Library/Homebrew/formula_installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1263,11 +1263,11 @@ def fetch

def downloader
if (bottle_path = formula.local_bottle_path)
LocalBottleDownloadStrategy.new(bottle_path)
Resource::Local.new(bottle_path)
elsif pour_bottle?
formula.bottle
else
formula
formula.resource
end
end

Expand Down
27 changes: 27 additions & 0 deletions Library/Homebrew/resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,33 @@ def determine_url_mirrors
[*extra_urls, *super].uniq
end

# A local resource that doesn't need to be downloaded.
class Local < Resource
def initialize(path)
super(File.basename(path))
@path = path

Check warning on line 276 in Library/Homebrew/resource.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/resource.rb#L275-L276

Added lines #L275 - L276 were not covered by tests
end

sig { override.returns(Pathname) }
def cached_download
@path

Check warning on line 281 in Library/Homebrew/resource.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/resource.rb#L281

Added line #L281 was not covered by tests
end

sig { override.void }
def clear_cache; end

sig {
override.params(

Check warning on line 288 in Library/Homebrew/resource.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/resource.rb#L288

Added line #L288 was not covered by tests
verify_download_integrity: T::Boolean,
timeout: T.nilable(T.any(Integer, Float)),
quiet: T::Boolean,
).returns(Pathname)
}
def fetch(verify_download_integrity: true, timeout: nil, quiet: false)
cached_download

Check warning on line 295 in Library/Homebrew/resource.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/resource.rb#L295

Added line #L295 was not covered by tests
end
end

# A resource for a formula.
class Formula < Resource
sig { override.returns(String) }
Expand Down
104 changes: 83 additions & 21 deletions Library/Homebrew/sbom.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# frozen_string_literal: true

require "cxxstdlib"
require "downloadable"
require "json"
require "development_tools"
require "extend/cachable"
Expand Down Expand Up @@ -89,43 +90,104 @@ def self.exist?(formula)
spdxfile(formula).exist?
end

sig { returns(T::Hash[String, String]) }
def self.fetch_schema!
return @schema if @schema.present?
class Schema
include Downloadable

url = SCHEMA_URL
target = SCHEMA_CACHE_TARGET
quieter = target.exist? && !target.empty?
sig { override.void }
def initialize
super

Check warning on line 98 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L98

Added line #L98 was not covered by tests

curl_args = Utils::Curl.curl_args(retries: 0)
curl_args += ["--silent", "--time-cond", target.to_s] if quieter
@url = URL.new(SCHEMA_URL)
@download_name = SCHEMA_FILENAME

Check warning on line 101 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L100-L101

Added lines #L100 - L101 were not covered by tests
end

begin
unless quieter
sig { override.returns(String) }
def name
download_name

Check warning on line 106 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L106

Added line #L106 was not covered by tests
end

sig { override.returns(String) }
def download_type
"SBOM schema"

Check warning on line 111 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L111

Added line #L111 was not covered by tests
end

sig { override.returns(Pathname) }
def cached_download
cache/download_name

Check warning on line 116 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L116

Added line #L116 was not covered by tests
end

sig { override.void }
def clear_cache
cached_download.unlink

Check warning on line 121 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L121

Added line #L121 was not covered by tests
end

sig {
override.params(

Check warning on line 125 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L125

Added line #L125 was not covered by tests
verify_download_integrity: T::Boolean,
timeout: T.nilable(T.any(Integer, Float)),
quiet: T::Boolean,
).returns(Pathname)
}
def fetch(verify_download_integrity: true, timeout: nil, quiet: false)
quiet ||= cached_download.exist? && !cached_download.empty?

Check warning on line 132 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L132

Added line #L132 was not covered by tests

curl_args = Utils::Curl.curl_args(retries: 0)

Check warning on line 134 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L134

Added line #L134 was not covered by tests
curl_args += ["--silent", "--time-cond", cached_download.to_s] if quiet

unless quiet
oh1 "Fetching SBOM schema"
ohai "Downloading #{url}"
end
Utils::Curl.curl_download(*curl_args, url, to: target, retries: 0)
FileUtils.touch(target, mtime: Time.now)

Utils::Curl.curl_download(*curl_args, url.to_s, to: cached_download, retries: 0)
FileUtils.touch(cached_download, mtime: Time.now)

Check warning on line 143 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L142-L143

Added lines #L142 - L143 were not covered by tests

download = cached_download

Check warning on line 145 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L145

Added line #L145 was not covered by tests
verify_download_integrity(download) if verify_download_integrity
download

Check warning on line 147 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L147

Added line #L147 was not covered by tests
end

sig { override.params(filename: Pathname).void }
def verify_download_integrity(filename)
JSON.parse(filename.read)

Check warning on line 152 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L152

Added line #L152 was not covered by tests
rescue JSON::ParserError => e
raise DownloadError.new(self, e)

Check warning on line 154 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L154

Added line #L154 was not covered by tests
end

sig { override.returns(Pathname) }
def cache
super.join("sbom")

Check warning on line 159 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L159

Added line #L159 was not covered by tests
end
end

sig { returns(T::Hash[String, String]) }
def self.fetch_schema!
return @schema if @schema.present?

schema = Schema.new

Check warning on line 167 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L167

Added line #L167 was not covered by tests

begin
schema.fetch

Check warning on line 170 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L170

Added line #L170 was not covered by tests
rescue ErrorDuringExecution
target.unlink if target.exist? && target.empty?
schema.clear_cache if schema.downloaded? && schema.cached_download.empty?

if target.exist?
if schema.downloaded?

Check warning on line 174 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L174

Added line #L174 was not covered by tests
opoo "SBOM schema update failed, falling back to cached version."
else
opoo "Failed to fetch SBOM schema, cannot perform SBOM validation!"

return {}
end
end
rescue DownloadError => e
if e.cause.is_a?(JSON::ParserError)
schema.clear_cache
opoo "Failed to fetch SBOM schema, cached version corrupted, cannot perform SBOM validation!"

Check warning on line 184 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L184

Added line #L184 was not covered by tests
end

@schema = begin
JSON.parse(target.read, freeze: true)
rescue JSON::ParserError
target.unlink
opoo "Failed to fetch SBOM schema, cached version corrupted, cannot perform SBOM validation!"
{}
return {}

Check warning on line 187 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L187

Added line #L187 was not covered by tests
end

@schema = JSON.parse(schema.cached_download.read, freeze: true)

Check warning on line 190 in Library/Homebrew/sbom.rb

View check run for this annotation

Codecov / codecov/patch

Library/Homebrew/sbom.rb#L190

Added line #L190 was not covered by tests
end

sig { params(bottling: T::Boolean).returns(T::Boolean) }
Expand Down

0 comments on commit 8bb8b5a

Please sign in to comment.