package app import ( "context" "path/filepath" "gitlab.com/wpetit/goweb/logger" "gopkg.in/yaml.v2" "forge.cadoles.com/arcad/edge/pkg/bundle" "github.com/pkg/errors" ) type FilesystemLoader struct { searchPatterns []string } type LoadedApp struct { App *App Bundle bundle.Bundle } func (l *FilesystemLoader) Load(ctx context.Context) ([]*LoadedApp, error) { apps := make([]*LoadedApp, 0) for _, seachPattern := range l.searchPatterns { absSearchPattern, err := filepath.Abs(seachPattern) if err != nil { return nil, errors.Wrapf(err, "could not generate absolute path for '%s'", seachPattern) } logger.Debug(ctx, "searching apps in filesystem", logger.F("searchPattern", absSearchPattern)) files, err := filepath.Glob(absSearchPattern) if err != nil { return nil, errors.Wrapf(err, "could not search files with pattern '%s'", absSearchPattern) } for _, f := range files { loopCtx := logger.With(ctx, logger.F("file", f)) logger.Debug(loopCtx, "found app bundle") b, err := bundle.FromPath(f) if err != nil { logger.Error(loopCtx, "could not load bundle", logger.E(errors.WithStack(err))) continue } logger.Debug(loopCtx, "loading app manifest") appManifest, err := LoadAppManifest(b) if err != nil { logger.Error(loopCtx, "could not load app manifest", logger.E(errors.WithStack(err))) continue } g := &App{ ID: appManifest.ID, Manifest: appManifest, } apps = append(apps, &LoadedApp{ App: g, Bundle: b, }) } } return apps, nil } func NewFilesystemLoader(searchPatterns ...string) *FilesystemLoader { return &FilesystemLoader{ searchPatterns: searchPatterns, } } func LoadAppManifest(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 }