86 lines
1.9 KiB
Go
86 lines
1.9 KiB
Go
package app
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"forge.cadoles.com/arcad/edge/pkg/bundle"
|
|
"github.com/pkg/errors"
|
|
"golang.org/x/mod/semver"
|
|
"gopkg.in/yaml.v2"
|
|
)
|
|
|
|
type ID string
|
|
|
|
type Manifest struct {
|
|
ID ID `yaml:"id" json:"id"`
|
|
Version string `yaml:"version" json:"version"`
|
|
Title string `yaml:"title" json:"title"`
|
|
Description string `yaml:"description" json:"description"`
|
|
Tags []string `yaml:"tags" json:"tags"`
|
|
Metadata MapStr `yaml:"metadata" json:"metadata"`
|
|
}
|
|
|
|
type MetadataValidator func(map[string]any) (bool, error)
|
|
|
|
func (m *Manifest) Validate(validators ...MetadataValidator) (bool, error) {
|
|
if m.ID == "" {
|
|
return false, errors.New("'id' property should not be empty")
|
|
}
|
|
|
|
if m.Version == "" {
|
|
return false, errors.New("'version' property should not be empty")
|
|
}
|
|
|
|
version := m.Version
|
|
if !strings.HasPrefix(version, "v") {
|
|
version = "v" + version
|
|
}
|
|
|
|
if !semver.IsValid(version) {
|
|
return false, errors.Errorf("version '%s' does not respect semver format", m.Version)
|
|
}
|
|
|
|
if m.Title == "" {
|
|
return false, errors.New("'title' property should not be empty")
|
|
}
|
|
|
|
if m.Tags != nil {
|
|
for _, t := range m.Tags {
|
|
if strings.ContainsAny(t, " \t\n\r") {
|
|
return false, errors.Errorf("tag '%s' should not contain any space or new line", t)
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, v := range validators {
|
|
valid, err := v(m.Metadata)
|
|
if !valid || err != nil {
|
|
return valid, errors.WithStack(err)
|
|
}
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
func LoadManifest(b bundle.Bundle) (*Manifest, error) {
|
|
reader, _, err := b.File("manifest.yml")
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "could not read manifest.yml")
|
|
}
|
|
|
|
defer func() {
|
|
if err := reader.Close(); err != nil {
|
|
panic(errors.WithStack(err))
|
|
}
|
|
}()
|
|
|
|
manifest := &Manifest{}
|
|
|
|
decoder := yaml.NewDecoder(reader)
|
|
if err := decoder.Decode(manifest); err != nil {
|
|
return nil, errors.Wrap(err, "could not decode manifest.yml")
|
|
}
|
|
|
|
return manifest, nil
|
|
}
|