resolver

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 4, 2025 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package resolver implements NuGet dependency resolution algorithms.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ConcurrencyTracker

type ConcurrencyTracker interface {
	// Enter is called when a worker starts (after acquiring semaphore).
	Enter()
	// Exit is called when a worker finishes (before releasing semaphore).
	Exit()
}

ConcurrencyTracker optionally tracks concurrent operations in ParallelResolver.

type ConflictDetector

type ConflictDetector struct{}

ConflictDetector detects version conflicts in dependency graphs. Operates during and after traversal (inline + post-processing).

func NewConflictDetector

func NewConflictDetector() *ConflictDetector

NewConflictDetector creates a new conflict detector.

func (*ConflictDetector) DetectFromGraph

func (cd *ConflictDetector) DetectFromGraph(root *GraphNode) ([]VersionConflict, []DowngradeWarning)

DetectFromGraph analyzes a completed graph for conflicts and downgrades.

type ConflictResolver

type ConflictResolver struct{}

ConflictResolver resolves version conflicts using nearest-wins.

func NewConflictResolver

func NewConflictResolver() *ConflictResolver

NewConflictResolver creates a new conflict resolver.

func (*ConflictResolver) ResolveConflict

func (cr *ConflictResolver) ResolveConflict(nodes []*GraphNode) *GraphNode

ResolveConflict resolves a conflict by selecting the nearest (lowest depth) version. If depths are equal, selects highest version (matches NuGet.Client).

type CycleAnalyzer

type CycleAnalyzer struct{}

CycleAnalyzer provides advanced cycle analysis and reporting

func NewCycleAnalyzer

func NewCycleAnalyzer() *CycleAnalyzer

NewCycleAnalyzer creates a new cycle analyzer

func (*CycleAnalyzer) AnalyzeCycles

func (ca *CycleAnalyzer) AnalyzeCycles(root *GraphNode) []CycleReport

AnalyzeCycles extracts all cycles from a graph and provides detailed reports

type CycleReport

type CycleReport struct {
	// PackageID involved in the cycle
	PackageID string

	// PathToSelf from root to the cycle point
	PathToSelf []string

	// Depth at which cycle was detected
	Depth int

	// Description is a human-readable description
	Description string
}

CycleReport provides detailed information about a detected cycle

type DependencyFetchResult

type DependencyFetchResult struct {
	Info  *PackageDependencyInfo
	Error error
}

DependencyFetchResult contains the result of fetching a dependency

type DependencyFetchTask

type DependencyFetchTask struct {
	// The dependency being fetched
	Dependency PackageDependency

	// Channel for receiving the result (Go equivalent of Task<T>)
	ResultChan chan *DependencyFetchResult

	// Edge information
	InnerEdge *GraphEdge
}

DependencyFetchTask represents an in-flight dependency fetch operation

type DependencyGroup

type DependencyGroup struct {
	TargetFramework string
	Dependencies    []PackageDependency
}

DependencyGroup represents dependencies for a specific target framework

type DependencyResult

type DependencyResult int

DependencyResult indicates the result of evaluating a dependency against the graph

const (
	// DependencyResultAcceptable - Dependency can be added to graph
	DependencyResultAcceptable DependencyResult = iota
	// DependencyResultEclipsed - Dependency is shadowed by another version
	DependencyResultEclipsed
	// DependencyResultPotentiallyDowngraded - Dependency might cause a downgrade
	DependencyResultPotentiallyDowngraded
	// DependencyResultCycle - Dependency creates a cycle
	DependencyResultCycle
)

type DependencyWalker

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

DependencyWalker builds dependency graphs using stack-based traversal. Matches NuGet.Client's RemoteDependencyWalker.

func NewDependencyWalker

func NewDependencyWalker(client PackageMetadataClient, sources []string, targetFramework string) *DependencyWalker

NewDependencyWalker creates a new dependency walker

func (*DependencyWalker) Walk

func (w *DependencyWalker) Walk(
	ctx context.Context,
	packageID string,
	versionRange string,
	targetFramework string,
	recursive bool,
) (*GraphNode, error)

Walk builds the complete dependency graph starting from the given package. Uses manual stack-based traversal matching NuGet.Client for performance. When recursive is false, only the root package is resolved (no transitive dependencies).

type Disposition

type Disposition int

Disposition tracks the state of a node in the dependency graph. Matches NuGet.Client's Disposition enum.

