2022-11-02 01:56:57 +01:00
|
|
|
package schema
|
|
|
|
|
|
|
|
import (
|
2022-11-02 16:31:12 +01:00
|
|
|
"context"
|
2022-11-02 20:25:55 +01:00
|
|
|
"crypto/sha256"
|
|
|
|
"encoding/hex"
|
2022-11-02 16:31:12 +01:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
2022-11-02 01:56:57 +01:00
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
type CharSchemaPluginName string
|
|
|
|
|
2022-11-02 20:25:55 +01:00
|
|
|
func (cspn CharSchemaPluginName) Hash() string {
|
|
|
|
bytes := sha256.Sum256([]byte(cspn))
|
|
|
|
return hex.EncodeToString(bytes[:])
|
|
|
|
}
|
|
|
|
|
2022-11-02 01:56:57 +01:00
|
|
|
type PluginOps struct {
|
|
|
|
Org string
|
|
|
|
RepositoryName string
|
|
|
|
Path string
|
|
|
|
Version string
|
|
|
|
}
|
|
|
|
|
2022-11-02 16:31:12 +01:00
|
|
|
type GitProtocol string
|
|
|
|
|
|
|
|
const (
|
|
|
|
GitProtocolHttps GitProtocol = "https"
|
|
|
|
GitProtocolSsh = "ssh"
|
|
|
|
)
|
|
|
|
|
|
|
|
type CloneUrlOpt struct {
|
|
|
|
Protocol GitProtocol
|
|
|
|
SshUser string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (po *PluginOps) GetCloneUrl(ctx context.Context, registry string, opt *CloneUrlOpt) (string, error) {
|
|
|
|
if opt == nil {
|
|
|
|
return "", errors.New("opt is required")
|
|
|
|
}
|
|
|
|
switch opt.Protocol {
|
|
|
|
case GitProtocolHttps:
|
|
|
|
return fmt.Sprintf("https://%s/%s/%s.git", registry, po.Org, po.RepositoryName), nil
|
|
|
|
case GitProtocolSsh:
|
|
|
|
return fmt.Sprintf("%s@%s:%s/%s.git", opt.SshUser, registry, po.Org, po.RepositoryName), nil
|
|
|
|
default:
|
|
|
|
return "", errors.New("protocol not allowed")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var memo = map[string]*PluginOps{}
|
|
|
|
|
|
|
|
func (cspn CharSchemaPluginName) Get() (*PluginOps, error) {
|
|
|
|
if m, ok := memo[string(cspn)]; ok {
|
|
|
|
return m, nil
|
|
|
|
}
|
|
|
|
|
2022-11-02 01:56:57 +01:00
|
|
|
po := &PluginOps{}
|
|
|
|
reg := regexp.MustCompile(
|
|
|
|
`(?P<org>[\d\w\-_\.]+)\/(?P<repo>[\d\w\-_\.]+)(?P<path>#[\d\w\-_\.\/]+)?(?P<version>@[\d\w\-_\.\/]+)?(?P<path>#[\d\w\-_\.\/]+)?`,
|
|
|
|
)
|
|
|
|
matches := reg.FindStringSubmatch(string(cspn))
|
|
|
|
tags := reg.SubexpNames()
|
|
|
|
|
|
|
|
matchTags := make(map[string]string, len(matches))
|
|
|
|
for i, match := range matches {
|
|
|
|
tag := tags[i]
|
|
|
|
if existingTag, ok := matchTags[tag]; !ok || existingTag == "" {
|
|
|
|
matchTags[tag] = match
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if org, ok := matchTags["org"]; ok {
|
|
|
|
po.Org = org
|
|
|
|
}
|
|
|
|
if repo, ok := matchTags["repo"]; ok {
|
|
|
|
po.RepositoryName = repo
|
|
|
|
}
|
|
|
|
if path, ok := matchTags["path"]; ok {
|
|
|
|
po.Path = strings.TrimLeft(path, "#")
|
|
|
|
}
|
|
|
|
if version, ok := matchTags["version"]; ok {
|
|
|
|
po.Version = strings.TrimLeft(version, "@")
|
|
|
|
}
|
|
|
|
|
2022-11-02 16:31:12 +01:00
|
|
|
if po.Org == "" || po.RepositoryName == "" {
|
|
|
|
return nil, errors.New("could not find org or repository name")
|
|
|
|
}
|
|
|
|
|
|
|
|
memo[string(cspn)] = po
|
|
|
|
|
|
|
|
return po, nil
|
2022-11-02 01:56:57 +01:00
|
|
|
}
|
|
|
|
|
2022-11-02 16:48:33 +01:00
|
|
|
type CharSchemaPlugins map[CharSchemaPluginName]*CharSchemaPlugin
|
2022-11-02 22:10:15 +01:00
|
|
|
type CharSchemaPluginVarName string
|
|
|
|
type CharSchemaPluginVars map[CharSchemaPluginVarName]string
|
2022-11-02 01:56:57 +01:00
|
|
|
|
|
|
|
type CharSchemaPlugin struct {
|
2022-11-02 16:48:33 +01:00
|
|
|
Opts *PluginOps
|
2022-11-02 22:10:15 +01:00
|
|
|
Vars CharSchemaPluginVars `json:"vars"`
|
2022-11-02 01:56:57 +01:00
|
|
|
}
|