diff --git a/cmd/char/ls.go b/cmd/char/ls.go index 7d6e691..394a85f 100644 --- a/cmd/char/ls.go +++ b/cmd/char/ls.go @@ -4,6 +4,7 @@ import ( "fmt" "git.front.kjuulh.io/kjuulh/char/pkg/register" + "git.front.kjuulh.io/kjuulh/char/pkg/schema" "github.com/spf13/cobra" ) @@ -13,6 +14,11 @@ func NewLsCommand() *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() + _, err := schema.ParseFile(ctx, ".char.yml") + if err != nil { + return err + } + r, err := register. NewPluginRegisterBuilder(). Add("gocli", "plugins/gocli/main.go"). @@ -32,7 +38,6 @@ func NewLsCommand() *cobra.Command { fmt.Printf("plugin: %s\n", a.Name) fmt.Printf("\tversion: %s\n", a.Version) fmt.Printf("\tabout: %s\n", a.About) - fmt.Println() } return nil diff --git a/examples/basic/char.yml b/examples/basic/.char.yml similarity index 100% rename from examples/basic/char.yml rename to examples/basic/.char.yml diff --git a/examples/basic/benchmark.sh b/examples/basic/benchmark.sh new file mode 100755 index 0000000..25580e4 --- /dev/null +++ b/examples/basic/benchmark.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +go build -o char ../../main.go + +function devcharls() { + CHAR_DEV_MODE=true ./char ls 2&> /dev/null +} + +function charls() { + ./char ls 2&> /dev/null +} + +echo "scratch" +time devcharls +echo "" + +echo "ready" +time charls +echo "" diff --git a/examples/basic/char b/examples/basic/char index 11c065e..57d0959 100755 Binary files a/examples/basic/char and b/examples/basic/char differ diff --git a/go.work.sum b/go.work.sum index 55be116..8b8a60b 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1 +1 @@ -golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/pkg/schema/schema.go b/pkg/schema/schema.go index f209a8b..76372ee 100644 --- a/pkg/schema/schema.go +++ b/pkg/schema/schema.go @@ -1,6 +1,37 @@ package schema +import ( + "context" + "errors" + "fmt" + "os" + + "gopkg.in/yaml.v3" +) + type CharSchema struct { Registry string `json:"registry" yaml:"registry"` Plugins CharSchemaPlugins `json:"plugins" yaml:"plugins"` } + +func ParseFile(ctx context.Context, path string) (*CharSchema, error) { + if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) { + return nil, fmt.Errorf("could not parse file, as it is not found or permitted: %s", path) + } + + file, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("could not read file: %w", err) + } + + var schema CharSchema + if err = yaml.Unmarshal(file, &schema); err != nil { + return nil, fmt.Errorf("could not deserialize yaml file into CharSchema: %w", err) + } + + return &schema, nil +} + +func (cs *CharSchema) GetPlugins(ctx context.Context) (*PluginOps, error) { + return nil, nil +} diff --git a/pkg/schema/schema_plugin.go b/pkg/schema/schema_plugin.go index 2b6f421..57e9764 100644 --- a/pkg/schema/schema_plugin.go +++ b/pkg/schema/schema_plugin.go @@ -1,6 +1,9 @@ package schema import ( + "context" + "errors" + "fmt" "regexp" "strings" ) @@ -14,7 +17,39 @@ type PluginOps struct { Version string } -func (cspn CharSchemaPluginName) Get() *PluginOps { +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 + } + po := &PluginOps{} reg := regexp.MustCompile( `(?P[\d\w\-_\.]+)\/(?P[\d\w\-_\.]+)(?P#[\d\w\-_\.\/]+)?(?P@[\d\w\-_\.\/]+)?(?P#[\d\w\-_\.\/]+)?`, @@ -43,7 +78,13 @@ func (cspn CharSchemaPluginName) Get() *PluginOps { po.Version = strings.TrimLeft(version, "@") } - return po + if po.Org == "" || po.RepositoryName == "" { + return nil, errors.New("could not find org or repository name") + } + + memo[string(cspn)] = po + + return po, nil } type CharSchemaPlugins map[CharSchemaPluginName]CharSchemaPlugin diff --git a/pkg/schema/schema_plugin_test.go b/pkg/schema/schema_plugin_test.go index 7db196d..b291462 100644 --- a/pkg/schema/schema_plugin_test.go +++ b/pkg/schema/schema_plugin_test.go @@ -1,6 +1,7 @@ package schema_test import ( + "context" "testing" "git.front.kjuulh.io/kjuulh/char/pkg/schema" @@ -65,8 +66,61 @@ func TestSchemaNameCanParse(t *testing.T) { for _, tc := range tt { t.Run(tc.name, func(t *testing.T) { - actual := tc.inputString.Get() + actual, _ := tc.inputString.Get() require.Equal(t, tc.expected, *actual) }) } } + +func TestPluginOpt(t *testing.T) { + t.Parallel() + + tt := []struct { + name string + pluginOpt schema.PluginOps + cloneUrlOpt schema.CloneUrlOpt + registry string + expected string + }{ + { + name: "ssh values", + pluginOpt: schema.PluginOps{ + Org: "kjuulh", + RepositoryName: "char", + Path: "", + Version: "", + }, + cloneUrlOpt: schema.CloneUrlOpt{ + Protocol: schema.GitProtocolSsh, + SshUser: "git", + }, + registry: "git.front.kjuulh.io", + expected: "git@git.front.kjuulh.io:kjuulh/char.git", + }, + { + name: "https values", + pluginOpt: schema.PluginOps{ + Org: "kjuulh", + RepositoryName: "char", + Path: "", + Version: "", + }, + cloneUrlOpt: schema.CloneUrlOpt{ + Protocol: schema.GitProtocolHttps, + }, + registry: "git.front.kjuulh.io", + expected: "https://git.front.kjuulh.io/kjuulh/char.git", + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + url, err := tc.pluginOpt.GetCloneUrl(context.Background(), tc.registry, &tc.cloneUrlOpt) + + require.NoError(t, err) + require.Equal(t, tc.expected, url) + + }) + } + +} diff --git a/plugins/gocli/main.go b/plugins/gocli/main.go index cd34804..a9e8c3b 100644 --- a/plugins/gocli/main.go +++ b/plugins/gocli/main.go @@ -7,8 +7,7 @@ import ( "git.front.kjuulh.io/kjuulh/char/pkg/register" ) -type GoCliPlugin struct { -} +type GoCliPlugin struct{} func (*GoCliPlugin) About(ctx context.Context) (*register.About, error) { return ®ister.About{ diff --git a/plugins/rust/main.go b/plugins/rust/main.go index edc957b..1d136e8 100644 --- a/plugins/rust/main.go +++ b/plugins/rust/main.go @@ -7,14 +7,13 @@ import ( "git.front.kjuulh.io/kjuulh/char/pkg/register" ) -type GoCliPlugin struct { -} +type GoCliPlugin struct{} func (*GoCliPlugin) About(ctx context.Context) (*register.About, error) { return ®ister.About{ Name: "rust", Version: "v0.0.1", - About: "golang cli provides a set of actions and presets supporting golang development", + About: "rust cli provides a set of actions and presets supporting rust development", }, nil }