const (
	// DispositionAcceptable - Node is valid and can be used
	DispositionAcceptable Disposition = iota
	// DispositionRejected - Node was rejected (conflict, constraint violation)
	DispositionRejected
	// DispositionAccepted - Node was explicitly accepted
	DispositionAccepted
	// DispositionPotentiallyDowngraded - Node might cause a downgrade
	DispositionPotentiallyDowngraded
	// DispositionCycle - Node creates a circular dependency
	DispositionCycle
)

func (Disposition) String

func (d Disposition) String() string

type DowngradeWarning

type DowngradeWarning struct {
	PackageID      string
	CurrentVersion string
	TargetVersion  string
	Path           []string // Path from root to downgrade
}

DowngradeWarning represents a potential package downgrade

type FrameworkSelector

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

FrameworkSelector selects the best dependency group for a target framework. Matches NuGet.Frameworks.FrameworkReducer behavior.

func NewFrameworkSelector

func NewFrameworkSelector() *FrameworkSelector

NewFrameworkSelector creates a new framework selector.

func (*FrameworkSelector) SelectDependencies

func (fs *FrameworkSelector) SelectDependencies(
	groups []DependencyGroup,
	targetFramework string,
) []PackageDependency

SelectDependencies selects dependencies from groups based on target framework. Implements NuGet's framework compatibility and reduction logic.

type GraphEdge

type GraphEdge struct {
	// OuterEdge - parent edge (chain to root)
	OuterEdge *GraphEdge

	// Item - the package at this edge
	Item *PackageDependencyInfo

	// Edge - the dependency that created this edge
	Edge PackageDependency
}

GraphEdge represents the edge between two nodes in the dependency graph. Matches NuGet.Client's GraphEdge<RemoteResolveResult>.

type GraphNode

type GraphNode struct {
	// Key - unique identifier for this node (packageID|version)
	Key string

	// Item - package metadata and dependencies
	Item *PackageDependencyInfo

	// OuterNode - parent node (singular, for tree structure)
	OuterNode *GraphNode

	// InnerNodes - child nodes (dependencies)
	InnerNodes []*GraphNode

	// ParentNodes - tracks multiple parents when node is shared
	// Used when node is removed from outer node but needs parent tracking
	ParentNodes []*GraphNode

	// Disposition - state of this node
	Disposition Disposition

	// Depth - distance from root
	Depth int

	// OuterEdge - edge to this node from parent
	OuterEdge *GraphEdge
}

GraphNode represents a node in the dependency graph. Matches NuGet.Client's GraphNode<RemoteResolveResult>.

func (*GraphNode) AreAllParentsRejected

func (n *GraphNode) AreAllParentsRejected() bool

AreAllParentsRejected checks if all parent nodes are rejected

func (*GraphNode) PathFromRoot

func (n *GraphNode) PathFromRoot() []string

PathFromRoot returns the path from root to this node

type LibraryIncludeFlags

type LibraryIncludeFlags int

LibraryIncludeFlags specifies what should be included from a dependency. Maps to NuGet's LibraryIncludeFlags for PrivateAssets/ExcludeAssets support.

const (
	// LibraryIncludeFlagsNone - Include nothing
	LibraryIncludeFlagsNone LibraryIncludeFlags = 0
	// LibraryIncludeFlagsRuntime - Include runtime assets
	LibraryIncludeFlagsRuntime LibraryIncludeFlags = 1 << 0
	// LibraryIncludeFlagsCompile - Include compile-time assets
	LibraryIncludeFlagsCompile LibraryIncludeFlags = 1 << 1
	// LibraryIncludeFlagsBuild - Include build assets
	LibraryIncludeFlagsBuild LibraryIncludeFlags = 1 << 2
	// LibraryIncludeFlagsContentFiles - Include content files
	LibraryIncludeFlagsContentFiles LibraryIncludeFlags = 1 << 3
	// LibraryIncludeFlagsNative - Include native assets
	LibraryIncludeFlagsNative LibraryIncludeFlags = 1 << 4
	// LibraryIncludeFlagsAnalyzers - Include analyzers
	LibraryIncludeFlagsAnalyzers LibraryIncludeFlags = 1 << 5
	// LibraryIncludeFlagsBuildTransitive - Include transitive build assets
	LibraryIncludeFlagsBuildTransitive LibraryIncludeFlags = 1 << 6
	// LibraryIncludeFlagsAll - Include everything
	LibraryIncludeFlagsAll LibraryIncludeFlags = 0x7F
)

type NuGetErrorCode

type NuGetErrorCode string

NuGetErrorCode represents standard NuGet error codes

