enrichment

package module
v0.6.4 Latest Latest
Warning

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

Go to latest
Published: Jul 27, 2026 License: MIT Imports: 23 Imported by: 2

README

enrichment

A Go library for fetching package metadata from multiple sources using PURLs. It queries the ecosyste.ms API, deps.dev, or package registries directly, and returns a unified PackageInfo struct with license, version, description, repository, changelog, funding, and maintainer information.

Install

go get github.com/git-pkgs/enrichment

Usage

client, err := enrichment.NewClient()
if err != nil {
    log.Fatal(err)
}

// Look up multiple packages at once
results, err := client.BulkLookup(ctx, []string{
    "pkg:npm/lodash",
    "pkg:pypi/requests",
})

// Get all versions of a package
versions, err := client.GetVersions(ctx, "pkg:npm/lodash")

// Get a specific version
version, err := client.GetVersion(ctx, "pkg:npm/lodash@4.17.21")

By default NewClient uses a hybrid strategy: PURLs with a repository_url qualifier go straight to the registry, everything else goes through ecosyste.ms. Set GIT_PKGS_DIRECT=1 or git config --global pkgs.direct true to skip ecosyste.ms and query all registries directly.

You can also construct a specific client if you want to control the source:

eco, _ := enrichment.NewEcosystemsClient()  // ecosyste.ms API only
reg := enrichment.NewRegistriesClient()      // direct registry queries only
dep := enrichment.NewDepsDevClient()         // deps.dev API only

The ecosyste.ms client can also fan out from a source repository URL to the packages published from that repository and their dependent packages:

groups, err := eco.GetDependentsByRepositoryURL(ctx, "https://github.com/rails/rails", 25, 30)
for _, group := range groups {
    fmt.Printf("%s has %d dependent packages\n", group.PackageName, len(group.Dependents))
}

Vulnerabilities, Licenses, and Versions

vulns, err := enrichment.CheckVulnerabilities(ctx, "npm", "lodash", "4.17.20")
for _, vuln := range vulns {
    fmt.Printf("%s: %s fixed in %s\n", vuln.ID, vuln.Severity, vuln.FixedVersion)
}

category := enrichment.CategorizeLicense("MIT OR Apache-2.0") // permissive
outdated := enrichment.IsOutdated("1.0.0", "1.2.0")           // true

Vulnerability checks use OSV by default. License categorization and version comparison are local helpers, so they continue to work in direct/private registry environments.

Scorecard

The scorecard sub-package queries the OpenSSF Scorecard API for repository-level security scores.

client := scorecard.New()
result, err := client.GetScore(ctx, "github.com/lodash/lodash")
fmt.Println(result.Score) // 6.8

End of Life

The endoflife sub-package queries the endoflife.date API for product lifecycle data -- release dates, EOL dates, LTS status, and support windows.

client := endoflife.New()

// All tracked products
products, err := client.GetAllProducts(ctx)

// All release cycles for a product
cycles, err := client.GetProduct(ctx, "nodejs")
for _, c := range cycles {
    fmt.Printf("%s: eol=%v lts=%v\n", c.Name, c.IsEOL(), c.IsLTS())
}

// Single cycle
cycle, err := client.GetCycle(ctx, "python", "3.12")
fmt.Println(cycle.Latest, cycle.IsEOL())

The eol, lts, support, and extendedSupport fields from the API can be either a date or a boolean. The DateOrBool type handles both, and the IsEOL(), IsSupported(), and IsLTS() methods on Cycle do the right thing regardless.

License

MIT

Documentation

Overview

Package enrichment provides a unified interface for fetching package metadata from external sources (ecosyste.ms API, direct registry queries, deps.dev).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsOutdated added in v0.5.0

func IsOutdated(current, latest string) bool

IsOutdated reports whether current is older than latest.

Types

type Advisory added in v0.2.1

type Advisory struct {
	Title       string
	Severity    string // e.g. "critical", "high", "medium", "low"
	CVSSScore   float32
	URL         string
	Identifiers []string // CVE IDs and other identifiers
}

Advisory is a security advisory affecting a package.

type Client

type Client interface {
	// BulkLookup fetches metadata for multiple packages by PURL.
	// Returns a map of PURL to PackageInfo. Missing packages are omitted.
	BulkLookup(ctx context.Context, purls []string) (map[string]*PackageInfo, error)

	// GetVersions fetches all versions for a package.
	// The purl should be a package PURL without version (pkg:npm/lodash).
	GetVersions(ctx context.Context, purl string) ([]VersionInfo, error)

	// GetVersion fetches metadata for a specific version.
	// The purl must include a version (pkg:npm/lodash@4.17.21).
	GetVersion(ctx context.Context, purl string) (*VersionInfo, error)
}

Client fetches package metadata from external sources.

func NewClient

func NewClient(opts ...Option) (Client, error)

NewClient creates an enrichment client based on configuration.

By default, uses a hybrid approach:

  • PURLs with repository_url qualifier -> direct registry query
  • Other PURLs -> ecosyste.ms API

To skip ecosyste.ms and query all registries directly:

  • Set GIT_PKGS_DIRECT=1 environment variable, or
  • Set git config: git config --global pkgs.direct true

type DependentPackage added in v0.6.0

type DependentPackage struct {
	Ecosystem           string
	Name                string
	PURL                string
	Repository          string
	RegistryURL         string
	LatestVersion       string
	Downloads           int
	DependentReposCount int
}

DependentPackage contains metadata for one package that depends on another.

type DepsDevClient

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

DepsDevClient queries the deps.dev v3 REST API.

func NewDepsDevClient

func NewDepsDevClient() *DepsDevClient

NewDepsDevClient creates a client for the deps.dev API.

func (*DepsDevClient) BulkLookup

func (c *DepsDevClient) BulkLookup(ctx context.Context, purls []string) (map[string]*PackageInfo, error)

func (*DepsDevClient) GetVersion

func (c *DepsDevClient) GetVersion(ctx context.Context, purlStr string) (*VersionInfo, error)

func (*DepsDevClient) GetVersions

func (c *DepsDevClient) GetVersions(ctx context.Context, purlStr string) ([]VersionInfo, error)

type EcosystemsClient

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

EcosystemsClient wraps the ecosyste.ms API client.

func NewEcosystemsClient

func NewEcosystemsClient() (*EcosystemsClient, error)

NewEcosystemsClient creates a client that uses the ecosyste.ms API.

func (*EcosystemsClient) BulkLookup

func (c *EcosystemsClient) BulkLookup(ctx context.Context, purls []string) (map[string]*PackageInfo, error)

func (*EcosystemsClient) GetDependentsByRepositoryURL added in v0.6.0

func (c *EcosystemsClient) GetDependentsByRepositoryURL(ctx context.Context, repositoryURL string, maxPackages, maxDependentsPerPackage int) ([]RepositoryDependents, error)

GetDependentsByRepositoryURL finds packages published from repositoryURL and fetches dependent packages for each of them.

func (*EcosystemsClient) GetVersion

func (c *EcosystemsClient) GetVersion(ctx context.Context, purlStr string) (*VersionInfo, error)

func (*EcosystemsClient) GetVersions

func (c *EcosystemsClient) GetVersions(ctx context.Context, purlStr string) ([]VersionInfo, error)

type HybridClient

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

HybridClient routes requests based on PURL qualifiers. PURLs with repository_url go to registries, others go to ecosyste.ms.

func NewHybridClient

func NewHybridClient() (*HybridClient, error)

NewHybridClient creates a client that routes based on PURL qualifiers.

func (*HybridClient) BulkLookup

func (c *HybridClient) BulkLookup(ctx context.Context, purls []string) (map[string]*PackageInfo, error)

func (*HybridClient) GetVersion

func (c *HybridClient) GetVersion(ctx context.Context, purlStr string) (*VersionInfo, error)

func (*HybridClient) GetVersions

func (c *HybridClient) GetVersions(ctx context.Context, purlStr string) ([]VersionInfo, error)

type LicenseCategory added in v0.5.0

type LicenseCategory string

LicenseCategory describes the broad policy category for a license expression.

const (
	// LicenseCategoryPermissive is used when every license in the expression is permissive.
	LicenseCategoryPermissive LicenseCategory = "permissive"
	// LicenseCategoryCopyleft is used when the expression contains a copyleft license.
	LicenseCategoryCopyleft LicenseCategory = "copyleft"
	// LicenseCategoryUnknown is used when the expression cannot be classified.
	LicenseCategoryUnknown LicenseCategory = "unknown"
)

func CategorizeLicense added in v0.5.0

func CategorizeLicense(license string) LicenseCategory

CategorizeLicense classifies a license expression as permissive, copyleft, or unknown. This is intentionally conservative: any copyleft license in an expression makes the whole expression copyleft, including OR expressions.

type Maintainer added in v0.3.0

type Maintainer struct {
	Login string
	Name  string
	Email string
	URL   string
	Role  string
}

Maintainer is a person or account that maintains a package on its registry.

type Option

type Option func(*options)

Option configures an enrichment client.

func WithAPIKey added in v0.4.0

func WithAPIKey(key string) Option

WithAPIKey sets the bearer token sent on ecosyste.ms API requests. Ignored by the direct registries client.

func WithBatchSize added in v0.4.0

func WithBatchSize(size int) Option

WithBatchSize sets the per-request batch size for ecosyste.ms bulk lookups. Values <= 0 or above the upstream maximum fall back to the upstream default. Ignored by the direct registries client.

func WithFrom added in v0.4.0

func WithFrom(email string) Option

WithFrom sets the From header (email address) for ecosyste.ms API requests. Identifying the client moves it out of the shared rate-limit pool, which reduces stream-level rejections. Ignored by the direct registries client.

func WithUserAgent

func WithUserAgent(ua string) Option

WithUserAgent sets the User-Agent header for API requests.

type PackageInfo

type PackageInfo struct {
	Ecosystem         string
	Name              string
	LatestVersion     string
	License           string
	Description       string
	Homepage          string
	Repository        string
	RegistryURL       string
	ChangelogFilename string
	Source            string // "ecosystems", "registries", or "depsdev"

	// Popularity and usage (ecosyste.ms only)
	Downloads              int
	DownloadsPeriod        string // e.g. "last-month"
	DependentPackagesCount int
	DependentReposCount    int

	// Security advisories (ecosyste.ms only)
	Advisories []Advisory

	// Funding and maintainers (ecosyste.ms only)
	FundingLinks []string
	Maintainers  []Maintainer
}

PackageInfo contains metadata about a package.

type RegistriesClient

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

RegistriesClient queries package registries directly.

func NewRegistriesClient

func NewRegistriesClient() *RegistriesClient

NewRegistriesClient creates a client that queries registries directly.

func (*RegistriesClient) BulkLookup

func (c *RegistriesClient) BulkLookup(ctx context.Context, purls []string) (map[string]*PackageInfo, error)

func (*RegistriesClient) GetVersion

func (c *RegistriesClient) GetVersion(ctx context.Context, purlStr string) (*VersionInfo, error)

func (*RegistriesClient) GetVersions

func (c *RegistriesClient) GetVersions(ctx context.Context, purlStr string) ([]VersionInfo, error)

type RepositoryDependents added in v0.6.0

type RepositoryDependents struct {
	PackageName string
	Ecosystem   string
	PURL        string
	Dependents  []DependentPackage
}

RepositoryDependents groups dependent packages by one package published from a source repository.

type VersionInfo

type VersionInfo struct {
	Number      string
	PublishedAt time.Time
	Integrity   string
	License     string
	Status      string         // registry-defined status, such as "yanked", "deprecated", or "retracted"
	Yanked      bool           // true when Status is "yanked"; retained for compatibility
	Metadata    map[string]any // registry-specific version metadata
}

VersionInfo contains metadata about a specific version.

type VulnInfo added in v0.5.0

type VulnInfo struct {
	ID           string
	Summary      string
	Details      string
	Severity     string
	CVSSScore    float64
	CVSSVersion  string
	CVSSVector   string
	FixedVersion string
	References   []string
	Aliases      []string
	Source       string
}

VulnInfo contains the vulnerability fields most consumers need for display and policy checks.

func CheckVulnerabilities added in v0.5.0

func CheckVulnerabilities(ctx context.Context, ecosystem, name, version string) ([]VulnInfo, error)

CheckVulnerabilities checks one package version using the default OSV-backed client.

type VulnerabilityClient added in v0.5.0

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

VulnerabilityClient checks package vulnerabilities using a configured source.

func NewVulnerabilityClient added in v0.5.0

func NewVulnerabilityClient(opts ...VulnerabilityOption) *VulnerabilityClient

NewVulnerabilityClient creates a client backed by OSV unless another source is provided.

func (*VulnerabilityClient) Check added in v0.5.0

func (c *VulnerabilityClient) Check(ctx context.Context, ecosystem, name, version string) ([]VulnInfo, error)

Check checks one package version for known vulnerabilities.

func (*VulnerabilityClient) CheckBatch added in v0.5.0

CheckBatch checks multiple package versions for known vulnerabilities.

type VulnerabilityOption added in v0.5.0

type VulnerabilityOption func(*vulnerabilityOptions)

VulnerabilityOption configures a VulnerabilityClient.

func WithVulnerabilitySource added in v0.5.0

func WithVulnerabilitySource(source vulns.Source) VulnerabilityOption

WithVulnerabilitySource sets the vulnerability data source.

func WithVulnerabilityUserAgent added in v0.5.0

func WithVulnerabilityUserAgent(userAgent string) VulnerabilityOption

WithVulnerabilityUserAgent sets the User-Agent for the default OSV source.

type VulnerabilityQuery added in v0.5.0

type VulnerabilityQuery struct {
	Ecosystem string
	Name      string
	Version   string
}

VulnerabilityQuery identifies a package version to check for vulnerabilities.

type VulnerabilityResult added in v0.5.0

type VulnerabilityResult struct {
	Query           VulnerabilityQuery
	Vulnerabilities []VulnInfo
}

VulnerabilityResult contains the vulnerabilities found for a query.

func BulkCheckVulnerabilities added in v0.5.0

func BulkCheckVulnerabilities(ctx context.Context, queries []VulnerabilityQuery) ([]VulnerabilityResult, error)

BulkCheckVulnerabilities checks multiple package versions using the default OSV-backed client.

Directories

Path Synopsis
Package endoflife provides a client for the endoflife.date API.
Package endoflife provides a client for the endoflife.date API.
Package scorecard provides a client for the OpenSSF Scorecard API.
Package scorecard provides a client for the OpenSSF Scorecard API.

Jump to

Keyboard shortcuts

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