Documentation
¶
Overview ¶
Package graph builds and traverses a service's dependency graph. It resolves dependencies recursively through a pluggable fetcher (siblings in parallel), detects cycles and version conflicts, and renders or diffs the resolved graph.
Index ¶
- Constants
- func RenderDiffTree(d *GraphDiff) string
- func RenderDiffTreeColored(d *GraphDiff, col DiffColors) string
- func RenderTree(r *Result) string
- func RenderTreeColored(r *Result, col TreeColors) string
- func ShortRef(ref string) string
- type ChangeType
- type Conflict
- type ContractFetcher
- type DependencyRef
- type DiffColors
- type DiffNode
- type Edge
- type GraphChange
- type GraphDiff
- type Node
- type ResolveOptions
- type Result
- type Scheme
- type TreeColors
Constants ¶
const ( EdgeDependency = "dependency" EdgeReference = "reference" )
EdgeType distinguishes dependency vs reference relationships.
Variables ¶
This section is empty.
Functions ¶
func RenderDiffTree ¶
RenderDiffTree renders a graph diff as a tree-style string, showing only nodes that have changes in their subtree. Uses the same tree connectors as RenderTree for consistency.
func RenderDiffTreeColored ¶
func RenderDiffTreeColored(d *GraphDiff, col DiffColors) string
RenderDiffTreeColored renders a graph diff as a tree-style string with optional colorizers applied to change labels.
func RenderTree ¶
RenderTree renders the dependency graph as a tree-style string similar to the Unix tree command.
func RenderTreeColored ¶
func RenderTreeColored(r *Result, col TreeColors) string
RenderTreeColored renders the tree applying the given colorizers.
Types ¶
type ChangeType ¶
type ChangeType string
ChangeType indicates the kind of dependency graph change.
const ( AddedNode ChangeType = "added" RemovedNode ChangeType = "removed" VersionChanged ChangeType = "version_changed" )
type Conflict ¶
Conflict represents a version conflict where the same service is required at incompatible versions.
type ContractFetcher ¶
type ContractFetcher interface {
Fetch(ctx context.Context, dep contract.Dependency) (*contract.Bundle, error)
}
ContractFetcher fetches a contract bundle for a dependency. The full Dependency is passed so implementations can use fields like Compatibility for version resolution.
type DependencyRef ¶
type DependencyRef struct {
Scheme Scheme
Location string // Registry ref (OCI) or filesystem path (local)
Original string // Original unparsed reference
}
DependencyRef is a parsed, normalized dependency reference.
func ParseDependencyRef ¶
func ParseDependencyRef(raw string) DependencyRef
ParseDependencyRef parses a raw dependency reference string into a structured DependencyRef. The scheme is detected as follows:
- "oci://" prefix → OCI registry reference
- "file://" prefix → local filesystem reference
- no scheme → local filesystem reference
func (DependencyRef) IsLocal ¶
func (r DependencyRef) IsLocal() bool
IsLocal reports whether the reference points to the local filesystem.
func (DependencyRef) IsOCI ¶
func (r DependencyRef) IsOCI() bool
IsOCI reports whether the reference points to an OCI registry.
type DiffColors ¶
type DiffColors struct {
Name func(string) string // node name (recommended nil — alignment safety)
Added func(string) string
Removed func(string) string
Changed func(string) string
}
DiffColors holds optional colorizer functions applied to diff tree labels. A nil field is treated as identity, so the zero value renders plain text.
type DiffNode ¶
type DiffNode struct {
Name string `json:"name"`
Version string `json:"version,omitempty"`
Change *GraphChange `json:"change,omitempty"`
Children []DiffNode `json:"children,omitempty"`
}
DiffNode represents a node in the diff tree, carrying its own change (if any) and the changes in its subtree.
type Edge ¶
type Edge struct {
Ref string `json:"ref"`
Required bool `json:"required"`
Compatibility string `json:"compatibility"`
Type string `json:"type"` // EdgeDependency or EdgeReference
Node *Node `json:"node,omitempty"`
Error string `json:"error,omitempty"`
Local bool `json:"local,omitempty"`
}
Edge represents a dependency or reference relationship.
func ExtractReferenceEdges ¶
ExtractReferenceEdges creates Edge entries for config/policy references in a contract.
type GraphChange ¶
type GraphChange struct {
Name string `json:"name"`
ChangeType ChangeType `json:"changeType"`
OldVersion string `json:"oldVersion,omitempty"`
NewVersion string `json:"newVersion,omitempty"`
}
GraphChange represents a single change in the dependency graph.
type GraphDiff ¶
type GraphDiff struct {
Root DiffNode `json:"root"`
Changes []GraphChange `json:"changes,omitempty"`
}
GraphDiff holds the result of comparing two dependency graphs.
func DiffGraphs ¶
DiffGraphs compares two resolved dependency graphs by walking the tree structure and detecting added, removed, and version-changed nodes at each level. A node removed as a direct dependency is detected even if it remains transitively reachable through another path.
type Node ¶
type Node struct {
Name string `json:"name"`
Version string `json:"version"`
Ref string `json:"ref,omitempty"`
Local bool `json:"local,omitempty"`
Dependencies []Edge `json:"dependencies,omitempty"`
Contract *contract.Contract `json:"-"`
FS fs.FS `json:"-"`
}
Node represents a service in the dependency graph.
type ResolveOptions ¶
type ResolveOptions struct {
IncludeReferences bool // include config/policy reference edges
OnlyReferences bool // show only reference edges (no dependencies)
// OnResolved is fired exactly once per UNIQUE fetched node (not per edge:
// shared edges and cycles re-traverse and must NOT re-fire). nil = no-op.
// It is invoked from multiple goroutines (sibling deps resolve concurrently),
// so it MUST be goroutine-safe.
OnResolved func()
}
ResolveOptions controls what edges are included in the graph.
type Result ¶
type Result struct {
Root *Node `json:"root"`
Cycles [][]string `json:"cycles,omitempty"`
Conflicts []Conflict `json:"conflicts,omitempty"`
}
Result holds the output of graph resolution.
func Resolve ¶
Resolve builds the dependency graph starting from the given contract. It recursively fetches dependencies via the fetcher, detects cycles and version conflicts. If fetcher is nil, only direct dependencies are shown without resolution. Sibling dependencies at each level are fetched concurrently.
func ResolveWithOptions ¶
func ResolveWithOptions(ctx context.Context, c *contract.Contract, fetcher ContractFetcher, opts ResolveOptions) *Result
ResolveWithOptions builds the dependency graph with the given options.
type TreeColors ¶
type TreeColors struct {
Name func(string) string // node / ref display name
Version func(string) string // @version
Marker func(string) string // [local], [ref], (shared)
Error func(string) string // (error: ...)
Warn func(string) string // cycle / conflict lines
}
TreeColors holds optional colorizer functions applied to tree tokens. A nil field is treated as identity, so the zero value renders plain text.