executiondag

package
v0.1.4 Latest Latest
Warning

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

Go to latest
Published: Jul 7, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddNode

func AddNode[TInput any, TOutput StatusProvider, NodeType Node[TInput, TOutput]](
	dag *DAG[TInput],
	node NodeType,
)

AddNode adds a node to the DAG Dependencies are extracted from node.GetDependencies() which should return DependsOn[NodeType]() values Panics if a node with the same type is already registered

func ApplyOverrides

func ApplyOverrides(ctx context.Context, output StatusProvider) error

func DependsOn

func DependsOn[NodeType any]() any

DependsOn creates a dependency key for a specific node type Usage: func (n *MyNode) GetDependencies() []any { return []any{DependsOn[*jsdeps.Node](), DependsOn[*pydeps.Node]()} }

func GetOutput

func GetOutput[NodeType any](ctx context.Context) any

GetOutput retrieves the output of a node by its node type from the context. The context must be the one returned by DAG.Execute(), as it contains all node outputs. Panics if the node type is not found in the context. Usage: GetOutput[*jsdeps.Node](ctx)

func GetOutputForNode

func GetOutputForNode[NodeType any, TOutput StatusProvider](ctx context.Context) TOutput

GetOutputForNode is an internal helper that retrieves output with proper typing. Used by nodeEntry.GetOutput() to maintain type safety.

func TryGetOutput

func TryGetOutput[NodeType any](ctx context.Context) (any, bool)

TryGetOutput retrieves the output of a node by its node type from the context. The context must be the one returned by DAG.Execute(), as it contains all node outputs. Returns the output and true if found, nil and false if not found.

Types

type BaseOutput

type BaseOutput struct {
	Status       Status `json:"status,omitempty"`
	StatusReason string `json:"status_reason,omitempty"`
}

BaseOutput provides default implementation of StatusProvider interface. Embed this in your output types to avoid boilerplate.

func (BaseOutput) GetStatus

func (b BaseOutput) GetStatus() Status

func (BaseOutput) GetStatusReason

func (b BaseOutput) GetStatusReason() string

type DAG

type DAG[TInput any] struct {
	// contains filtered or unexported fields
}

func NewDAG

func NewDAG[TInput any]() *DAG[TInput]

NewDAG creates a new empty DAG

func (*DAG[TInput]) CollectUpstreamSources

func (d *DAG[TInput]) CollectUpstreamSources(node any) map[string]Source

func (*DAG[TInput]) Execute

func (d *DAG[TInput]) Execute(ctx context.Context, input TInput) (context.Context, TInput, error)

Execute runs all nodes in the DAG in topological order with parallel execution. Returns the updated context containing all node outputs and any execution error. Callers must use the returned context to retrieve outputs via GetOutput[T](ctx).

func (*DAG[TInput]) GetNodes

func (d *DAG[TInput]) GetNodes() []dagNode

GetNodes returns all nodes in the DAG

func (*DAG[TInput]) GetSupportedOverrides

func (d *DAG[TInput]) GetSupportedOverrides() []overrides.FieldInfo

GetSupportedOverrides collects override field descriptors from all nodes whose output implements OverridableV2.

type DataSourceInfo

type DataSourceInfo struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	URL         string `json:"url"`
}

DataSourceInfo contains information about external data sources consulted by fetch nodes

type Entry

type Entry struct {
	Key       string
	Data      any
	Extension string
}

Entry represents a single output item for storage. Used internally by CollectEntries and storage backends.

type NoFetchProvider

type NoFetchProvider interface {
	GetNoFetch() bool
}

NoFetchProvider is satisfied by Input types whose --no-fetch flag should be honored. When the executor encounters an Input that implements this and returns true, fetch nodes are read from disk instead of re-executed.

type Node

type Node[TInput any, TOutput StatusProvider] interface {
	// Execute runs the node's logic
	// - ctx: context for cancellation, logging, and accessing previous node outputs via GetOutput
	// - input: the input data for the node. MUST be treated as read-only. The
	//   DAG runs sibling nodes in a stage in parallel and passes the same input
	//   by value to each; if input contains pointer or slice fields, mutating
	//   them from inside Execute will race against other workers in the stage.
	// Returns the node's output or an error
	// If output.GetStatus() == StatusSkipped, dependent nodes are auto-skipped
	// (unless they implement SkipPropagationNode with AllowAutoSkip() returning false)
	// Any error halts the entire DAG execution
	Execute(ctx context.Context, input TInput) (TOutput, error)

	// GetDependencies returns the dependency keys for this node
	// Use DependsOn[T]() to create dependency keys
	GetDependencies() []any

	// CreateSkippedOutput creates a skipped output with the given reason
	// Called by the DAG framework when this node is auto-skipped due to a dependency being skipped
	// The implementation should return an output with StatusSkipped and appropriate zero/nil values for fields
	CreateSkippedOutput(reason string, input TInput) TOutput

	// Kind returns the kind/category of this node (e.g., "transformer", "scanner", "check")
	Kind() string
}

