summaryrefslogtreecommitdiff
path: root/loadCache.go
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2025-10-22 09:19:26 -0500
committerJeff Carr <[email protected]>2025-10-22 09:19:26 -0500
commit23b2d19bc03b4db253b15cc6fef7176ab31d4f18 (patch)
tree275cb2d3fc92cb5af997582c715f4619eb1d68d2 /loadCache.go
parent820fa4b7e71690accbd17063894032140bd9c4b6 (diff)
finally can fix the Load() and Save() names
Diffstat (limited to 'loadCache.go')
-rw-r--r--loadCache.go318
1 files changed, 0 insertions, 318 deletions
diff --git a/loadCache.go b/loadCache.go
deleted file mode 100644
index 2c8b9a9..0000000
--- a/loadCache.go
+++ /dev/null
@@ -1,318 +0,0 @@
-package config
-
-import (
- "errors"
- "fmt"
- "os"
- "path/filepath"
- "strings"
-
- "go.wit.com/lib/ENV"
- "go.wit.com/log"
- "google.golang.org/protobuf/encoding/protojson"
- "google.golang.org/protobuf/encoding/prototext"
- "google.golang.org/protobuf/proto"
-)
-
-// loads foo.proto from ~/.cache/<appname>/foo.text
-func CacheLoad(pb proto.Message) error {
- appname, err := ENV.GetAppname() // already configured by your application
- if err != nil {
- return err
- }
- protoname, err := GetProtobufName(pb) // defined in the foo.proto file
- if err != nil {
- return err
- }
-
- // Get ~/.cache/appname/protoname.text
- fullname := makeCacheFilename(appname, protoname)
-
- // get the current filename in the protobuf file
- curfilename, err := GetFilename(pb)
- if err != nil {
- return err
- }
- if curfilename == "" {
- // log.Printf("ConfigLoad() read in %s\n", fullname)
- }
-
- err = loadPB(pb, fullname)
- if err != nil {
- return ErrMarshal
- }
-
- // If the cache file is new or has moved, this updates it to correct filename
- // (the filename is what is used by pb.Save()
- if curfilename != fullname {
- _, err := SetFilename(pb, fullname)
- if err != nil {
- log.Info("FILENAME COULD NOT BE SET old=", curfilename)
- log.Info("FILENAME COULD NOT BE SET new=", fullname)
- return errors.Join(err, errors.New("something is wrong in lib/config"))
- }
- }
- return nil
-}
-
-// loads from the users .cache dir
-// if the .proto file version changes, automatically delete the .pb
-// file. This is important to avoid marshalling garbage data
-// .cache files are treated as such, a "cache" file. don't keep important
-// things in here. argv stores the information here for autodelete
-func LoadCache(pb proto.Message, appname string, protoname string) error {
- cacheDir, _ := os.UserCacheDir()
- fullpath := filepath.Join(cacheDir, appname)
- os.MkdirAll(fullpath, os.ModePerm)
- fullname := filepath.Join(fullpath, protoname+".pb")
- _, err := SetFilename(pb, fullname)
- if err != nil {
- pb = nil
- os.Remove(fullname)
- return err
- }
- newver, curver, err := LoadVersionCheckPB(pb)
- if err != nil {
- pb = nil
- os.Remove(fullname)
- return err
- }
- _, _ = newver, curver
- return nil
-}
-
-func LoadVersionCheckPB(pb proto.Message) (string, string, error) {
- var newver string
- var pbver string
- var err error
-
- fullname, err := GetFilename(pb)
- if err != nil {
- return newver, pbver, err
- }
- // text is supposed to be "easy". Don't verify 'version'
- if strings.HasSuffix(fullname, ".text") {
- err = loadTEXT(pb, fullname)
- return newver, pbver, err
- }
-
- // verify 'version' for .pb files
- // application should die if they don't match
- var worked bool
- newver, err = GetString(pb, "version")
- if err != nil {
- return newver, pbver, err
- }
- // maybe don't really verify .json files (?)
- // doing it for now anyway. maybe just return an error
- if strings.HasSuffix(fullname, ".json") {
- if err = loadJSON(pb, fullname); err != nil {
- return newver, pbver, err
- }
- worked = true
- }
- if strings.HasSuffix(fullname, ".pb") {
- if err = loadPB(pb, fullname); err != nil {
- return newver, pbver, err
- }
- _, err = SetFilename(pb, fullname)
- if err != nil {
- return newver, pbver, err
- }
- worked = true
- }
- if !worked {
- return newver, pbver, fmt.Errorf("unknown filetype '%s'", fullname)
- }
- // get the version from the current PB saved on disk
- pbver, _ = GetString(pb, "version")
- if newver != pbver {
- return newver, pbver, VersionMismatch
- }
- return newver, pbver, nil
-}
-
-// uses the version to die. This is needed because loading binary
-// protobuf files with rearranged messages is indeterminate
-func LoadPB(pb proto.Message) error {
- fullname, err := GetFilename(pb)
- if fullname == "" {
- panic("config.LoadPB() got blank filename = ''")
- }
- if err != nil {
- return err
- }
- // this code needs work
- newver, pbver, err := LoadVersionCheckPB(pb)
- if errors.Is(err, os.ErrNotExist) {
- return err
- }
- if errors.Is(err, VersionMismatch) || (newver != pbver) {
- fmt.Println("")
- fmt.Printf("VERSION new '%s' != cur PB '%s'\n", newver, pbver)
- fmt.Println("")
- fmt.Println("Your protobuf file is old and can not be loaded")
- fmt.Println("your application must decide how to handle this (delete or fix)")
- fmt.Println("always die here. application is broken")
- fmt.Println("You must delete or convert the file", fullname)
- fmt.Println("")
- // probably should ALWAYS PANIC HERE
- // upon further study, always die here is better than not
- s := fmt.Sprintf("protobuf version wrong. delete or fix %s", fullname)
- panic(s)
- }
- if err != nil {
- // return to let the application figure this out
- return err
- }
- return nil
-}
-
-func LoadFromFilename(pb proto.Message, fullname string) error {
- return LoadFile(pb, fullname)
-}
-
-func LoadFile(pb proto.Message, fullname string) error {
- if strings.HasSuffix(fullname, ".text") {
- return loadTEXT(pb, fullname)
- }
- if strings.HasSuffix(fullname, ".json") {
- return loadJSON(pb, fullname)
- }
- if strings.HasSuffix(fullname, ".pb") {
- return loadPB(pb, fullname)
- }
-
- return fmt.Errorf("unknown filetype '%s'", fullname)
-}
-
-func loadPB(pb proto.Message, fullname string) error {
- data, err := loadFile(fullname)
- if err != nil {
- // set pb.Filename that was attempted
- return err
- }
-
- if err = proto.Unmarshal(data, pb); err != nil {
- return err
- }
-
- return nil
-}
-
-func LoadConfigPB(pb proto.Message, appname string, protoname string) (string, error) {
- var fullname string
- if strings.HasPrefix(appname, "/") {
- fullname = filepath.Join(appname, protoname+".pb")
- } else {
- configDir, err := os.UserConfigDir()
- if err != nil {
- return "", err
- }
-
- fullname = filepath.Join(configDir, appname, protoname+".pb")
- }
-
- data, err := loadFile(fullname)
- if err != nil {
- return fullname, err
- }
-
- // Unmarshal()
- if err = proto.Unmarshal(data, pb); err != nil {
- return fullname, err
- }
-
- return fullname, nil
-}
-
-func loadTEXT(pb proto.Message, fullname string) error {
- var data []byte
- var err error
- SetFilename(pb, fullname)
- if data, err = loadFile(fullname); err != nil {
- return err
- }
-
- // don't even bother with Marshal()
- if data == nil {
- return ErrEmpty // file is empty
- }
-
- // Unmarshal()
- if err = prototext.Unmarshal(data, pb); err != nil {
- return ErrMarshal
- }
-
- if fn, err := GetFilename(pb); err != nil {
- if fn != fullname {
- SetFilename(pb, fullname)
- }
- }
- return nil
-}
-
-// json files are backup Marshal() data in case .text Unmarshal() fails
-// they always should have the ".text" filename in them
-func loadJSON(pb proto.Message, fullname string) error {
- var data []byte
- var err error
- if data, err = loadFile(fullname); err != nil {
- return err
- }
-
- // don't even bother with Marshal()
- if data == nil {
- return ErrEmpty // file is empty
- }
-
- // Unmarshal()
- if err = protojson.Unmarshal(data, pb); err != nil {
- return ErrMarshal
- }
-
- if fn, err := GetFilename(pb); err != nil {
- if fn != fullname {
- SetFilename(pb, fullname)
- }
- }
- return nil
-}
-
-/* left this here to remind myself just how dumb I can be
-
-// dumb but simple to read logic
-func missingConfig(fullname string) error {
- data1, err1 := os.ReadFile(fullname)
- if !errors.Is(err1, os.ErrNotExist) {
- return err1
- }
-
- data2, err2 := os.ReadFile(fullname + ".json")
- if !errors.Is(err2, os.ErrNotExist) {
- return err2
- }
- if errors.Is(err1, os.ErrNotExist) && errors.Is(err2, os.ErrNotExist) {
- return os.ErrNotExist
- }
- if (len(data1) == 0) && (len(data2) == 0) {
- return ErrEmpty
- }
- return nil
-}
-*/
-
-func loadFile(fullname string) ([]byte, error) {
- data, err := os.ReadFile(fullname)
- if errors.Is(err, os.ErrNotExist) {
- // if file does not exist, just return nil. this
- return nil, err
- }
- if err != nil {
- return nil, err
- }
- if len(data) == 0 {
- return data, ErrEmpty
- }
- return data, nil
-}