fix: Bug with transitive dependency resolution

This commit is contained in:
abhisek
2025-05-15 14:33:46 +05:30
parent a399e2f59c
commit 0c2a2ec0b2
7 changed files with 46 additions and 19 deletions
+13 -13
View File
@@ -3,6 +3,7 @@ package packagemanager
import (
"context"
"fmt"
"slices"
packagev1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/package/v1"
"github.com/safedep/dry/log"
@@ -71,7 +72,7 @@ func (r *dependencyResolver) resolvePackageDependenciesRecursive(
return err
}
log.Warnf("error resolving package dependencies: %w", err)
log.Warnf("error resolving package dependencies: %s", err)
return nil
}
@@ -103,28 +104,20 @@ func (r *dependencyResolver) resolvePackageDependenciesRecursive(
dependencies = append(dependencies, dependencyList.DevDependencies...)
}
// Create package version objects for all dependencies
// Create package version objects for all dependencies and clean versions
resolvedDependencies := make([]*packagev1.PackageVersion, 0, len(dependencies))
for _, dependency := range dependencies {
depPackageVersion := &packagev1.PackageVersion{
resolvedDependencies = append(resolvedDependencies, &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 {
if r.config.IncludeTransitiveDependencies && depth < r.config.TransitiveDepth {
for _, dependency := range resolvedDependencies {
err := r.resolvePackageDependenciesRecursive(ctx, pd, dependency, depth+1, visitedPackages, result)
if err != nil {
@@ -133,6 +126,13 @@ func (r *dependencyResolver) resolvePackageDependenciesRecursive(
}
}
// Finally add resolved dependencies to the result
for _, dependency := range resolvedDependencies {
if !slices.Contains(*result, dependency) {
*result = append(*result, dependency)
}
}
return nil
}
+1 -1
View File
@@ -20,7 +20,7 @@ type NpmDependencyResolverConfig struct {
func NewDefaultNpmDependencyResolverConfig() NpmDependencyResolverConfig {
return NpmDependencyResolverConfig{
IncludeDevDependencies: true,
IncludeDevDependencies: false,
IncludeTransitiveDependencies: true,
TransitiveDepth: 5,
FailFast: false,
+10 -2
View File
@@ -91,8 +91,16 @@ func TestNpmDependencyResolver_ResolveDependencies(t *testing.T) {
assertFn: func(t *testing.T, dependencies []*packagev1.PackageVersion, err error) {
require.NoError(t, err)
require.Equal(t, 2, len(dependencies))
require.Equal(t, "loose-envify", dependencies[0].Package.Name)
require.Equal(t, "react-dom", dependencies[1].Package.Name)
packageNames := []string{}
for _, dep := range dependencies {
packageNames = append(packageNames, dep.Package.Name)
}
require.ElementsMatch(t, []string{
"loose-envify",
"js-tokens",
}, packageNames)
},
},
{