mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
76 lines
2.1 KiB
Go
76 lines
2.1 KiB
Go
// Package registry provides interfaces and implementations for fetching dependencies
|
|
// from various package registries (npm, pypi, go, etc.)
|
|
package registry
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/safedep/pmg/pkg/models"
|
|
)
|
|
|
|
// Fetcher defines the interface for registry dependency fetchers
|
|
type Fetcher interface {
|
|
// GetDependencyTree returns the complete dependency tree for a package
|
|
GetDependencyTree(ctx context.Context, pkg models.Package) (*models.DependencyNode, error)
|
|
|
|
// GetFlattenedDependencies returns a list of all dependencies as package@version strings
|
|
GetFlattenedDependencies(ctx context.Context, packageName, version string) ([]string, error)
|
|
}
|
|
|
|
// BaseFetcher implements common functionality for all registry fetchers
|
|
type BaseFetcher struct {
|
|
visitedMu sync.RWMutex
|
|
visited map[string]bool
|
|
client RegistryClient
|
|
}
|
|
|
|
// NewBaseFetcher creates a new BaseFetcher with the specified registry client
|
|
func NewBaseFetcher(client RegistryClient) *BaseFetcher {
|
|
return &BaseFetcher{
|
|
visited: make(map[string]bool),
|
|
client: client,
|
|
}
|
|
}
|
|
|
|
// isVisited checks if a package has already been visited
|
|
func (bf *BaseFetcher) isVisited(key string) bool {
|
|
bf.visitedMu.RLock()
|
|
defer bf.visitedMu.RUnlock()
|
|
return bf.visited[key]
|
|
}
|
|
|
|
// markVisited marks a package as visited
|
|
func (bf *BaseFetcher) markVisited(key string) {
|
|
bf.visitedMu.Lock()
|
|
defer bf.visitedMu.Unlock()
|
|
bf.visited[key] = true
|
|
}
|
|
|
|
// cacheKey generates a unique key for a package
|
|
func cacheKey(pkg models.Package) string {
|
|
return fmt.Sprintf("%s@%s", pkg.Name, pkg.Version)
|
|
}
|
|
|
|
// flattenDependencyTree recursively converts a dependency tree to a flat list of strings
|
|
func flattenDependencyTree(node *models.DependencyNode, result *[]string) {
|
|
if node == nil {
|
|
return
|
|
}
|
|
|
|
depString := fmt.Sprintf("%s@%s", node.Name, node.Version)
|
|
*result = append(*result, depString)
|
|
|
|
for _, dep := range node.Dependencies {
|
|
flattenDependencyTree(dep, result)
|
|
}
|
|
}
|
|
|
|
// resetVisited resets the visited packages map
|
|
func (bf *BaseFetcher) resetVisited() {
|
|
bf.visitedMu.Lock()
|
|
defer bf.visitedMu.Unlock()
|
|
bf.visited = make(map[string]bool)
|
|
}
|