Compare commits

..

1 Commits

Author SHA1 Message Date
98999336dc
remove existing 2023-01-21 15:02:04 +01:00
33 changed files with 0 additions and 1560 deletions

View File

@ -1,4 +0,0 @@
kind: template
load: bust_gobin_default_template.yaml
name: char
data: {}

1
.gitignore vendored
View File

@ -1 +0,0 @@
dist/

View File

@ -1,26 +0,0 @@
# Char
Char is an organizations best friend, it helps with code sharing when either
using a multi-repo strategy or mono repo. The goal of the project is to
facilitate sharing of presets and plugins to reduce the required complexity
developers have to take on.
This project is best suited with a standard library of plugins (which serves the
function of libraries), as well `kjuulh/bust` which is a platform agnostic
CI/task setup
This is in very early stages, and for now it officially supports scaffolding.
## Example
The `examples` folder shows how to load plugins, though presets are still
pending.
```yaml
# file: .char.yml
registry: git.front.kjuulh.io
plugins:
"kjuulh/char#/plugins/gocli":
vars:
name: "char"
```

View File

@ -1,67 +0,0 @@
package char
import (
"context"
"log"
"git.front.kjuulh.io/kjuulh/char/pkg/charcontext"
"github.com/spf13/cobra"
)
type RequiredArg struct {
Required bool
Value string
}
func NewDoCommand(charctx *charcontext.CharContext) *cobra.Command {
cmd := &cobra.Command{
Use: "do",
}
about, err := charctx.About(context.Background())
if err != nil {
log.Fatal(err)
}
for _, a := range about {
for _, c := range a.Commands {
requiredArgs := make(map[string]*RequiredArg, len(c.Args))
for _, arg := range c.Args {
requiredArgs[arg] = &RequiredArg{
Required: false,
}
}
for _, required := range c.Required {
if _, ok := requiredArgs[required]; ok {
requiredArg := requiredArgs[required]
requiredArg.Required = true
}
}
doCmd := &cobra.Command{
Use: c.Name,
RunE: func(cmd *cobra.Command, args []string) error {
if err := cmd.ParseFlags(args); err != nil {
return err
}
if err := charctx.Do(cmd.Context(), a.ClientName, c.Name, nil); err != nil {
return err
}
return nil
},
}
for argName, argValue := range requiredArgs {
doCmd.PersistentFlags().StringVar(&argValue.Value, argName, "", "")
if argValue.Required {
doCmd.MarkPersistentFlagRequired(argName)
}
}
cmd.AddCommand(doCmd)
}
}
return cmd
}

View File

@ -1,13 +0,0 @@
package char
import (
"github.com/spf13/cobra"
)
func NewLimitedCharCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "char",
}
return cmd
}

View File

@ -1,64 +0,0 @@
package char
import (
"fmt"
"git.front.kjuulh.io/kjuulh/char/pkg/charcontext"
"github.com/spf13/cobra"
)
func NewLsCommand(charctx *charcontext.CharContext) *cobra.Command {
cmd := &cobra.Command{
Use: "ls",
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
about, err := charctx.About(ctx)
if err != nil {
return err
}
for _, a := range about {
fmt.Printf("plugin: %s\n", a.Name)
fmt.Printf("\tversion: %s\n", a.Version)
fmt.Printf("\tabout: %s\n", a.About)
if len(a.Vars) > 0 {
fmt.Println("\tVars:")
for _, av := range a.Vars {
fmt.Printf("\t\t%s\n", av)
}
}
if len(a.Commands) > 0 {
fmt.Println("\tCommands:")
for _, ac := range a.Commands {
fmt.Printf("\t\t%s\n", ac.Name)
if len(ac.Args) == 0 {
continue
}
fmt.Println("\t\tArgs")
for _, aca := range ac.Args {
isrequired := false
for _, acr := range ac.Required {
if acr == aca {
isrequired = true
}
}
if isrequired {
fmt.Printf("\t\t\t%s: required\n", aca)
} else {
fmt.Printf("\t\t\t%s\n", aca)
}
}
}
}
fmt.Println()
}
return nil
},
}
return cmd
}