Node represents a node in the execution DAG TInput is the type of the input data passed to all nodes TOutput is the type of the output data produced by this node (must implement StatusProvider)

type NodeSummary

type NodeSummary struct {
	NodeType     string          `json:"node_type"`               // Type name of the node
	Status       string          `json:"status"`                  // "success", "skipped", "error"
	FilesWritten []string        `json:"files_written,omitempty"` // Paths to files written by this node
	Stats        map[string]any  `json:"stats,omitempty"`         // Node-specific statistics (e.g., records fetched, items processed)
	DataSource   *DataSourceInfo `json:"data_source,omitempty"`   // Non-nil for fetch nodes that consult external sources
}

NodeSummary contains information about what a node did during execution

type OutputSummary

type OutputSummary interface {
	Summary(outputDir string) NodeSummary
}

OutputSummary is an optional interface that node outputs can implement to provide summary information for reporting purposes.

This is primarily intended for fetch and transform node outputs. The Summary() method has access to the output's data to generate statistics. The outputDir parameter allows outputs to construct file paths they wrote.

type OverridableV2

type OverridableV2 interface {
	ApplyOverridesV2([]overrides.Override) ([]overrides.AppliedOverride, error)
	GetSupportedOverrides() []overrides.FieldInfo
}

OverridableV2 is implemented by outputs that support typed override application. Combining apply + describe on the same type ensures compile-time consistency: you cannot implement one without the other.

type Persistable

type Persistable interface {
	PersistKey() string
}

Persistable is implemented by outputs that should be persisted to disk. The framework serializes the entire output using PersistKey() as the filename.

type ReadableNode

type ReadableNode[TInput any, TOutput StatusProvider] interface {
	Node[TInput, TOutput]
	Read(ctx context.Context, input TInput) (TOutput, error)
}

ReadableNode is an optional interface that nodes can implement to support loading data from disk instead of executing (used with --no-fetch flag). Nodes that implement this interface can be loaded from previous runs.

type SkipPropagationNode

type SkipPropagationNode interface {
	// AllowAutoSkip returns whether this node should be automatically skipped
	// when one or more of its dependencies are skipped.
	// - Return true: node will be auto-skipped (default behavior)
	// - Return false: node's Execute() will be called, allowing it to inspect dependency status
	AllowAutoSkip() bool
}

SkipPropagationNode is an optional interface that nodes can implement to control whether they are automatically skipped when dependencies are skipped. By default, if a node's dependency is skipped, the node is auto-skipped. Implementing this interface allows nodes to opt-out of this behavior.

type Source

type Source struct {
	Name        string         `json:"name" jsonschema:"description=Human-readable name of the data source"`
	Description string         `json:"description" jsonschema:"description=Description of what data this source provides"`
	URL         string         `json:"url" jsonschema:"description=Base URL of the data source API or website"`
	Category    SourceCategory `` /* 137-byte string literal not displayed */
	Version     string         `json:"version,omitempty" jsonschema:"description=Version of the data source (e.g. CWE database version)"`
}

func (Source) ToDataSourceInfo

func (s Source) ToDataSourceInfo() DataSourceInfo

type SourceCategory

type SourceCategory string
const (
	SourceCategoryVulnerability SourceCategory = "vulnerability"
	SourceCategoryRegistry      SourceCategory = "registry"
	SourceCategoryReference     SourceCategory = "reference"
)

type SourceProvider

type SourceProvider interface {
	GetSources() map[string]Source
}

type Status

type Status string
const (
	// StatusSuccess indicates the node executed successfully
	StatusSuccess Status = "success"

	// StatusSkipped indicates the node was skipped
	StatusSkipped Status = "skipped"
)

func (Status) String

func (s Status) String() string

type StatusProvider

type StatusProvider interface {
	GetStatus() Status
	GetStatusReason() string
}

StatusProvider is an interface that all node outputs must implement.

Jump to

Keyboard shortcuts

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