github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/tiltfile/encoding/json.go (about) 1 package encoding 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "os" 8 "strings" 9 10 "github.com/pkg/errors" 11 "go.starlark.net/starlark" 12 13 tiltfile_io "github.com/tilt-dev/tilt/internal/tiltfile/io" 14 "github.com/tilt-dev/tilt/internal/tiltfile/starkit" 15 "github.com/tilt-dev/tilt/internal/tiltfile/value" 16 ) 17 18 // reads json from a file 19 func readJSON(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { 20 path := value.NewLocalPathUnpacker(thread) 21 var defaultValue starlark.Value 22 if err := starkit.UnpackArgs(thread, fn.Name(), args, kwargs, "paths", &path, "default?", &defaultValue); err != nil { 23 return nil, err 24 } 25 26 localPath := path.Value 27 contents, err := tiltfile_io.ReadFile(thread, localPath) 28 if err != nil { 29 // Return the default value if the file doesn't exist AND a default value was given 30 if os.IsNotExist(err) && defaultValue != nil { 31 return defaultValue, nil 32 } 33 return nil, err 34 } 35 36 return jsonStringToStarlark(string(contents), localPath) 37 } 38 39 // reads json from a string 40 func decodeJSON(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { 41 var contents value.Stringable 42 if err := starkit.UnpackArgs(thread, fn.Name(), args, kwargs, "json", &contents); err != nil { 43 return nil, err 44 } 45 46 return jsonStringToStarlark(contents.Value, "") 47 } 48 49 func jsonStringToStarlark(s string, source string) (starlark.Value, error) { 50 var decodedJSON interface{} 51 dec := json.NewDecoder(strings.NewReader(s)) 52 dec.UseNumber() 53 if err := dec.Decode(&decodedJSON); err != nil { 54 return nil, wrapError(err, "error parsing JSON", source) 55 } 56 if dec.More() { 57 return nil, wrapError(fmt.Errorf("found multiple JSON values"), "error parsing JSON", source) 58 } 59 60 v, err := ConvertStructuredDataToStarlark(decodedJSON) 61 if err != nil { 62 return nil, wrapError(err, "error converting JSON to Starlark", source) 63 } 64 return v, nil 65 } 66 67 func encodeJSON(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { 68 var obj starlark.Value 69 if err := starkit.UnpackArgs(thread, fn.Name(), args, kwargs, "obj", &obj); err != nil { 70 return nil, err 71 } 72 73 ret, err := starlarkToJSONString(obj) 74 if err != nil { 75 return nil, err 76 } 77 78 return starlark.String(ret), nil 79 } 80 81 func starlarkToJSONString(obj starlark.Value) (string, error) { 82 v, err := convertStarlarkToStructuredData(obj) 83 if err != nil { 84 return "", errors.Wrap(err, "error converting object from starlark") 85 } 86 87 w := bytes.Buffer{} 88 e := json.NewEncoder(&w) 89 e.SetIndent("", " ") 90 err = e.Encode(v) 91 if err != nil { 92 return "", errors.Wrap(err, "error serializing object to json") 93 } 94 95 return w.String(), nil 96 }