const (
	// NU1101 - No versions of package exist on any configured source
	NU1101 NuGetErrorCode = "NU1101"

	// NU1102 - Package exists but no version matches the requested range
	NU1102 NuGetErrorCode = "NU1102"

	// NU1103 - Only prerelease versions available when stable requested
	NU1103 NuGetErrorCode = "NU1103"
)

type OperationCache

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

OperationCache caches in-flight operations to avoid duplicate work. Matches NuGet.Client's ConcurrentDictionary<LibraryRange, Task<GraphItem>>.

func NewOperationCache

func NewOperationCache(ttl time.Duration) *OperationCache

NewOperationCache creates a new operation cache

func (*OperationCache) Clear

func (oc *OperationCache) Clear()

Clear removes all cached operations

func (*OperationCache) GetOrStart

func (oc *OperationCache) GetOrStart(
	ctx context.Context,
	key string,
	operation func(context.Context) (*PackageDependencyInfo, error),
) (*PackageDependencyInfo, error)

GetOrStart gets cached operation or starts a new one. This is the Go equivalent of ConcurrentDictionary.GetOrAdd with Task<T>.

type PackageDependency

type PackageDependency struct {
	ID              string
	VersionRange    string
	TargetFramework string // Empty = all frameworks

	// Include/Exclude flags for assets
	IncludeType LibraryIncludeFlags
	ExcludeType LibraryIncludeFlags

	// SuppressParent - when LibraryIncludeFlagsAll, parent is completely suppressed (PrivateAssets="All")
	SuppressParent LibraryIncludeFlags
}

PackageDependency represents a dependency on another package. Maps to NuGet's LibraryDependency.

type PackageDependencyInfo

type PackageDependencyInfo struct {
	ID           string
	Version      string
	Dependencies []PackageDependency

	// For framework-specific dependencies
	DependencyGroups []DependencyGroup

	// IsUnresolved indicates this package could not be found
	// Maps to LibraryType.Unresolved in NuGet.Client
	IsUnresolved bool
}

PackageDependencyInfo represents complete package metadata with dependencies. Maps to NuGet's RemoteResolveResult.

func (*PackageDependencyInfo) Key

func (p *PackageDependencyInfo) Key() string

Key returns a unique key for this package

func (*PackageDependencyInfo) String

func (p *PackageDependencyInfo) String() string

type PackageMetadataClient

type PackageMetadataClient interface {
	GetPackageMetadata(ctx context.Context, source string, packageID string, versionRange string) ([]*PackageDependencyInfo, error)
}

PackageMetadataClient interface for fetching package metadata

type ParallelResolver

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

ParallelResolver provides advanced parallel resolution strategies. Matches NuGet.Client's parallel restoration capabilities.

func NewParallelResolver

func NewParallelResolver(resolver *Resolver, maxWorkers int) *ParallelResolver

NewParallelResolver creates a new parallel resolver.

func (*ParallelResolver) BatchResolve

func (pr *ParallelResolver) BatchResolve(
	ctx context.Context,
	packages []PackageDependency,
	batchSize int,
) ([]*ResolutionResult, error)

BatchResolve resolves packages in batches for better resource control.

func (*ParallelResolver) ResolveMultiplePackages

func (pr *ParallelResolver) ResolveMultiplePackages(
	ctx context.Context,
	packages []PackageDependency,
) ([]*ResolutionResult, error)

ResolveMultiplePackages resolves multiple packages in parallel.

func (*ParallelResolver) ResolveProjectParallel

func (pr *ParallelResolver) ResolveProjectParallel(
	ctx context.Context,
	roots []PackageDependency,
) (*ResolutionResult, error)

ResolveProjectParallel resolves project dependencies with parallel optimization.

func (*ParallelResolver) WithTracker

func (pr *ParallelResolver) WithTracker(tracker ConcurrencyTracker) *ParallelResolver

WithTracker sets an optional concurrency tracker.

type ResolutionResult

type ResolutionResult struct {
	Packages   []*PackageDependencyInfo
	Conflicts  []VersionConflict
	Downgrades []DowngradeWarning
	Cycles     []CycleReport
	Unresolved []UnresolvedPackage // Packages that could not be resolved
}

ResolutionResult represents the result of dependency resolution. Maps to NuGet's RestoreTargetGraph.

func (*ResolutionResult) Success

func (r *ResolutionResult) Success() bool

Success returns true if resolution completed without unresolved packages. Matches NuGet.Client's success check: graphs.All(g => g.Unresolved.Count == 0)

type Resolver

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

Resolver provides high-level resolution API.

func NewResolver

