Wrapper around the osv-scanner CLI (https://google.github.io/osv-scanner/).
osv-scanner queries the OSV.dev database, which
aggregates advisories from many ecosystems (Hex, Maven/Gradle, Swift
PM, npm, PyPI, RubyGems, ...) into a single feed. Several Mob scan
layers (hex_deps, gradle_deps, swift_deps) call this helper so
the binary integration lives in one place.
All public functions are pure orchestration — no parsing logic, no
finding shape. Parser does the actual JSON → Finding translation,
which keeps the network/process side easy to mock and the parser
trivially testable with fixture JSON.
Summary
Types
What to scan. {:lockfile, path} for a single lockfile, {:directory, path}
for a recursive scan that finds every supported manifest under the tree.
Functions
True if osv-scanner is on PATH.
Scan a target and return findings tagged with the given layer.
Types
Functions
@spec installed?() :: boolean()
True if osv-scanner is on PATH.
@spec scan(target(), atom(), keyword()) :: {:ok, [MobDev.SecurityScan.Finding.t()]} | {:error, :not_installed | {:not_found, Path.t()} | {:scan_failed, String.t()}}
Scan a target and return findings tagged with the given layer.
Returns:
{:ok, findings}— scan completed (findings list may be empty){:error, :not_installed}— binary not on PATH{:error, {:not_found, path}}— target path doesn't exist{:error, {:scan_failed, reason}}— binary exited non-zero or produced unparseable output
osv-scanner exits with code 1 when findings are present and 0
when clean — this function treats both as success and only signals
:scan_failed for true errors (code 127, malformed JSON, etc.).