Fetches and caches the upstream advisory sources the bundled-runtime
layer matches against (see MobDev.SecurityScan.BundledRuntime.Advisories).
The scan has to complete offline and must not hammer the unauthenticated
GitHub API (60 requests/hour), so every source goes through a file cache
at advisories/ in the runtime cache ($MOB_CACHE_DIR, default ~/.mob/cache):
- a cached copy younger than the TTL (default 24 h) is used as-is;
- otherwise the source is fetched, validated, and written to the cache;
- if the fetch fails, an older cached copy is used and reported as stale;
- with no cached copy either,
load/2returns{:error, reason}and the layer falls back to manual-check notes.
A fetched body is validated before it replaces the cache, so a rate-limit page or a redesigned site can't overwrite good data with nothing.
Options
:advisory_cache_dir— cache directory (defaultdefault_cache_dir/0):advisory_ttl— seconds a cached copy counts as fresh (default 86_400):advisory_http_get—(url, headers) -> {:ok, status, headers, body} | {:error, reason}; defaults to:httpc. Tests inject a stub.:github_token— token for the GitHub API; defaults toGITHUB_TOKEN,GH_TOKEN, thengh auth token. Unauthenticated access works.:now—DateTimeused for cache age (defaultDateTime.utc_now/0)
Summary
Types
Where the data came from. A fetch whose cache write failed carries the write error, since the next offline run will have nothing to fall back to.
Functions
Default cache directory for advisory data: advisories/ in the runtime cache.
Load one source's decoded data: [advisory] for :otp, the parsed
page entries for {:openssl, branch} and :sqlite, [cycle] for
:openssl_eol.
Extract the rel="next" URL from a GitHub Link header, if any.
Types
@type http_response() :: {:ok, non_neg_integer(), [{String.t(), String.t()}], binary()}
@type provenance() :: {:fetched, DateTime.t()} | {:fetched, DateTime.t(), {:cache_write_failed, String.t()}} | {:cached, DateTime.t()} | {:stale, DateTime.t(), String.t()}
Where the data came from. A fetch whose cache write failed carries the write error, since the next offline run will have nothing to fall back to.
@type source() :: :otp | {:openssl, String.t()} | :openssl_eol | :sqlite
Functions
@spec default_cache_dir() :: Path.t()
Default cache directory for advisory data: advisories/ in the runtime cache.
@spec load( source(), keyword() ) :: {:ok, term(), provenance()} | {:error, String.t()}
Load one source's decoded data: [advisory] for :otp, the parsed
page entries for {:openssl, branch} and :sqlite, [cycle] for
:openssl_eol.
Extract the rel="next" URL from a GitHub Link header, if any.