add git clone
This commit is contained in:
parent
ebc2d7aa8f
commit
bace568ad5
@ -3,27 +3,42 @@ package char
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"git.front.kjuulh.io/kjuulh/char/pkg/plugins/provider"
|
||||||
"git.front.kjuulh.io/kjuulh/char/pkg/register"
|
"git.front.kjuulh.io/kjuulh/char/pkg/register"
|
||||||
"git.front.kjuulh.io/kjuulh/char/pkg/schema"
|
"git.front.kjuulh.io/kjuulh/char/pkg/schema"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewLsCommand() *cobra.Command {
|
func NewLsCommand() *cobra.Command {
|
||||||
|
gpp := provider.NewGitPluginProvider()
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "ls",
|
Use: "ls",
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
ctx := cmd.Context()
|
ctx := cmd.Context()
|
||||||
|
|
||||||
_, err := schema.ParseFile(ctx, ".char.yml")
|
s, err := schema.ParseFile(ctx, ".char.yml")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := register.
|
plugins, err := s.GetPlugins(ctx)
|
||||||
NewPluginRegisterBuilder().
|
if err != nil {
|
||||||
Add("gocli", "plugins/gocli/main.go").
|
return err
|
||||||
Add("rust", "plugins/rust/main.go").
|
}
|
||||||
Build(ctx)
|
|
||||||
|
err = gpp.FetchPlugins(ctx, s.Registry, plugins)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
builder := register.NewPluginRegisterBuilder()
|
||||||
|
|
||||||
|
for name, plugin := range plugins {
|
||||||
|
builder = builder.Add(name.Hash(), plugin.Opts.Path)
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err := builder.Build(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1 +0,0 @@
|
|||||||
../../../../
|
|
@ -1 +0,0 @@
|
|||||||
../../../../
|
|
1
examples/basic/.gitignore
vendored
Normal file
1
examples/basic/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.char/plugins/
|
Binary file not shown.
79
pkg/plugins/provider/git.go
Normal file
79
pkg/plugins/provider/git.go
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.front.kjuulh.io/kjuulh/char/pkg/schema"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GitPluginProvider struct{}
|
||||||
|
|
||||||
|
func NewGitPluginProvider() *GitPluginProvider {
|
||||||
|
return &GitPluginProvider{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gpp *GitPluginProvider) FetchPlugins(ctx context.Context, registry string, plugins schema.CharSchemaPlugins) error {
|
||||||
|
errgroup, ctx := errgroup.WithContext(ctx)
|
||||||
|
baseDir := ".char/plugins"
|
||||||
|
if os.Getenv("CHAR_DEV_MODE") == "true" {
|
||||||
|
if err := os.RemoveAll(baseDir); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(baseDir, 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for n, plugin := range plugins {
|
||||||
|
n, plugin := n, plugin
|
||||||
|
errgroup.Go(func() error {
|
||||||
|
log.Printf("fetching git plugin repo: %s", n)
|
||||||
|
return gpp.FetchPlugin(
|
||||||
|
ctx,
|
||||||
|
registry,
|
||||||
|
plugin,
|
||||||
|
fmt.Sprintf(
|
||||||
|
"%s/%s",
|
||||||
|
strings.TrimRight(baseDir, "/"), n.Hash(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := errgroup.Wait(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gpp *GitPluginProvider) FetchPlugin(ctx context.Context, registry string, plugin *schema.CharSchemaPlugin, dest string) error {
|
||||||
|
cloneUrl, err := plugin.Opts.GetCloneUrl(ctx, registry, &schema.CloneUrlOpt{
|
||||||
|
Protocol: schema.GitProtocolSsh,
|
||||||
|
SshUser: "git",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
output, err := exec.Command(
|
||||||
|
"git",
|
||||||
|
"clone",
|
||||||
|
cloneUrl,
|
||||||
|
dest,
|
||||||
|
).CombinedOutput()
|
||||||
|
if len(output) > 0 {
|
||||||
|
log.Print(string(output))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -12,7 +12,7 @@ type PluginBuilder struct {
|
|||||||
serveConfig *plugin.ServeConfig
|
serveConfig *plugin.ServeConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPluginBuilder(name string, p Plugin) *PluginBuilder {
|
func NewPluginBuilder(p Plugin) *PluginBuilder {
|
||||||
logger := hclog.New(&hclog.LoggerOptions{
|
logger := hclog.New(&hclog.LoggerOptions{
|
||||||
Level: hclog.Error,
|
Level: hclog.Error,
|
||||||
Output: os.Stderr,
|
Output: os.Stderr,
|
||||||
@ -20,7 +20,7 @@ func NewPluginBuilder(name string, p Plugin) *PluginBuilder {
|
|||||||
})
|
})
|
||||||
|
|
||||||
var pluginMap = map[string]plugin.Plugin{
|
var pluginMap = map[string]plugin.Plugin{
|
||||||
name: &PluginAPI{
|
"plugin": &PluginAPI{
|
||||||
Impl: p,
|
Impl: p,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/go-hclog"
|
"github.com/hashicorp/go-hclog"
|
||||||
"github.com/hashicorp/go-plugin"
|
"github.com/hashicorp/go-plugin"
|
||||||
@ -43,7 +44,7 @@ func (pr *PluginRegisterBuilder) Build(ctx context.Context) (*PluginRegister, er
|
|||||||
name, p := name, p
|
name, p := name, p
|
||||||
|
|
||||||
errgroup.Go(func() error {
|
errgroup.Go(func() error {
|
||||||
pluginPath := fmt.Sprintf(".char/plugins/%s/dist/%s", name, name)
|
pluginPath := fmt.Sprintf(".char/plugins/%s/dist/cmd", name)
|
||||||
|
|
||||||
_, err := os.Stat(pluginPath)
|
_, err := os.Stat(pluginPath)
|
||||||
if err != nil || os.Getenv("CHAR_DEV_MODE") == "true" {
|
if err != nil || os.Getenv("CHAR_DEV_MODE") == "true" {
|
||||||
@ -52,10 +53,15 @@ func (pr *PluginRegisterBuilder) Build(ctx context.Context) (*PluginRegister, er
|
|||||||
"sh",
|
"sh",
|
||||||
"-c",
|
"-c",
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
"(cd .char/plugins/%s; go build -o dist/%s %s)",
|
"(cd .char/plugins/%s; go build -o dist/plugin %s/main.go)",
|
||||||
name,
|
|
||||||
name,
|
name,
|
||||||
|
strings.TrimSuffix(
|
||||||
|
strings.TrimSuffix(
|
||||||
p.path,
|
p.path,
|
||||||
|
"main.go",
|
||||||
|
),
|
||||||
|
"/",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
@ -80,8 +86,7 @@ func (pr *PluginRegisterBuilder) Build(ctx context.Context) (*PluginRegister, er
|
|||||||
}),
|
}),
|
||||||
Cmd: exec.Command(
|
Cmd: exec.Command(
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
".char/plugins/%s/dist/%s",
|
".char/plugins/%s/dist/plugin",
|
||||||
name,
|
|
||||||
name,
|
name,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -95,7 +100,7 @@ func (pr *PluginRegisterBuilder) Build(ctx context.Context) (*PluginRegister, er
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
raw, err := rpcClient.Dispense(name)
|
raw, err := rpcClient.Dispense("plugin")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@ package schema
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -10,6 +12,11 @@ import (
|
|||||||
|
|
||||||
type CharSchemaPluginName string
|
type CharSchemaPluginName string
|
||||||
|
|
||||||
|
func (cspn CharSchemaPluginName) Hash() string {
|
||||||
|
bytes := sha256.Sum256([]byte(cspn))
|
||||||
|
return hex.EncodeToString(bytes[:])
|
||||||
|
}
|
||||||
|
|
||||||
type PluginOps struct {
|
type PluginOps struct {
|
||||||
Org string
|
Org string
|
||||||
RepositoryName string
|
RepositoryName string
|
||||||
|
@ -55,16 +55,16 @@ func TestGetPlugins(t *testing.T) {
|
|||||||
input: `
|
input: `
|
||||||
registry: git.front.kjuulh.io
|
registry: git.front.kjuulh.io
|
||||||
plugins:
|
plugins:
|
||||||
"kjuulh/char#plugins/gocli": {}
|
"kjuulh/char#plugins/gocli@v1.9.0": {}
|
||||||
"kjuulh/char#plugins/rust": {}
|
"kjuulh/char#plugins/rust": {}
|
||||||
`,
|
`,
|
||||||
expected: map[schema.CharSchemaPluginName]*schema.CharSchemaPlugin{
|
expected: map[schema.CharSchemaPluginName]*schema.CharSchemaPlugin{
|
||||||
"kjuulh/char#plugins/gocli": {
|
"kjuulh/char#plugins/gocli@v1.9.0": {
|
||||||
Opts: &schema.PluginOps{
|
Opts: &schema.PluginOps{
|
||||||
Org: "kjuulh",
|
Org: "kjuulh",
|
||||||
RepositoryName: "char",
|
RepositoryName: "char",
|
||||||
Path: "plugins/gocli",
|
Path: "plugins/gocli",
|
||||||
Version: "",
|
Version: "v1.9.0",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"kjuulh/char#plugins/rust": {
|
"kjuulh/char#plugins/rust": {
|
||||||
|
@ -22,7 +22,6 @@ var _ register.Plugin = &GoCliPlugin{}
|
|||||||
func main() {
|
func main() {
|
||||||
if err := register.
|
if err := register.
|
||||||
NewPluginBuilder(
|
NewPluginBuilder(
|
||||||
"gocli",
|
|
||||||
&GoCliPlugin{},
|
&GoCliPlugin{},
|
||||||
).
|
).
|
||||||
Serve(context.Background()); err != nil {
|
Serve(context.Background()); err != nil {
|
||||||
|
@ -22,7 +22,6 @@ var _ register.Plugin = &GoCliPlugin{}
|
|||||||
func main() {
|
func main() {
|
||||||
if err := register.
|
if err := register.
|
||||||
NewPluginBuilder(
|
NewPluginBuilder(
|
||||||
"rust",
|
|
||||||
&GoCliPlugin{},
|
&GoCliPlugin{},
|
||||||
).
|
).
|
||||||
Serve(context.Background()); err != nil {
|
Serve(context.Background()); err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user