graphql-engine/cli/pkg/console/template.go
2020-04-07 14:53:20 +05:30

152 lines
4.4 KiB
Go

package console
import (
"fmt"
"html/template"
"io/ioutil"
"regexp"
"github.com/pkg/errors"
"github.com/gin-gonic/contrib/renders/multitemplate"
_ "github.com/hasura/graphql-engine/cli/pkg/console/templates/packed"
"github.com/hasura/graphql-engine/cli/version"
"github.com/markbates/pkger"
)
const (
preReleaseVersion = "v1.0-alpha"
unversioned = "unversioned"
versioned = "versioned"
)
type TemplateProvider interface {
// BasePath will return the basepath for the tempalate directory
BasePath() string
// This is the template filename eg: console.html, console2.html
TemplateFilename() string
// DoTemplateExist returns true if an asset exists at pathk
DoTemplateExist(path string) bool
LoadTemplates(path string, templateNames ...string) (multitemplate.Render, error)
// GetTemplateVersion returns the template version tv required to render
// the console html.
GetTemplateVersion(v *version.Version) string
// GetAssetsVersion returns the assets version av to be used in the
// console template. This function is supposed to return the following:
// > input -> output
// > dev-build -> versioned/dev-build
// > v1.0.0-beta.01 -> beta/v1.0
// > v1.0.0-alpha.01 -> alpha/v1.0
// > v1.2.1-rc.03 -> rc/v1.2
// > v1.1.0 -> stable/v1.1
GetAssetsVersion(v *version.Version) string
}
// DefaultTemplateProvider implements the github.com/hasura/graphl-engine/cli/pkg/templates.DefaultTemplateProvider interface
type DefaultTemplateProvider struct {
basePath string
templateFileName string
}
func NewDefaultTemplateProvider(basePath, templateFilename string) *DefaultTemplateProvider {
return &DefaultTemplateProvider{
basePath: basePath,
templateFileName: templateFilename,
}
}
func (p *DefaultTemplateProvider) BasePath() string {
return p.basePath
}
func (p *DefaultTemplateProvider) TemplateFilename() string {
return p.templateFileName
}
// DoTemplateExist returns true if an asset exists at pathk
func (p *DefaultTemplateProvider) DoTemplateExist(path string) bool {
_, err := pkger.Stat(path)
return err == nil
}
func (p *DefaultTemplateProvider) LoadTemplates(path string, templateNames ...string) (multitemplate.Render, error) {
r := multitemplate.New()
for _, templateName := range templateNames {
templateFile, err := pkger.Open(path + templateName)
if err != nil {
return nil, errors.Wrap(err, "error opening file "+path+templateName)
}
templateBytes, err := ioutil.ReadAll(templateFile)
if err != nil {
return nil, errors.Wrap(err, "error reading from file "+path+templateName)
}
theTemplate, err := template.New(templateName).Parse(string(templateBytes))
if err != nil {
return nil, errors.Wrap(err, "error creating template"+path+templateName)
}
err = templateFile.Close()
if err != nil {
return nil, err
}
r.Add(templateName, theTemplate)
}
return r, nil
}
// GetTemplateVersion returns the template version tv required to render
// the console html.
func (p *DefaultTemplateProvider) GetTemplateVersion(v *version.Version) string {
// pre-release builds
if v.Server == "" {
return preReleaseVersion
}
// tagged build
if v.Server != "" {
if v.ServerSemver != nil {
return fmt.Sprintf("v%d.%d", v.ServerSemver.Major(), v.ServerSemver.Minor())
}
}
// untagged version
return unversioned
}
// GetAssetsVersion returns the assets version av to be used in the
// console template. This function is supposed to return the following:
// > input -> output
// > dev-build -> versioned/dev-build
// > v1.0.0-beta.01 -> beta/v1.0
// > v1.0.0-alpha.01 -> alpha/v1.0
// > v1.2.1-rc.03 -> rc/v1.2
// > v1.1.0 -> stable/v1.1
func (p *DefaultTemplateProvider) GetAssetsVersion(v *version.Version) string {
// server has a version
if v.Server != "" {
// version is semver
if v.ServerSemver != nil {
// check for release channels
preRelease := v.ServerSemver.Prerelease()
channel := "stable"
if preRelease != "" {
// Get the correct channel from the prerelease tag
var re = regexp.MustCompile(`^[a-z]+`)
tag := re.FindString(preRelease)
if tag != "" {
channel = tag
}
}
return fmt.Sprintf("channel/%s/v%d.%d", channel, v.ServerSemver.Major(), v.ServerSemver.Minor())
}
// version is not semver
return fmt.Sprintf("%s/%s", versioned, v.Server)
}
// server doesn't have a version - very old server :(
return preReleaseVersion
}