View File

@ -1,19 +0,0 @@
package char
import (
"git.front.kjuulh.io/kjuulh/char/pkg/charcontext"
"github.com/spf13/cobra"
)
func NewCharCmd(charctx *charcontext.CharContext) *cobra.Command {
cmd := &cobra.Command{
Use: "char",
}
cmd.AddCommand(
NewLsCommand(charctx),
NewDoCommand(charctx),
)
return cmd
}

View File

@ -1,4 +0,0 @@
registry: git.front.kjuulh.io
plugins:
"kjuulh/char#plugins/gocli": {}
"kjuulh/char#plugins/rust": {}

View File

@ -1,2 +0,0 @@
.char/plugins/
char

View File

@ -1,21 +0,0 @@
#!/bin/bash
set -e
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 ""

View File

@ -1,7 +0,0 @@
#!/bin/bash
set -e
go build -o char ../../main.go
CHAR_DEV_MODE=true ./char ls

View File

@ -1,13 +0,0 @@
#!/bin/bash
set -e
go build -o char ../../main.go
echo "base"
CHAR_DEV_MODE=true ./char do -h
echo
echo "--------"
echo "local_up"
CHAR_DEV_MODE=false ./char do local_up --fish something

31
go.mod
View File

@ -1,31 +0,0 @@
module git.front.kjuulh.io/kjuulh/char
go 1.19
require (
github.com/hashicorp/go-hclog v1.5.0
github.com/hashicorp/go-plugin v1.4.9
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.8.2
golang.org/x/sync v0.2.0
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/golang/protobuf v1.3.4 // indirect
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 // indirect
github.com/oklog/run v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/net v0.0.0-20190311183353-d8887717615a // indirect
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect
golang.org/x/text v0.3.0 // indirect
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 // indirect
google.golang.org/grpc v1.27.1 // indirect
)

133
go.sum
View File

@ -1,133 +0,0 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU=
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v1.3.1 h1:vDwF1DFNZhntP4DAjuTpOw3uEgMUpXh1pB5fW9DqHpo=
github.com/hashicorp/go-hclog v1.3.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-hclog v1.4.0 h1:ctuWFGrhFha8BnnzxqeRGidlEcQkDyL5u8J8t5eA11I=
github.com/hashicorp/go-hclog v1.4.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-plugin v1.4.5 h1:oTE/oQR4eghggRg8VY7PAz3dr++VwDNBGCcOfIvHpBo=
github.com/hashicorp/go-plugin v1.4.5/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
github.com/hashicorp/go-plugin v1.4.6 h1:MDV3UrKQBM3du3G7MApDGvOsMYy3JQJ4exhSoKBAeVA=
github.com/hashicorp/go-plugin v1.4.6/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
github.com/hashicorp/go-plugin v1.4.9 h1:ESiK220/qE0aGxWdzKIvRH69iLiuN/PjoLTm69RoWtU=
github.com/hashicorp/go-plugin v1.4.9/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg=
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191008105621-543471e840be h1:QAcqgptGM8IQBC9K/RC4o+O9YmqEm0diQn9QmZw/0mU=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -1,3 +0,0 @@
go 1.19
use .

View File

@ -1 +0,0 @@
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

29
main.go
View File

@ -1,29 +0,0 @@
package main
import (
"context"
"errors"
"log"
"git.front.kjuulh.io/kjuulh/char/cmd/char"
"git.front.kjuulh.io/kjuulh/char/pkg/charcontext"
)
func main() {
charctx, err := charcontext.NewCharContext(context.Background())
if err != nil {
if errors.Is(err, charcontext.ErrNoContextFound) {
log.Print("you are not in a char context, as such you will be presented with limited options")
if err := char.NewLimitedCharCmd().Execute(); err != nil {
log.Fatal(err)
}
} else {
log.Fatal(err)
}
}
defer charctx.Close()
if err := char.NewCharCmd(charctx).Execute(); err != nil {
log.Fatal(err)
}
}

View File

