func/repository.go

124 lines
3.2 KiB
Go

package function
import (
"errors"
"io/ioutil"
"path/filepath"
"strings"
"github.com/markbates/pkger"
)
// Path to builtin repositories.
// note: this constant must be defined in the same file in which it is used due
// to pkger performing static analysis on source files separately.
const builtinRepositories = "/templates"
// Repository
type Repository struct {
Name string
Templates []Template
Runtimes []string
}
// NewRepository from path.
// Represents the file structure of 'path' at time of construction as
// a Repository with Templates, each of which has a Name and its Runtime.
// a convenience member of Runtimes is the unique, sorted list of all
// runtimes
func NewRepositoryFromPath(path string) (Repository, error) {
// TODO: read and use manifest if it exists
r := Repository{
Name: filepath.Base(path),
Templates: []Template{},
Runtimes: []string{}}
// Each subdirectory is a Runtime
runtimes, err := ioutil.ReadDir(path)
if err != nil {
return r, err
}
for _, runtime := range runtimes {
if !runtime.IsDir() || strings.HasPrefix(runtime.Name(), ".") {
continue // ignore files and hidden
}
r.Runtimes = append(r.Runtimes, runtime.Name())
// Each subdirectory is a Template
templates, err := ioutil.ReadDir(filepath.Join(path, runtime.Name()))
if err != nil {
return r, err
}
for _, template := range templates {
if !template.IsDir() || strings.HasPrefix(template.Name(), ".") {
continue // ignore files and hidden
}
r.Templates = append(r.Templates, Template{
Runtime: runtime.Name(),
Repository: r.Name,
Name: template.Name()})
}
}
return r, nil
}
// NewRepository from builtin (encoded ./templates)
func NewRepositoryFromBuiltin() (Repository, error) {
r := Repository{
Name: DefaultRepository,
Templates: []Template{},
Runtimes: []string{}}
// Read in runtimes
dir, err := pkger.Open(builtinRepositories)
if err != nil {
return r, err
}
runtimes, err := dir.Readdir(-1)
if err != nil {
return r, err
}
for _, runtime := range runtimes {
if !runtime.IsDir() || strings.HasPrefix(runtime.Name(), ".") {
continue // ignore from runtimes non-directory or hidden items
}
r.Runtimes = append(r.Runtimes, runtime.Name())
// Each subdirectory is a Template
templateDir, err := pkger.Open(filepath.Join(builtinRepositories, runtime.Name()))
if err != nil {
return r, err
}
templates, err := templateDir.Readdir(-1)
if err != nil {
return r, err
}
for _, template := range templates {
if !template.IsDir() || strings.HasPrefix(template.Name(), ".") {
continue // ignore from templates non-directory or hidden items
}
r.Templates = append(r.Templates, Template{
Runtime: runtime.Name(),
Repository: r.Name,
Name: template.Name(),
})
}
}
return r, nil
}
// GetTemplate from repo with given runtime
func (r *Repository) GetTemplate(runtime, name string) (Template, error) {
// TODO: return a typed RuntimeNotFound in repo X
// rather than the generic Template Not Found
for _, t := range r.Templates {
if t.Runtime == runtime && t.Name == name {
return t, nil
}
}
// TODO: Typed TemplateNotFound in repo X
return Template{}, errors.New("template not found")
}