setmeta updates to support json files (or reading stdin). easier interop with getmeta (#1240)

This commit is contained in:
Mike Sawka 2024-11-08 10:19:57 -08:00 committed by GitHub
parent fb641ac717
commit b36a7df929
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -6,6 +6,8 @@ package cmd
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"os"
"strconv" "strconv"
"strings" "strings"
@ -14,15 +16,46 @@ import (
) )
var setMetaCmd = &cobra.Command{ var setMetaCmd = &cobra.Command{
Use: "setmeta {blockid|blocknum|this} key=value ...", Use: "setmeta [-b {blockid|blocknum|this}] [--json file.json] key=value ...",
Short: "set metadata for an entity", Short: "set metadata for an entity",
Args: cobra.MinimumNArgs(1), Args: cobra.MinimumNArgs(0),
Run: setMetaRun, Run: setMetaRun,
PreRunE: preRunSetupRpcClient, PreRunE: preRunSetupRpcClient,
} }
var setMetaJsonFilePath string
func init() { func init() {
rootCmd.AddCommand(setMetaCmd) rootCmd.AddCommand(setMetaCmd)
setMetaCmd.Flags().StringVar(&setMetaJsonFilePath, "json", "", "JSON file containing metadata to apply (use '-' for stdin)")
}
func loadJSONFile(filepath string) (map[string]interface{}, error) {
var data []byte
var err error
if filepath == "-" {
data, err = io.ReadAll(os.Stdin)
if err != nil {
return nil, fmt.Errorf("reading from stdin: %v", err)
}
} else {
data, err = os.ReadFile(filepath)
if err != nil {
return nil, fmt.Errorf("reading JSON file: %v", err)
}
}
var result map[string]interface{}
if err := json.Unmarshal(data, &result); err != nil {
return nil, fmt.Errorf("parsing JSON file: %v", err)
}
if result == nil {
return nil, fmt.Errorf("JSON file must contain an object, not null")
}
return result, nil
} }
func parseMetaSets(metaSets []string) (map[string]interface{}, error) { func parseMetaSets(metaSets []string) (map[string]interface{}, error) {
@ -39,7 +72,7 @@ func parseMetaSets(metaSets []string) (map[string]interface{}, error) {
meta[fields[0]] = true meta[fields[0]] = true
} else if setVal == "false" { } else if setVal == "false" {
meta[fields[0]] = false meta[fields[0]] = false
} else if setVal[0] == '[' || setVal[0] == '{' { } else if setVal[0] == '[' || setVal[0] == '{' || setVal[0] == '"' {
var val interface{} var val interface{}
err := json.Unmarshal([]byte(setVal), &val) err := json.Unmarshal([]byte(setVal), &val)
if err != nil { if err != nil {
@ -63,31 +96,63 @@ func parseMetaSets(metaSets []string) (map[string]interface{}, error) {
return meta, nil return meta, nil
} }
func simpleMergeMeta(meta map[string]interface{}, metaUpdate map[string]interface{}) map[string]interface{} {
for k, v := range metaUpdate {
if v == nil {
delete(meta, k)
} else {
meta[k] = v
}
}
return meta
}
func setMetaRun(cmd *cobra.Command, args []string) { func setMetaRun(cmd *cobra.Command, args []string) {
oref := blockArg if blockArg == "" {
metaSetsStrs := args[:] WriteStderr("[error] block (oref) is required\n")
if oref == "" {
WriteStderr("[error] oref is required\n")
return return
} }
err := validateEasyORef(oref) err := validateEasyORef(blockArg)
if err != nil { if err != nil {
WriteStderr("[error] %v\n", err) WriteStderr("[error] %v\n", err)
return return
} }
meta, err := parseMetaSets(metaSetsStrs)
var jsonMeta map[string]interface{}
if setMetaJsonFilePath != "" {
jsonMeta, err = loadJSONFile(setMetaJsonFilePath)
if err != nil {
WriteStderr("[error] %v\n", err)
return
}
}
cmdMeta, err := parseMetaSets(args)
if err != nil { if err != nil {
WriteStderr("[error] %v\n", err) WriteStderr("[error] %v\n", err)
return return
} }
fullORef, err := resolveSimpleId(oref)
// Merge JSON metadata with command-line metadata, with command-line taking precedence
var fullMeta map[string]any
if len(jsonMeta) > 0 {
fullMeta = simpleMergeMeta(jsonMeta, cmdMeta)
} else {
fullMeta = cmdMeta
}
if len(fullMeta) == 0 {
WriteStderr("[error] no metadata keys specified\n")
return
}
fullORef, err := resolveSimpleId(blockArg)
if err != nil { if err != nil {
WriteStderr("[error] resolving oref: %v\n", err) WriteStderr("[error] resolving oref: %v\n", err)
return return
} }
setMetaWshCmd := &wshrpc.CommandSetMetaData{ setMetaWshCmd := &wshrpc.CommandSetMetaData{
ORef: *fullORef, ORef: *fullORef,
Meta: meta, Meta: fullMeta,
} }
_, err = RpcClient.SendRpcRequest(wshrpc.Command_SetMeta, setMetaWshCmd, &wshrpc.RpcOpts{Timeout: 2000}) _, err = RpcClient.SendRpcRequest(wshrpc.Command_SetMeta, setMetaWshCmd, &wshrpc.RpcOpts{Timeout: 2000})
if err != nil { if err != nil {