scanpipeline

package
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 4, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package scanpipeline runs the scan pipeline that assembles a neutral sbom.Inventory. Run is the full flow over a source path: collect files → fingerprint → scan → source declared dependencies from the same files → gather + enrich the requested layers via the SDK's decoration pipeline (scanoss.DecorationPipeline). Build is the lower half (scan result → inventory) for callers that already have a scan result (e.g. a pre-generated WFP). Rendering is left to sbom.Generate — this package does not render. Layers to gather are driven by the caller's request, never by any output format.

Index

Constants

View Source
const (
	LayerCollect     = "collect"     // local: walking the tree and applying the filters
	LayerFingerprint = "fingerprint" // local: hashing the collected files
	LayerManifests   = "manifests"   // local: parsing dependency manifests
	LayerUpload      = "upload"      // remote: uploading the WFP
	LayerScan        = "scan"        // remote: the server-side scan
)

Layers the pipeline runs itself or delegates. Enrichment layers are not listed: they report under their API service name, which the SDK already supplies.

Variables

This section is empty.

Functions

func Build

func Build(ctx context.Context, client *scanoss.Client, result *scanossapi.ScanResult, services []scanoss.Service, includeDeclared bool, declared *parsers.LocalDependencies, reporter scanoss.DecorationReporter) (sbom.Inventory, error)

Build sources an Inventory from a scan result and enriches it with the requested layers. It is the lower half of the pipeline (scan result → inventory), used directly by callers that already have a scan result. Scan matches populate the detected components; when the deps layer is requested and declared manifests are supplied, they are resolved into the same Components list, tagged declared. Every requested purl-layer (licenses, vulns, crypto, geo) is then gathered over all components, via the decoration pipeline. The requested layers, not any format, decide what is gathered. Enrichment is non-fatal: a failed service is logged and skipped so a partial inventory is still returned.

func Enrich

func Enrich(ctx context.Context, client *scanoss.Client, inv *sbom.Inventory, services []scanoss.Service, reporter scanoss.DecorationReporter)

Enrich runs the decoration pipeline over the inventory's components and attaches the requested purl-layers in place — licenses/cryptography/geoprovenance inline on each component, vulnerabilities as the flat top-level list. It is the pipeline's format-blind enrichment stage, keyed purely by PURL (+ version): the scan path reaches it through Build/Run, and the enrich command calls it directly on an inventory parsed from an existing SBOM — no scan required. Each layer is opt-in (driven by the requested set, never the output format); with no purl-layer requested it makes no API call. Enrichment is non-fatal: a failed service is logged and skipped.

Types

type Options

type Options struct {
	Client *scanoss.Client // required

	// Services are the decoration services to gather over the components. The caller resolves
	// these — from a flag, a config file, or nothing at all — and hands over the result: this
	// package knows services, not whatever vocabulary produced them.
	Services []scanoss.Service

	// SourceDeclared asks for declared dependencies to be sourced from the dependency manifests in
	// the same tree, and merged into the inventory alongside the scan's detected components. It is
	// not a decoration service: nothing is fetched, the manifests already carry resolved PURLs.
	SourceDeclared bool

	SourcePath string         // file or directory to scan (required)
	Threads    int            // fingerprint workers (<1 => 1)
	Filter     filter.Options // file-collection filters (directory scans)
	// DependencySettings is the scanoss.json skip rules for the dependencies
	// operation. The manifest collection is a stage of its own, with its own
	// profile, so it cannot reuse Filter.Settings (which holds the scanning
	// section). Nil when there is no scanoss.json.
	DependencySettings *filter.Settings
	ScanOptions        []scanoss.ScanOption // per-scan tuning (chunk size, poll interval, BOM, ...)

	// OnProgress receives every layer's progress. Optional; nil reports nothing. The pipeline runs
	// layers concurrently, so it must be safe for concurrent use.
	OnProgress func(Progress)
}

Options configures Run, the full scan pipeline over a source path. Every layer reports through OnProgress — the steps the pipeline runs itself and the ones it delegates to the SDK alike, so a caller listens on one channel rather than reconciling two.

type Progress added in v0.5.0

type Progress struct {
	Layer  string // which layer is reporting; see the Layer* constants
	Status Status // where that layer is
	Done   int    // units done, only ever growing
	Total  int    // units in total; 0 when the layer cannot say
}

Progress is one update from one pipeline layer, whether the pipeline ran that layer itself or delegated it to the SDK. Every field means the same thing for every layer, so a consumer can render any update without knowing which layer produced it, or how that layer works.

Done and Total only ever grow within a layer. Where the underlying work says otherwise — the server-side scan runs in passes that each restart their own counter — it is normalised here, so that no consumer has to know.

type Reporter added in v0.5.0

type Reporter struct {
	// contains filtered or unexported fields
}

Reporter turns the SDK's stages into this package's layer updates. Run wires one up itself; it is exported for the callers that drive the SDK directly — `results` resumes a scan and enriches it, collecting and fingerprinting nothing — so that every entry point reports layers the same way and the translation exists in one place.

Hand it to a call with WithScanReporter and WithDecorationReporter — the reporter belongs to the operation, not to the client, so the same client can serve several with different listeners.

func NewReporter added in v0.5.0

func NewReporter(on func(Progress)) *Reporter

NewReporter returns a Reporter delivering to on. A nil on makes every update a no-op.

func (*Reporter) Decorating added in v0.5.0

func (r *Reporter) Decorating(service string, done, total int)

Decorating names the layer after the service that reported it, which is what a consumer sees.

func (*Reporter) Fingerprinting added in v0.5.0

func (r *Reporter) Fingerprinting(done, total int)

func (*Reporter) Scanning added in v0.5.0

func (r *Reporter) Scanning(e scanossapi.ScanEnvelope)

Scanning normalises the poll: the server restarts its counter on every pass, so each pass owns a share of the layer's range and the result only ever grows.

func (*Reporter) Uploading added in v0.5.0

func (r *Reporter) Uploading(done, total int)

type Result

type Result struct {
	Inventory     sbom.Inventory
	WFP           []byte
	ProcessErrors int
}

Result is the outcome of Run: the gathered inventory, the generated WFP (for --save-wfp) and the count of files that failed to fingerprint.

What the filters excluded is not here: it is reported as the collect layer completing, while the scan is still ahead, rather than handed back once everything is over.

func Run

func Run(ctx context.Context, opts Options) (Result, error)

Run executes the full pipeline over Options.SourcePath: collect the files (applying the filters for a directory), fingerprint them, scan, source declared dependencies from the same file set (when the deps layer is requested), and gather + enrich into an Inventory. It owns everything from file collection onward; the caller supplies only flag-derived configuration.

type Status added in v0.5.0

type Status string

Status is a layer's position in its lifecycle, normalised so that layers as different as a local file walk and a queued server-side scan are rendered the same way.

const (
	StatusPending   Status = "pending" // known, not started: a queued scan, a layer awaiting its turn
	StatusRunning   Status = "running"
	StatusCompleted Status = "completed"
	StatusFailed    Status = "failed"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL