Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Parse function to pkgecosystem, use in ResolvePackage #769

Merged
merged 3 commits into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions internal/worker/resolvepackage.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ func ResolvePkg(manager *pkgmanager.PkgManager, name, version, localPath string)
// ResolvePurl creates a Pkg object from the given purl
// See https://github.com/package-url/purl-spec
func ResolvePurl(purl packageurl.PackageURL) (*pkgmanager.Pkg, error) {
var ecosystem pkgecosystem.Ecosystem
if err := ecosystem.UnmarshalText([]byte(purl.Type)); err != nil {
return nil, fmt.Errorf("unsupported package ecosystem '%s'", purl.Type)
ecosystem, err := pkgecosystem.ParsePurlType(purl.Type)
if err != nil {
return nil, err
}

manager := pkgmanager.Manager(ecosystem)
if manager == nil {
return nil, fmt.Errorf("unsupported package ecosystem '%s'", purl.Type)
return nil, pkgecosystem.Unsupported(purl.Type)
}

// Prepend package namespace to package name, if present
Expand Down
52 changes: 44 additions & 8 deletions pkg/api/pkgecosystem/ecosystem.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// The pkgecosystem package defines the open source ecosystems supported by Package Analysis.
// Package pkgecosystem defines the open source ecosystems supported by Package Analysis.
package pkgecosystem

import (
Expand All @@ -25,6 +25,12 @@ const (
// correspond to a defined ecosystem constant is passed in as a parameter.
var ErrUnsupported = errors.New("ecosystem unsupported")

// Unsupported returns a new ErrUnsupported that adds the unsupported ecosystem name
// to the error message
func Unsupported(name string) error {
return fmt.Errorf("%w: %s", ErrUnsupported, name)
}

// SupportedEcosystems is a list of all the ecosystems supported.
var SupportedEcosystems = []Ecosystem{
CratesIO,
Expand All @@ -43,14 +49,14 @@ var SupportedEcosystemsStrings = EcosystemsAsStrings(SupportedEcosystems)
// It will only succeed when unmarshaling ecosytems in SupportedEcosystems or
// empty.
func (e *Ecosystem) UnmarshalText(text []byte) error {
search := string(text)
for _, s := range append(SupportedEcosystems, None) {
if string(s) == search {
*e = s
return nil
}
ecosystem, err := Parse(string(text))

if err != nil {
return err
}
return fmt.Errorf("%w: %s", ErrUnsupported, text)

*e = ecosystem
return nil
}

// MarshalText implements the encoding.TextMarshaler interface.
Expand All @@ -71,3 +77,33 @@ func EcosystemsAsStrings(es []Ecosystem) []string {
}
return s
}

// Parse returns an Ecosystem corresponding to the given string name, or
// the None ecosystem along with an error if there is no matching Ecosystem.
// If name == "", then the None ecosystem is returned with no error.
func Parse(name string) (Ecosystem, error) {
for _, s := range append(SupportedEcosystems, None) {
if string(s) == name {
maxfisher-g marked this conversation as resolved.
Show resolved Hide resolved
return s, nil
}
}

return None, Unsupported(name)
}

// ParsePurlType converts from a Package URL type, defined at
// https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst
// to an Ecosystem object
func ParsePurlType(purlType string) (Ecosystem, error) {
switch purlType {
case "cargo":
return CratesIO, nil
case "composer":
return Packagist, nil
case "gem":
return RubyGems, nil
default:
// we use the same name for NPM and PyPI as the purl type string
return Parse(purlType)
}
}