Class: Homebrew::Vulns::CachedFeed Abstract Private

Inherits:
Object
  • Object
show all
Extended by:
T::Helpers, Utils::Output::Mixin
Defined in:
vulns/cached_feed.rb

Overview

This class is part of a private API. This class may only be used in the Homebrew/brew repository. Third parties should avoid using this class if possible, as it may be removed or changed without warning.

This class is abstract.

It cannot be directly instantiated. Subclasses must implement the abstract methods below.

Base class for read-only loaders of a single upstream JSON feed cached under HOMEBREW_CACHE/vulns/. Subclasses implement CachedFeed.data_url, CachedFeed.cache_filename and #initialize(data) (which validates the parsed payload) and may override CachedFeed.default_max_age. CachedFeed.load handles freshness, atomic refresh and stale-cache fallback uniformly.

Direct Known Subclasses

CPANSec, Repology

Defined Under Namespace

Classes: Error

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils::Output::Mixin

issue_reporting_message, odebug, odeprecated, odie, odisabled, ofail, oh1, oh1_title, ohai, ohai_title, onoe, opoo, opoo_outside_github_actions, opoo_without_github_actions_annotation, pretty_deprecated, pretty_disabled, pretty_duration, pretty_install_status, pretty_installed, pretty_uninstalled, pretty_unmarked, pretty_upgradable, pretty_warning

Constructor Details

#initialize(data) ⇒ void

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

  • data (T.anything)


33
# File 'vulns/cached_feed.rb', line 33

def initialize(data); end

Class Method Details

.cache_filenameString

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method is abstract.

Returns:



27
# File 'vulns/cached_feed.rb', line 27

def self.cache_filename; end

.data_urlString

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

This method is abstract.

Returns:



24
# File 'vulns/cached_feed.rb', line 24

def self.data_url; end

.default_max_ageInteger

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns:



30
# File 'vulns/cached_feed.rb', line 30

def self.default_max_age = 86_400

.from_file(path) ⇒ T.attached_class

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

Returns:

  • (T.attached_class)


66
67
68
69
70
# File 'vulns/cached_feed.rb', line 66

def self.from_file(path)
  new(JSON.parse(path.read))
rescue JSON::ParserError => e
  raise Error, "Failed to parse #{cache_filename} at #{path}: #{e.message}"
end

.load(cache: HOMEBREW_CACHE/"vulns", max_age: default_max_age) ⇒ T.attached_class

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

  • cache (Pathname) (defaults to: HOMEBREW_CACHE/"vulns")
  • max_age (Integer) (defaults to: default_max_age)

Returns:

  • (T.attached_class)


36
37
38
39
40
41
42
43
44
45
46
47
# File 'vulns/cached_feed.rb', line 36

def self.load(cache: HOMEBREW_CACHE/"vulns", max_age: default_max_age)
  cache_file = cache/cache_filename
  return from_file(cache_file) if cache_file.exist? && (Time.now - cache_file.mtime) <= max_age

  refresh(cache_file)
rescue ErrorDuringExecution, Error => e
  raise unless cache_file.exist?

  opoo "Failed to refresh #{cache_filename} (#{e.message.lines.first&.strip}); " \
       "using cached copy from #{cache_file.mtime}."
  from_file(cache_file)
end

.refresh(cache_file) ⇒ T.attached_class

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Download to a per-process sibling temp file and validate before atomically replacing the cache so a failed, truncated or concurrent fetch cannot corrupt the stale copy.

Parameters:

Returns:

  • (T.attached_class)


53
54
55
56
57
58
59
60
61
62
63
# File 'vulns/cached_feed.rb', line 53

def self.refresh(cache_file)
  cache_file.dirname.mkpath
  Tempfile.create([cache_filename, ".download"], cache_file.dirname.to_s) do |tmp|
    tmp.close
    path = Pathname(tmp.path)
    Utils::Curl.curl_download("--fail", "--silent", data_url, to: path)
    loaded = from_file(path)
    File.rename(path, cache_file)
    return loaded
  end
end

Instance Method Details

#as_hash(value) ⇒ Hash{String => T.untyped}?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

  • value (T.anything)

Returns:



73
74
75
76
77
# File 'vulns/cached_feed.rb', line 73

def as_hash(value)
  case value
  when Hash then value
  end
end