@ -1,70 +0,0 @@
package charcontext
import (
"context"
"log"
"git.front.kjuulh.io/kjuulh/char/pkg/plugins/provider"
"git.front.kjuulh.io/kjuulh/char/pkg/register"
"git.front.kjuulh.io/kjuulh/char/pkg/schema"
)
type CharContext struct {
contextPath string
pluginRegister *register.PluginRegister
schema *schema.CharSchema
}
func NewCharContext(ctx context.Context) (*CharContext, error) {
localPath, err := FindLocalRoot(ctx)
if err != nil {
return nil, err
}
gpp := provider.NewGitPluginProvider()
s, err := schema.ParseFile(ctx, ".char.yml")
if err != nil {
return nil, err
}
plugins, err := s.GetPlugins(ctx)
if err != nil {
return nil, err
}
err = gpp.FetchPlugins(ctx, s.Registry, plugins)
if err != nil {
return nil, 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 {
return nil, err
}
return &CharContext{
contextPath: localPath,
pluginRegister: r,
schema: s,
}, nil
}
func (cc *CharContext) Close() {
if err := cc.pluginRegister.Close(); err != nil {
log.Fatal(err)
}
}
func (cc *CharContext) About(ctx context.Context) ([]register.AboutItem, error) {
return cc.pluginRegister.About(ctx)
}
func (cc *CharContext) Do(ctx context.Context, clientName string, commandName string, args map[string]string) error {
return cc.pluginRegister.Do(ctx, clientName, commandName, args)
}

View File

@ -1,57 +0,0 @@
package charcontext
import (
"context"
"errors"
"os"
"path"
)
var ErrNoContextFound = errors.New("could not find project root")
const CharFileName = ".char.yml"
func FindLocalRoot(ctx context.Context) (string, error) {
curdir, err := os.Getwd()
if err != nil {
return "", err
}
return recursiveFindLocalRoot(ctx, curdir)
//output, err := exec.Command("git", "rev-parse", "--show-toplevel").CombinedOutput()
//if err != nil {
// return "", err
//}
//if len(output) == 0 {
// return "", errors.New("could not find absolute path")
//}
//if _, err := os.Stat(string(output)); errors.Is(err, os.ErrNotExist) {
// return "", fmt.Errorf("path does not exist %s", string(output))
//}
//return string(output), nil
}
func recursiveFindLocalRoot(ctx context.Context, localpath string) (string, error) {
entries, err := os.ReadDir(localpath)
if err != nil {
return "", err
}
for _, entry := range entries {
if entry.Name() == CharFileName {
return localpath, nil
}
}
if localpath == "/" {
return "", ErrNoContextFound
}
return recursiveFindLocalRoot(ctx, path.Dir(localpath))
}
func ChangeToPath(_ context.Context, path string) error {
return os.Chdir(path)
}

View File

@ -1,107 +0,0 @@
package provider
import (
"context"
"errors"
"fmt"
"log"
"os"
"os/exec"
"strings"
"time"
"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 fmt.Errorf("path already exists cannot create: %w", err)
}
for n, plugin := range plugins {
n, plugin := n, plugin
errgroup.Go(func() error {
dest := fmt.Sprintf(
"%s/%s",
strings.TrimRight(baseDir, "/"), n.Hash(),
)
fileinfo, err := os.Stat(dest)
if errors.Is(err, os.ErrNotExist) {
log.Printf("fetching git plugin repo: %s", n)
return gpp.FetchPlugin(
ctx,
registry,
plugin,
dest,
)
}
if fileinfo.ModTime().Add(time.Hour * 1).Before(time.Now()) {
log.Printf("fetching git plugin repo: %s as it is stale", n)
return gpp.FetchPlugin(
ctx,
registry,
plugin,
dest,
)
}
return nil
})
}
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
}
if _, err := os.Stat(dest); !errors.Is(err, os.ErrNotExist) {
if err = os.RemoveAll(dest); err != nil {
return err
}
}
output, err := exec.Command(
"git",
"clone",
"--depth=1",
cloneUrl,
dest,
).CombinedOutput()
if len(output) > 0 {
log.Print(string(output))
}
if err != nil {
return err
}
return nil
}

View File

@ -1,29 +0,0 @@
package register
import "context"
type AboutCommand struct {
Name string `json:"name" yaml:"name"`
Args []string `json:"args" yaml:"args"`
Required []string `json:"required" yaml:"required"`
}
type About struct {
Name string `json:"name"`
Version string `json:"version"`
About string `json:"about"`
Vars []string `json:"vars"`
Commands []*AboutCommand `json:"commands"`
}
type DoCommand struct {
CommandName string `json:"commandName"`
Args map[string]string `json:"args"`
}
type Plugin interface {
About(ctx context.Context) (*About, error)
Do(ctx context.Context, cmd *DoCommand) error
}
const PluginKey = "plugin"

View File

@ -1,20 +0,0 @@
package register
import (
"net/rpc"
"github.com/hashicorp/go-plugin"
)
type PluginAPI struct {
path string
Impl Plugin
}
func (pa *PluginAPI) Server(*plugin.MuxBroker) (any, error) {
return &PluginServer{Impl: pa.Impl}, nil
}
func (*PluginAPI) Client(b *plugin.MuxBroker, c *rpc.Client) (any, error) {
return &PluginClient{client: c}, nil
}

View File

@ -1,48 +0,0 @@
package register
import (
"context"
"os"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-plugin"
)
type PluginBuilder struct {
serveConfig *plugin.ServeConfig
}
func NewPluginBuilder(p Plugin) *PluginBuilder {
logger := hclog.New(&hclog.LoggerOptions{
Level: hclog.Debug,
Output: os.Stderr,
JSONFormat: false,
})
var pluginMap = map[string]plugin.Plugin{
PluginKey: &PluginAPI{
Impl: p,
},
}
serveConfig := &plugin.ServeConfig{
HandshakeConfig: plugin.HandshakeConfig{
ProtocolVersion: 1,
MagicCookieKey: "BASIC_PLUGIN",
MagicCookieValue: "char",
},
Plugins: pluginMap,
Logger: logger,
}
return &PluginBuilder{
serveConfig: serveConfig,
}
}
func (pr *PluginBuilder) Serve(ctx context.Context) error {
plugin.Serve(
pr.serveConfig,
)
return nil
}

View File

@ -1,39 +0,0 @@
package register
import (
"context"
"encoding/json"
"net/rpc"
)
type PluginClient struct {
client *rpc.Client
}
// Do implements Plugin
func (pc *PluginClient) Do(ctx context.Context, cmd *DoCommand) error {
err := pc.client.Call("Plugin.Do", cmd, new(string))
if err != nil {
return err
}
return nil
}
var _ Plugin = &PluginClient{}
func (pc *PluginClient) About(ctx context.Context) (*About, error) {
var resp string
err := pc.client.Call("Plugin.About", new(any), &resp)
if err != nil {
return nil, err
}
var about About
err = json.Unmarshal([]byte(resp), &about)
if err != nil {
return nil, err
}
return &about, nil
}

View File

@ -1,248 +0,0 @@
package register
import (
"context"
"errors"
"fmt"
"log"
"os"
"os/exec"
"strings"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-plugin"
"golang.org/x/sync/errgroup"
)
type PluginRegisterBuilder struct {
plugins map[string]PluginAPI
}
func NewPluginRegisterBuilder() *PluginRegisterBuilder {
return &PluginRegisterBuilder{
plugins: make(map[string]PluginAPI),
}
}
func (pr *PluginRegisterBuilder) Add(name, path string) *PluginRegisterBuilder {
pr.plugins[name] = PluginAPI{
path: path,
}
return pr
}
func (pr *PluginRegisterBuilder) Build(ctx context.Context) (*PluginRegister, error) {
clients := make(map[string]*pluginClientWrapper, 0)
errgroup, _ := errgroup.WithContext(ctx)
if err := os.MkdirAll(".char/plugins/", 0755); err != nil {
return nil, err
}
for name, p := range pr.plugins {
name, p := name, p
errgroup.Go(func() error {
pluginPath := fmt.Sprintf(".char/plugins/%s/dist/plugin", name)
_, err := os.Stat(pluginPath)
if err != nil || os.Getenv("CHAR_DEV_MODE") == "true" {
log.Printf("building: %s", name)
cmd := exec.Command(
"sh",
"-c",
fmt.Sprintf(
"(cd .char/plugins/%s; go build -o dist/plugin %s/main.go)",
name,
strings.TrimSuffix(
strings.TrimSuffix(
p.path,
"main.go",
),
"/",
),
),
)
output, err := cmd.CombinedOutput()
if len(output) > 0 {
log.Println(string(output))
}
if err != nil {
return fmt.Errorf("could not build plugin: %w", err)
}
}
client := plugin.NewClient(&plugin.ClientConfig{
HandshakeConfig: plugin.HandshakeConfig{
ProtocolVersion: 1,
MagicCookieKey: "BASIC_PLUGIN",
MagicCookieValue: "char",
},
Logger: hclog.New(&hclog.LoggerOptions{
Name: "char",
Output: os.Stdout,
Level: hclog.Debug,
}),
Cmd: exec.Command(
fmt.Sprintf(
".char/plugins/%s/dist/plugin",
name,
),
),
Plugins: map[string]plugin.Plugin{
PluginKey: &p,
},
})
rpcClient, err := client.Client()
if err != nil {
return err
}
raw, err := rpcClient.Dispense("plugin")
if err != nil {
return err
}
pluginApi, ok := raw.(Plugin)
if !ok {
return errors.New("could not cast as plugin")
}
clients[name] = &pluginClientWrapper{
plugin: pluginApi,
client: client,
}
return nil
})
}
err := errgroup.Wait()
if err != nil {
return nil, err
}
return &PluginRegister{
clients: clients,
}, nil
}
// ---
type pluginClientWrapper struct {
plugin Plugin
client *plugin.Client
}
func (pcw *pluginClientWrapper) Close() {
pcw.client.Kill()
}
// ---
type PluginRegister struct {
clients map[string]*pluginClientWrapper
}
func (pr *PluginRegister) Close() error {
errgroup, _ := errgroup.WithContext(context.Background())
for _, c := range pr.clients {
c := c
errgroup.Go(func() error {
c.Close()
return nil
})
}
if err := errgroup.Wait(); err != nil {
return err
}
return nil
}
type CommandAboutItem struct {
Name string
Args []string
Required []string
}
type CommandAboutItems []*CommandAboutItem
func FromAboutCommands(commands []*AboutCommand) CommandAboutItems {
cai := make(CommandAboutItems, 0)
for _, command := range commands {
cai = append(cai, &CommandAboutItem{
Name: command.Name,
Args: command.Args,
Required: command.Required,
})
}
return cai
}
type AboutItem struct {
Name string
Version string
About string
Vars []string
Commands CommandAboutItems
ClientName string
}
func (pr *PluginRegister) About(ctx context.Context) ([]AboutItem, error) {
list := make([]AboutItem, 0)
errgroup, ctx := errgroup.WithContext(ctx)
for name, c := range pr.clients {
name, c := name, c
errgroup.Go(func() error {
about, err := c.plugin.About(ctx)
if err != nil {
return err
}
list = append(list, AboutItem{
Name: about.Name,
Version: about.Version,
About: about.About,
Vars: about.Vars,
Commands: FromAboutCommands(about.Commands),
ClientName: name,
})
return nil
})
}
if err := errgroup.Wait(); err != nil {
return nil, err
}
return list, nil
}
func (pr *PluginRegister) Do(ctx context.Context, clientName string, commandName string, args map[string]string) error {
errgroup, ctx := errgroup.WithContext(ctx)
client, ok := pr.clients[clientName]
if !ok {
return fmt.Errorf("plugin was not found: %s", clientName)
}
errgroup.Go(func() error {
return client.plugin.Do(ctx, &DoCommand{
CommandName: commandName,
Args: args,
})
})
if err := errgroup.Wait(); err != nil {
return err
}
return nil
}

View File

@ -1,44 +0,0 @@
package register
import (
"context"
"encoding/json"
)
type PluginServer struct {
Impl Plugin
}
func (ps *PluginServer) Do(args *DoCommand, resp *string) error {
//rawReq, ok := args.(string)
//if !ok {
// return errors.New("args is not a string")
//}
//var doReq DoRequest
//if err := json.Unmarshal([]byte(rawReq), &doReq); err != nil {
// return err
//}
if err := ps.Impl.Do(context.Background(), args); err != nil {
return err
}
*resp = ""
return nil
}
func (ps *PluginServer) About(args any, resp *string) error {
r, err := ps.Impl.About(context.Background())
if err != nil {
return err
}
respB, err := json.Marshal(r)
if err != nil {
return err
}
*resp = string(respB)
return nil
}

View File

@ -1,50 +0,0 @@
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)
}
return Parse(file)
}
func Parse(content []byte) (*CharSchema, error) {
var schema CharSchema
if err := yaml.Unmarshal(content, &schema); err != nil {
return nil, fmt.Errorf("could not deserialize yaml into CharSchema: %w", err)
}
return &schema, nil
}
func (cs *CharSchema) GetPlugins(ctx context.Context) (CharSchemaPlugins, error) {
plugins := make(map[CharSchemaPluginName]*CharSchemaPlugin, len(cs.Plugins))
for n, plugin := range cs.Plugins {
po, err := n.Get()
if err != nil {
return nil, err
}
plugin.Opts = po
plugins[n] = plugin
}
return plugins, nil
}

View File

@ -1,104 +0,0 @@
package schema
import (
"context"
"crypto/sha256"
"encoding/hex"
"errors"
"fmt"
"regexp"
"strings"
)
type CharSchemaPluginName string
func (cspn CharSchemaPluginName) Hash() string {
bytes := sha256.Sum256([]byte(cspn))
return hex.EncodeToString(bytes[:])
}
type PluginOps struct {
Org string
RepositoryName string
Path string
Version string
}
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<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, "@")
}
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
type CharSchemaPluginVarName string
type CharSchemaPluginVars map[CharSchemaPluginVarName]string
type CharSchemaPlugin struct {
Opts *PluginOps
Vars CharSchemaPluginVars `json:"vars"`
}

View File

@ -1,126 +0,0 @@
package schema_test
import (
"context"
"testing"
"git.front.kjuulh.io/kjuulh/char/pkg/schema"
"github.com/stretchr/testify/require"
)
func TestSchemaNameCanParse(t *testing.T) {
t.Parallel()
tt := []struct {
name string
inputString schema.CharSchemaPluginName
expected schema.PluginOps
}{
{
name: "default string",
inputString: `kju123K_-ulh/someRepo-._123`,
expected: schema.PluginOps{
Org: "kju123K_-ulh",
RepositoryName: "someRepo-._123",
},
},
{
name: "default string with path",
inputString: `kju123K_-ulh/someRepo-._123#somepath/sometoherpath/somethridpath`,
expected: schema.PluginOps{
Org: "kju123K_-ulh",
RepositoryName: "someRepo-._123",
Path: "somepath/sometoherpath/somethridpath",
},
},
{
name: "default string with version",
inputString: `kju123K_-ulh/someRepo-._123@12l3.jk1lj`,
expected: schema.PluginOps{
Org: "kju123K_-ulh",
RepositoryName: "someRepo-._123",
Version: "12l3.jk1lj",
},
},
{
name: "default string with version and path",
inputString: `kju123K_-ulh/someRepo-._123@12l3.jk1lj#somepath/sometoherpath/somethridpath`,
expected: schema.PluginOps{
Org: "kju123K_-ulh",
RepositoryName: "someRepo-._123",
Version: "12l3.jk1lj",
Path: "somepath/sometoherpath/somethridpath",
},
},
{
name: "default string with path and version",
inputString: `kju123K_-ulh/someRepo-._123#somepath/sometoherpath/somethridpath@12l3.jk1lj`,
expected: schema.PluginOps{
Org: "kju123K_-ulh",
RepositoryName: "someRepo-._123",
Version: "12l3.jk1lj",
Path: "somepath/sometoherpath/somethridpath",
},
},
}
for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
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)
})
}
}

View File

