Skip to content

Commit

Permalink
feat(flipt): implement collection delete
Browse files Browse the repository at this point in the history
  • Loading branch information
GeorgeMac committed Jul 2, 2023
1 parent 5643ce6 commit ae5f065
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 50 deletions.
77 changes: 63 additions & 14 deletions cmd/flipt/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"io/fs"
"os"

Expand Down Expand Up @@ -60,7 +61,7 @@ func main() {
panic(err)
}

enc := json.NewEncoder(os.Stdout)
enc := newDocumentEncoder(os.Stdout)
if err := walkDocuments(os.DirFS("."), func(path string, document *ext.Document) error {
if document.Namespace != string(flag.Namespace) {
return nil
Expand All @@ -80,7 +81,9 @@ func main() {
f.Rules = flag.Payload.Rules
}

action := "update"
if !found {
action = "create"
document.Flags = append(document.Flags, &ext.Flag{
Key: flag.ID,
Name: flag.Payload.Name,
Expand All @@ -91,31 +94,77 @@ func main() {
})
}

buf := &bytes.Buffer{}
if err := yaml.NewEncoder(buf).Encode(document); err != nil {
return err
return enc.encode(
fmt.Sprintf("feat: %s flag \"%s/%s\"", action, flag.Namespace, flag.ID),
path,
document,
)
}); err != nil {
panic(err)
}
case "delete":
if len(os.Args) < 4 {
panic("delete [namespace] [id]")
}

var (
namespace = os.Args[2]
id = os.Args[3]
)

enc := newDocumentEncoder(os.Stdout)
if err := walkDocuments(os.DirFS("."), func(path string, document *ext.Document) error {
if document.Namespace != string(namespace) {
return nil
}

if err := enc.Encode(fidgit.Change{
Path: path,
Contents: buf.Bytes(),
}); err != nil {
return err
var found bool
for i, f := range document.Flags {
if f.Key != string(id) {
continue
}

document.Flags = append(document.Flags[:i], document.Flags[i+1:]...)

found = true
}

return nil
if !found {
return nil
}

return enc.encode(
fmt.Sprintf("feat: delete flag \"%s/%s\"", namespace, id),
path,
document,
)
}); err != nil {
panic(err)
}
case "delete":
default:
panic(fmt.Errorf("unexpected command: %q", os.Args[1]))
}
}

type document struct {
ext.Document
path string
type encoder struct {
Encoder *json.Encoder
}

func newDocumentEncoder(w io.Writer) encoder {
return encoder{json.NewEncoder(w)}
}

func (e encoder) encode(message, path string, doc *ext.Document) error {
buf := &bytes.Buffer{}
if err := yaml.NewEncoder(buf).Encode(doc); err != nil {
return err
}

return e.Encoder.Encode(fidgit.Change{
Message: message,
Path: path,
Contents: buf.Bytes(),
})
}

type flag struct {
Expand Down
75 changes: 39 additions & 36 deletions internal/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func NewFactory(ctx context.Context, path string) (_ *Factory, err error) {
}

buf := &bytes.Buffer{}
if err := factory.invoke(ctx, buf, "type"); err != nil {
if err := factory.invoke(ctx, buf, []string{"type"}); err != nil {
return nil, err
}

Expand Down Expand Up @@ -66,39 +66,14 @@ type Collection struct {
index map[fidgit.Namespace]*namespace
}

func (f *Factory) invoke(ctx context.Context, dst io.Writer, command string, opts ...func(wazero.ModuleConfig) wazero.ModuleConfig) error {
config := wazero.NewModuleConfig().
WithStdout(dst).
WithStderr(os.Stderr)

for _, opt := range opts {
config = opt(config)
}

// InstantiateModule runs the "_start" function, WASI's "main".
// * Set the program name (arg[0]) to "wasi"; arg[1] should be "/test.txt".
_, err := f.runtime.InstantiateWithConfig(ctx, f.wasm, config.WithArgs("wasi", command))
if err != nil {
// Note: Most compilers do not exit the module after running "_start",
// unless there was an error. This allows you to call exported functions.
if exitErr, ok := err.(*sys.ExitError); ok && exitErr.ExitCode() != 0 {
return exitErr
} else if !ok {
return err
}
}

return nil
}

func (f *Factory) Build() (fidgit.Type, fidgit.FactoryFunc) {
return f.typ, func(ctx context.Context, dir fs.FS) (fidgit.Collection, error) {
var (
buf = &bytes.Buffer{}
dec = json.NewDecoder(buf)
)

if err := f.invoke(ctx, buf, "list", func(mc wazero.ModuleConfig) wazero.ModuleConfig {
if err := f.invoke(ctx, buf, []string{"list"}, func(mc wazero.ModuleConfig) wazero.ModuleConfig {
return mc.WithFS(dir)
}); err != nil {
return nil, err
Expand Down Expand Up @@ -171,20 +146,31 @@ func (c *Collection) List(ctx context.Context, n fidgit.Namespace) ([]*fidgit.En
}

func (c *Collection) Put(ctx context.Context, entry *fidgit.Entry) ([]fidgit.Change, error) {
var (
in, out = &bytes.Buffer{}, &bytes.Buffer{}
dec = json.NewDecoder(out)
)
in := &bytes.Buffer{}

if err := json.NewEncoder(in).Encode(entry); err != nil {
return nil, err
}

if err := c.invoke(ctx, out, "put", func(mc wazero.ModuleConfig) wazero.ModuleConfig {
return c.mutate(ctx, []string{"put"}, func(mc wazero.ModuleConfig) wazero.ModuleConfig {
return mc.WithStdin(in)
})
}

func (c *Collection) Delete(ctx context.Context, n fidgit.Namespace, id fidgit.ID) ([]fidgit.Change, error) {
return c.mutate(ctx, []string{"delete", string(n), string(id)})
}

func (c *Collection) mutate(ctx context.Context, args []string, opts ...func(wazero.ModuleConfig) wazero.ModuleConfig) ([]fidgit.Change, error) {
var (
out = &bytes.Buffer{}
dec = json.NewDecoder(out)
)

if err := c.invoke(ctx, out, args, append(opts, func(mc wazero.ModuleConfig) wazero.ModuleConfig {
return mc.
WithStdin(in).
WithFS(c.fs)
}); err != nil {
})...); err != nil {
return nil, err
}

Expand All @@ -204,6 +190,23 @@ func (c *Collection) Put(ctx context.Context, entry *fidgit.Entry) ([]fidgit.Cha
return changes, nil
}

func (c *Collection) Delete(ctx context.Context, n fidgit.Namespace, id fidgit.ID) ([]fidgit.Change, error) {
panic("not implemented") // TODO: Implement
func (f *Factory) invoke(ctx context.Context, dst io.Writer, args []string, opts ...func(wazero.ModuleConfig) wazero.ModuleConfig) error {
config := wazero.NewModuleConfig().
WithStdout(dst).
WithStderr(os.Stderr)

for _, opt := range opts {
config = opt(config)
}

_, err := f.runtime.InstantiateWithConfig(ctx, f.wasm, config.WithArgs(append([]string{"wasi"}, args...)...))
if err != nil {
if exitErr, ok := err.(*sys.ExitError); ok && exitErr.ExitCode() != 0 {
return exitErr
} else if !ok {
return err
}
}

return nil
}

0 comments on commit ae5f065

Please sign in to comment.