code/go/internal/packages/package.go (86 lines of code) (raw):

// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one // or more contributor license agreements. Licensed under the Elastic License; // you may not use this file except in compliance with the Elastic License. package packages import ( "errors" "fmt" "io/fs" "os" "path" "github.com/Masterminds/semver/v3" "gopkg.in/yaml.v3" ) // Package represents an Elastic Package Registry package type Package struct { Name string Type string Version *semver.Version SpecVersion *semver.Version fs fs.FS location string } // Open opens a file in the package filesystem. func (p *Package) Open(name string) (fs.File, error) { return p.fs.Open(name) } // Path returns a path meaningful for the user. func (p *Package) Path(names ...string) string { return path.Join(append([]string{p.location}, names...)...) } // IsGA returns true if the package is GA. func (p *Package) IsGA() bool { if p.Version.Prerelease() != "" { return false } if p.Version.LessThan(semver.MustParse("1.0.0")) { return false } return true } // NewPackage creates a new Package from a path to the package's root folder func NewPackage(pkgRootPath string) (*Package, error) { info, err := os.Stat(pkgRootPath) if os.IsNotExist(err) { return nil, fmt.Errorf("no package found at path [%v]: %w", pkgRootPath, err) } if !info.IsDir() { return nil, fmt.Errorf("no package folder found at path [%v]", pkgRootPath) } return NewPackageFromFS(pkgRootPath, os.DirFS(pkgRootPath)) } // NewPackageFromFS creates a new package from a given filesystem. A root path can be indicated // to help building paths meaningful for the users. func NewPackageFromFS(location string, fsys fs.FS) (*Package, error) { pkgManifestPath := "manifest.yml" _, err := fs.Stat(fsys, pkgManifestPath) if os.IsNotExist(err) { return nil, fmt.Errorf("no package manifest file found at path [%v]: %w", pkgManifestPath, err) } data, err := fs.ReadFile(fsys, pkgManifestPath) if err != nil { return nil, fmt.Errorf("could not read package manifest file [%v]", pkgManifestPath) } var manifest struct { Name string `yaml:"name"` Type string `yaml:"type"` Version string `yaml:"version"` SpecVersion string `yaml:"format_version"` } if err := yaml.Unmarshal(data, &manifest); err != nil { return nil, fmt.Errorf("could not parse package manifest file [%v]: %w", pkgManifestPath, err) } if manifest.Type == "" { return nil, errors.New("package type undefined in the package manifest file") } if manifest.Version == "" { return nil, errors.New("package version undefined in the package manifest file") } packageVersion, err := semver.NewVersion(manifest.Version) if err != nil { return nil, fmt.Errorf("could not read package version from package manifest file [%v]: %w", pkgManifestPath, err) } specVersion, err := semver.NewVersion(manifest.SpecVersion) if err != nil { return nil, fmt.Errorf("could not read specification version from package manifest file [%v]: %w", manifest.SpecVersion, err) } // Instantiate Package object and return it p := Package{ Name: manifest.Name, Type: manifest.Type, Version: packageVersion, SpecVersion: specVersion, fs: fsys, location: location, } return &p, nil }