@ -1,93 +0,0 @@
package schema_test
import (
"context"
"testing"
"git.front.kjuulh.io/kjuulh/char/pkg/schema"
"github.com/stretchr/testify/require"
)
func TestSchemaParse(t *testing.T) {
t.Parallel()
tt := []struct {
name string
input string
expected *schema.CharSchema
}{
{
name: "with plugins",
input: `
registry: git.front.kjuulh.io
plugins:
"kjuulh/char#plugins/gocli": {}
"kjuulh/char#plugins/rust": {}
`,
expected: &schema.CharSchema{
Registry: "git.front.kjuulh.io",
Plugins: map[schema.CharSchemaPluginName]*schema.CharSchemaPlugin{
"kjuulh/char#plugins/gocli": {},
"kjuulh/char#plugins/rust": {},
},
},
},
}
for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
s, err := schema.Parse([]byte(tc.input))
require.NoError(t, err)
require.Equal(t, tc.expected, s)
})
}
}
func TestGetPlugins(t *testing.T) {
t.Parallel()
tt := []struct {
name string
input string
expected schema.CharSchemaPlugins
}{
{
name: "with plugins",
input: `
registry: git.front.kjuulh.io
plugins:
"kjuulh/char#plugins/gocli@v1.9.0": {}
"kjuulh/char#plugins/rust": {}
`,
expected: map[schema.CharSchemaPluginName]*schema.CharSchemaPlugin{
"kjuulh/char#plugins/gocli@v1.9.0": {
Opts: &schema.PluginOps{
Org: "kjuulh",
RepositoryName: "char",
Path: "plugins/gocli",
Version: "v1.9.0",
},
},
"kjuulh/char#plugins/rust": {
Opts: &schema.PluginOps{
Org: "kjuulh",
RepositoryName: "char",
Path: "plugins/rust",
Version: "",
},
},
},
},
}
for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
s, err := schema.Parse([]byte(tc.input))
require.NoError(t, err)
plugins, err := s.GetPlugins(context.Background())
require.NoError(t, err)
require.Equal(t, tc.expected, plugins)
})
}
}

View File

@ -1,47 +0,0 @@
package main
import (
"context"
"log"
"git.front.kjuulh.io/kjuulh/char/pkg/register"
"github.com/hashicorp/go-hclog"
)
type GoCliPlugin struct{}
// Do implements register.Plugin
func (*GoCliPlugin) Do(ctx context.Context, cmd *register.DoCommand) error {
hclog.L().Info("received command", "commandName", cmd.CommandName)
return nil
}
func (*GoCliPlugin) About(ctx context.Context) (*register.About, error) {
return &register.About{
Name: "gocli",
Version: "v0.0.1",
About: "golang cli provides a set of actions and presets supporting golang development",
Vars: []string{
"dev.mode",
},
Commands: []*register.AboutCommand{
{
Name: "local_up",
Args: []string{"fish"},
Required: []string{"fish"},
},
},
}, nil
}
var _ register.Plugin = &GoCliPlugin{}
func main() {
if err := register.
NewPluginBuilder(
&GoCliPlugin{},
).
Serve(context.Background()); err != nil {
log.Fatal(err)
}
}

View File

@ -1,37 +0,0 @@
package main
import (
"context"
"log"
"git.front.kjuulh.io/kjuulh/char/pkg/register"
"github.com/hashicorp/go-hclog"
)
type GoCliPlugin struct{}
// Do implements register.Plugin
func (*GoCliPlugin) Do(ctx context.Context, cmd *register.DoCommand) error {
hclog.L().Info("received command", "commandName", cmd.CommandName)
return nil
}
func (*GoCliPlugin) About(ctx context.Context) (*register.About, error) {
return &register.About{
Name: "rust",
Version: "v0.0.1",
About: "rust cli provides a set of actions and presets supporting rust development",
}, nil
}
var _ register.Plugin = &GoCliPlugin{}
func main() {
if err := register.
NewPluginBuilder(
&GoCliPlugin{},
).
Serve(context.Background()); err != nil {
log.Fatal(err)
}
}

View File

@ -1,3 +0,0 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
}