mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
Remove refactored source files
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
package packagemanager
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
packagev1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/package/v1"
|
||||
"github.com/safedep/dry/log"
|
||||
"github.com/safedep/dry/packageregistry"
|
||||
)
|
||||
|
||||
type dependencyResolverConfig struct {
|
||||
IncludeDevDependencies bool
|
||||
IncludeTransitiveDependencies bool
|
||||
TransitiveDepth int
|
||||
FailFast bool
|
||||
}
|
||||
|
||||
type dependencyResolver struct {
|
||||
client packageregistry.Client
|
||||
config dependencyResolverConfig
|
||||
}
|
||||
|
||||
func newDependencyResolver(client packageregistry.Client, config dependencyResolverConfig) *dependencyResolver {
|
||||
return &dependencyResolver{
|
||||
client: client,
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *dependencyResolver) resolveDependencies(ctx context.Context,
|
||||
packageVersion *packagev1.PackageVersion) ([]*packagev1.PackageVersion, error) {
|
||||
pd, err := r.client.PackageDiscovery()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get package discovery: %w", err)
|
||||
}
|
||||
|
||||
// Track visited packages to avoid cycles
|
||||
visitedPackages := make(map[string]bool)
|
||||
|
||||
// Result collection
|
||||
dependencies := make([]*packagev1.PackageVersion, 0)
|
||||
|
||||
// Start recursive resolution
|
||||
err = r.resolvePackageDependenciesRecursive(ctx, pd, packageVersion, 0, visitedPackages, &dependencies)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve dependencies: %w", err)
|
||||
}
|
||||
|
||||
return dependencies, nil
|
||||
}
|
||||
|
||||
// resolvePackageDependenciesRecursive resolves dependencies for a package version recursively
|
||||
func (r *dependencyResolver) resolvePackageDependenciesRecursive(
|
||||
ctx context.Context,
|
||||
pd packageregistry.PackageDiscovery,
|
||||
packageVersion *packagev1.PackageVersion,
|
||||
depth int,
|
||||
visitedPackages map[string]bool,
|
||||
result *[]*packagev1.PackageVersion) error {
|
||||
|
||||
// Check for context cancellation
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
ff := func(err error) error {
|
||||
if r.config.FailFast {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Warnf("error resolving package dependencies: %w", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check depth limit
|
||||
if depth > r.config.TransitiveDepth {
|
||||
return ff(fmt.Errorf("exceeded maximum transitive depth of %d", r.config.TransitiveDepth))
|
||||
}
|
||||
|
||||
// Skip if already visited
|
||||
packageKey := r.packageKey(packageVersion)
|
||||
if visitedPackages[packageKey] {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Mark the current package as visited
|
||||
visitedPackages[packageKey] = true
|
||||
|
||||
log.Debugf("resolving dependencies for %s@%s", packageVersion.Package.Name, packageVersion.Version)
|
||||
|
||||
// Get dependencies for the current package
|
||||
dependencyList, err := pd.GetPackageDependencies(packageVersion.Package.Name, packageVersion.Version)
|
||||
if err != nil {
|
||||
return ff(fmt.Errorf("failed to get package dependencies: %w", err))
|
||||
}
|
||||
|
||||
// Collect all dependencies (and optionally dev dependencies)
|
||||
dependencies := dependencyList.Dependencies
|
||||
if r.config.IncludeDevDependencies {
|
||||
dependencies = append(dependencies, dependencyList.DevDependencies...)
|
||||
}
|
||||
|
||||
// Create package version objects for all dependencies
|
||||
resolvedDependencies := make([]*packagev1.PackageVersion, 0, len(dependencies))
|
||||
for _, dependency := range dependencies {
|
||||
depPackageVersion := &packagev1.PackageVersion{
|
||||
Package: &packagev1.Package{
|
||||
Ecosystem: packagev1.Ecosystem_ECOSYSTEM_NPM,
|
||||
Name: dependency.Name,
|
||||
},
|
||||
Version: npmCleanVersion(dependency.VersionSpec),
|
||||
}
|
||||
|
||||
// Check if this dependency is already in the result to avoid duplicates
|
||||
depKey := r.packageKey(depPackageVersion)
|
||||
if !visitedPackages[depKey] {
|
||||
resolvedDependencies = append(resolvedDependencies, depPackageVersion)
|
||||
*result = append(*result, depPackageVersion)
|
||||
visitedPackages[depKey] = true
|
||||
}
|
||||
}
|
||||
|
||||
// Process transitive dependencies if enabled
|
||||
if r.config.IncludeTransitiveDependencies {
|
||||
for _, dependency := range resolvedDependencies {
|
||||
err := r.resolvePackageDependenciesRecursive(ctx, pd, dependency, depth+1, visitedPackages, result)
|
||||
if err != nil {
|
||||
return ff(fmt.Errorf("failed to resolve transitive dependency: %w", err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *dependencyResolver) packageKey(pkg *packagev1.PackageVersion) string {
|
||||
return fmt.Sprintf("%s@%s", pkg.Package.Name, pkg.Version)
|
||||
}
|
||||
Reference in New Issue
Block a user