feat: values updaters

This commit is contained in:
2022-05-10 22:31:17 +02:00
parent 08476e5346
commit 0e7e955a58
16 changed files with 415 additions and 155 deletions

View File

@ -4,7 +4,6 @@ import (
"bytes"
"io"
"net/url"
"os"
encjson "encoding/json"
@ -15,6 +14,9 @@ import (
"forge.cadoles.com/wpetit/formidable/internal/data/scheme/file"
"forge.cadoles.com/wpetit/formidable/internal/data/scheme/http"
"forge.cadoles.com/wpetit/formidable/internal/data/scheme/stdin"
"forge.cadoles.com/wpetit/formidable/internal/data/updater/exec"
fileUpdater "forge.cadoles.com/wpetit/formidable/internal/data/updater/file"
"forge.cadoles.com/wpetit/formidable/internal/data/updater/stdout"
"forge.cadoles.com/wpetit/formidable/internal/def"
"github.com/pkg/errors"
"github.com/santhosh-tekuri/jsonschema/v5"
@ -50,8 +52,8 @@ func commonFlags() []cli.Flag {
&cli.StringFlag{
Name: "output",
Aliases: []string{"o", "out"},
Value: "-",
Usage: "Output modified values to `output_file` (or '-' for stdout, the default)",
Value: "stdout://local?format=json",
Usage: "Output modified values to specified URL",
},
}
}
@ -147,29 +149,39 @@ func loadSchema(ctx *cli.Context) (*jsonschema.Schema, error) {
return schema, nil
}
const OutputStdout = "-"
func outputValues(ctx *cli.Context, values interface{}) error {
outputFlag := ctx.String("output")
type noopWriteCloser struct {
io.Writer
}
func (c *noopWriteCloser) Close() error {
return nil
}
func outputWriter(ctx *cli.Context) (io.WriteCloser, error) {
output := ctx.String("output")
if output == OutputStdout {
return &noopWriteCloser{ctx.App.Writer}, nil
}
file, err := os.OpenFile(output, os.O_WRONLY|os.O_CREATE, 0o644)
url, err := url.Parse(outputFlag)
if err != nil {
return nil, errors.WithStack(err)
return errors.WithStack(err)
}
return file, nil
encoder := newEncoder()
reader, err := encoder.Encode(url, values)
if err != nil {
return errors.WithStack(err)
}
updater := newUpdater()
writer, err := updater.Update(url)
if err != nil {
return errors.WithStack(err)
}
defer func() {
if err := writer.Close(); err != nil {
panic(errors.WithStack(err))
}
}()
if _, err := io.Copy(writer, reader); err != nil && !errors.Is(err, io.EOF) {
return errors.WithStack(err)
}
return nil
}
func newLoader() *data.Loader {
@ -187,3 +199,18 @@ func newDecoder() *data.Decoder {
yaml.NewDecoderHandler(),
)
}
func newUpdater() *data.Updater {
return data.NewUpdater(
stdout.NewUpdaterHandler(),
fileUpdater.NewUpdaterHandler(),
exec.NewUpdaterHandler(),
)
}
func newEncoder() *data.Encoder {
return data.NewEncoder(
json.NewEncoderHandler(),
yaml.NewEncoderHandler(),
)
}

View File

@ -1,7 +1,6 @@
package command
import (
"encoding/json"
"fmt"
"os"
@ -49,17 +48,8 @@ func Delete() *cli.Command {
return errors.Wrap(err, "could not validate resulting json")
}
output, err := outputWriter(ctx)
if err != nil {
return errors.Wrap(err, "could not create output writer")
}
encoder := json.NewEncoder(output)
encoder.SetIndent("", " ")
if err := encoder.Encode(updatedValues); err != nil {
return errors.Wrap(err, "could not write to output")
if err := outputValues(ctx, updatedValues); err != nil {
return errors.Wrap(err, "could not output updated values")
}
return nil

View File

@ -52,6 +52,13 @@ func Edit() *cli.Command {
server.WithSchema(schema),
server.WithValues(values),
server.WithDefaults(defaults),
server.WithOnUpdate(func(values interface{}) error {
if err := outputValues(ctx, values); err != nil {
return errors.Wrap(err, "could not output updated values")
}
return nil
}),
)
addrs, srvErrs := srv.Start(srvCtx)

View File

@ -1,7 +1,6 @@
package command
import (
"encoding/json"
"fmt"
"os"
@ -50,17 +49,8 @@ func Get() *cli.Command {
return errors.Wrapf(err, "could not get value from pointer '%v'", rawPointer)
}
output, err := outputWriter(ctx)
if err != nil {
return errors.Wrap(err, "could not create output writer")
}
encoder := json.NewEncoder(output)
encoder.SetIndent("", " ")
if err := encoder.Encode(value); err != nil {
return errors.Wrap(err, "could not write to output")
if err := outputValues(ctx, value); err != nil {
return errors.Wrap(err, "could not output updated values")
}
return nil

View File

@ -1,7 +1,6 @@
package command
import (
"encoding/json"
"fmt"
"os"
@ -44,23 +43,17 @@ func Set() *cli.Command {
pointer := jsonpointer.New(rawPointer)
var value interface{}
if err := json.Unmarshal([]byte(rawValue), &value); err != nil {
return errors.Wrapf(err, "could not parse json '%s'", rawValue)
}
var updatedValues interface{}
force := ctx.Bool("force")
if force {
updatedValues, err = pointer.Force(values, value)
updatedValues, err = pointer.Force(values, rawValue)
if err != nil {
return errors.Wrapf(err, "could not force value '%v' to pointer '%v'", rawValue, rawPointer)
}
} else {
updatedValues, err = pointer.Set(values, value)
updatedValues, err = pointer.Set(values, rawValue)
if err != nil {
return errors.Wrapf(err, "could not set value '%v' to pointer '%v'", rawValue, rawPointer)
}
@ -76,17 +69,8 @@ func Set() *cli.Command {
return errors.Wrap(err, "could not validate resulting json")
}
output, err := outputWriter(ctx)
if err != nil {
return errors.Wrap(err, "could not create output writer")
}
encoder := json.NewEncoder(output)
encoder.SetIndent("", " ")
if err := encoder.Encode(updatedValues); err != nil {
return errors.Wrap(err, "could not write to output")
if err := outputValues(ctx, updatedValues); err != nil {
return errors.Wrap(err, "could not output updated values")
}
return nil