func NewResolver(client PackageMetadataClient, sources []string, targetFramework string) *Resolver

NewResolver creates a new resolver.

func (*Resolver) ReplaceParallelResolver

func (r *Resolver) ReplaceParallelResolver(pr *ParallelResolver)

ReplaceParallelResolver replaces the parallel resolver with a custom one. This is useful for controlling worker pool limits.

func (*Resolver) Resolve

func (r *Resolver) Resolve(
	ctx context.Context,
	packageID string,
	versionRange string,
) (*ResolutionResult, error)

Resolve performs complete dependency resolution with conflict resolution.

func (*Resolver) ResolveBatch

func (r *Resolver) ResolveBatch(
	ctx context.Context,
	packages []PackageDependency,
	batchSize int,
) ([]*ResolutionResult, error)

ResolveBatch resolves packages in batches for better resource control.

func (*Resolver) ResolveMultiple

func (r *Resolver) ResolveMultiple(
	ctx context.Context,
	packages []PackageDependency,
) ([]*ResolutionResult, error)

ResolveMultiple resolves multiple packages in parallel.

func (*Resolver) ResolveNonRecursive

func (r *Resolver) ResolveNonRecursive(
	ctx context.Context,
	packageID string,
	versionRange string,
) (*ResolutionResult, error)

ResolveNonRecursive resolves a package without transitive dependencies. Matches NuGet.Client's WalkAsync with recursive: false.

func (*Resolver) ResolveProject

func (r *Resolver) ResolveProject(
	ctx context.Context,
	dependencies []PackageDependency,
) (*ResolutionResult, error)

ResolveProject resolves transitive dependencies for a project with multiple direct dependencies.

type TransitiveResolver

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

TransitiveResolver resolves the complete transitive closure of dependencies

func NewTransitiveResolver

func NewTransitiveResolver(resolver *Resolver) *TransitiveResolver

NewTransitiveResolver creates a new transitive resolver

func (*TransitiveResolver) ResolveMultipleRoots

func (tr *TransitiveResolver) ResolveMultipleRoots(
	ctx context.Context,
	roots []PackageDependency,
) (*ResolutionResult, error)

ResolveMultipleRoots resolves transitive dependencies for multiple root packages. Used for projects with multiple direct dependencies.

func (*TransitiveResolver) ResolveTransitive

func (tr *TransitiveResolver) ResolveTransitive(
	ctx context.Context,
	packageID string,
	versionRange string,
) (*ResolutionResult, error)

ResolveTransitive resolves all transitive dependencies for a package. Returns a flattened list of all unique packages in the dependency graph.

type UnresolvedPackage

type UnresolvedPackage struct {
	// ID is the package identifier
	ID string

	// VersionRange is the requested version range
	VersionRange string

	// TargetFramework where this was unresolved (empty for all)
	TargetFramework string

	// ErrorCode is the NuGet error code (NU1101, NU1102, NU1103)
	ErrorCode string

	// Message is the detailed error message
	Message string

	// Sources lists sources that were checked
	Sources []string

	// AvailableVersions lists versions found (for NU1102)
	AvailableVersions []string

	// NearestVersion is the closest version found (for NU1102)
	NearestVersion string
}

UnresolvedPackage represents a package that could not be resolved. Maps to NuGet's LibraryRange with LibraryType.Unresolved.

type VersionConflict

type VersionConflict struct {
	PackageID string
	Versions  []string
	Paths     [][]string // Path from root to each conflicting version
}

VersionConflict represents a version conflict between dependencies

type WalkerCache

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

WalkerCache caches package metadata lookups for the dependency walker. Uses two-tier caching: operation cache for in-flight operations, result cache for completed lookups.

func NewWalkerCache

func NewWalkerCache() *WalkerCache

NewWalkerCache creates a new walker cache

func (*WalkerCache) GetOrFetch

func (c *WalkerCache) GetOrFetch(
	ctx context.Context,
	key string,
	fetcher func(context.Context) (*PackageDependencyInfo, error),
) (*PackageDependencyInfo, error)

GetOrFetch gets cached result or fetches via operation

type WalkerStackState

type WalkerStackState struct {
	// Node being processed
	Node *GraphNode

	// Dependency creation tasks (started but not yet awaited)
	DependencyTasks []*DependencyFetchTask

	// Current index in DependencyTasks
	Index int

	// OuterEdge for this frame
	OuterEdge *GraphEdge
}

WalkerStackState represents the state of a single frame in the manual stack traversal. Matches NuGet.Client's GraphNodeStackState.

Jump to

Keyboard shortcuts

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