2020-04-07 12:23:20 +03:00
|
|
|
package console
|
|
|
|
|
|
|
|
import (
|
2021-06-04 10:27:34 +03:00
|
|
|
"embed"
|
2020-04-07 12:23:20 +03:00
|
|
|
"fmt"
|
|
|
|
"html/template"
|
|
|
|
"regexp"
|
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
|
|
|
|
"github.com/gin-gonic/contrib/renders/multitemplate"
|
2021-06-16 14:44:15 +03:00
|
|
|
"github.com/hasura/graphql-engine/cli/v2/version"
|
2020-04-07 12:23:20 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
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
|
2021-05-04 14:58:55 +03:00
|
|
|
GetAssetsCDN() string
|
2020-04-07 12:23:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// DefaultTemplateProvider implements the github.com/hasura/graphl-engine/cli/pkg/templates.DefaultTemplateProvider interface
|
|
|
|
type DefaultTemplateProvider struct {
|
|
|
|
basePath string
|
|
|
|
templateFileName string
|
2021-06-04 10:27:34 +03:00
|
|
|
consoleFS embed.FS
|
2020-04-07 12:23:20 +03:00
|
|
|
}
|
|
|
|
|
2021-06-04 10:27:34 +03:00
|
|
|
func NewDefaultTemplateProvider(basePath, templateFilename string, consoleFS embed.FS) *DefaultTemplateProvider {
|
2020-04-07 12:23:20 +03:00
|
|
|
return &DefaultTemplateProvider{
|
|
|
|
basePath: basePath,
|
|
|
|
templateFileName: templateFilename,
|
2021-06-04 10:27:34 +03:00
|
|
|
consoleFS: consoleFS,
|
2020-04-07 12:23:20 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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 {
|
2021-06-04 10:27:34 +03:00
|
|
|
_, err := p.consoleFS.ReadFile(path)
|
2020-04-07 12:23:20 +03:00
|
|
|
return err == nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *DefaultTemplateProvider) LoadTemplates(path string, templateNames ...string) (multitemplate.Render, error) {
|
|
|
|
r := multitemplate.New()
|
|
|
|
|
|
|
|
for _, templateName := range templateNames {
|
2021-06-04 10:27:34 +03:00
|
|
|
templatePath := path + templateName
|
|
|
|
templateBytes, err := p.consoleFS.ReadFile(templatePath)
|
2020-04-07 12:23:20 +03:00
|
|
|
if err != nil {
|
2021-06-04 10:27:34 +03:00
|
|
|
return nil, errors.Wrap(err, "error reading from file "+templatePath)
|
2020-04-07 12:23:20 +03:00
|
|
|
}
|
|
|
|
theTemplate, err := template.New(templateName).Parse(string(templateBytes))
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "error creating template"+path+templateName)
|
|
|
|
}
|
|
|
|
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 != "" {
|
|
|
|
var re = regexp.MustCompile(`^[a-z]+`)
|
|
|
|
tag := re.FindString(preRelease)
|
2021-05-04 14:58:55 +03:00
|
|
|
// cloud and pro will be tagged like v2.0.0-cloud.9
|
|
|
|
// so, tag will be set as cloud/pro
|
|
|
|
// then assets should be loaded from stable channel
|
|
|
|
if tag != "" && tag != "cloud" && tag != "pro" {
|
2020-04-07 12:23:20 +03:00
|
|
|
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
|
|
|
|
}
|
2021-05-04 14:58:55 +03:00
|
|
|
|
|
|
|
func (p *DefaultTemplateProvider) GetAssetsCDN() string {
|
|
|
|
return "https://graphql-engine-cdn.hasura.io/console/assets"
|
|
|
|
}
|