work on config file save

This commit is contained in:
Jeff Carr 2024-12-05 12:37:07 -06:00
parent f98179971e
commit 34a287a38e
4 changed files with 91 additions and 72 deletions

141
config.go
View File

@ -7,24 +7,38 @@ import (
"errors"
"os"
"path/filepath"
"time"
"go.wit.com/log"
)
// write to ~/.config/forge/ unless ENV{FORGE_HOME} is set
func (f *Forge) ConfigSave() error {
// f.Config.Lock()
// defer f.Config.UnLock()
if os.Getenv("FORGE_HOME") == "" {
homeDir, _ := os.UserHomeDir()
fullpath := filepath.Join(homeDir, ".config/forge")
os.Setenv("FORGE_HOME", fullpath)
var err error
// backup the current config files
if e := backupConfig(); e != nil {
log.Info("forge.BackupConfig() error", e)
err = e
// continue here? notsure. could be bad either way
// out of disk space?
}
// try to backup the current cluster config files
if err := backupConfig(); err != nil {
return err
if f.Config != nil {
if e := f.Config.ConfigSave(); e != nil {
log.Info("forge.Config.ConfigSave() error", e)
err = e
}
}
data, err := f.Config.Marshal()
if f.Repos != nil {
if e := f.Repos.ConfigSave(); e != nil {
log.Info("forge.Repos.ConfigSave() error", e)
err = e
}
}
return err
}
// write to ~/.config/forge/ unless ENV{FORGE_CONFIG} is set
func (f *ForgeConfigs) ConfigSave() error {
data, err := f.Marshal()
if err != nil {
log.Info("proto.Marshal() failed len", len(data), err)
return err
@ -32,88 +46,83 @@ func (f *Forge) ConfigSave() error {
log.Info("forgepb.ConfigSave() proto.Marshal() worked len", len(data))
configWrite("forge.pb", data)
s := f.Config.FormatTEXT()
s := f.FormatTEXT()
configWrite("forge.text", []byte(s))
s = f.Config.FormatJSON()
s = f.FormatJSON()
configWrite("forge.json", []byte(s))
if f.Repos != nil {
f.Repos.ConfigSave()
}
return nil
}
// load the ~/.config/forge/ files
func (c *ForgeConfigs) ConfigLoad() error {
if os.Getenv("FORGE_HOME") == "" {
if os.Getenv("FORGE_CONFIG") == "" {
homeDir, _ := os.UserHomeDir()
fullpath := filepath.Join(homeDir, ".config/forge")
os.Setenv("FORGE_HOME", fullpath)
os.Setenv("FORGE_CONFIG", fullpath)
}
var data []byte
var err error
// var data []byte
// var err error
if c == nil {
// can't safely do c = new(ForgeConfig) if c is in a struct from the caller. notsure why
return errors.New("It's not safe to run ConfigLoad() on a nil")
}
if data, err = loadFile("forge.pb"); err != nil {
// something went wrong loading the file
return err
}
if data != nil {
// this means the forge.pb file exists and was read
if len(data) == 0 {
// todo: error out if the file is empty?
// try forge.text & forge.json?
if data, err := loadFile("forge.pb"); err == nil {
if data != nil {
if len(data) != 0 {
if err = c.Unmarshal(data); err == nil {
log.Info("forge.ConfigLoad()", len(c.ForgeConfigs), "entries in ~/.config/forge")
return nil
}
}
}
if err = c.Unmarshal(data); err != nil {
log.Warn("broken forge.pb config file")
return err
}
log.Info("found", len(c.ForgeConfigs), "entries in ~/.config/forge")
return nil
}
log.Warn("broken forge.pb config file")
// forge.db doesn't exist. try forge.text
// this lets the user hand edit the config
if data, err = loadFile("forge.text"); err != nil {
// something went wrong loading the file
return err
}
if data != nil {
// this means the forge.text file exists and was read
if len(data) == 0 {
// todo: error out if the file is empty?
if data, err := loadFile("forge.text"); err == nil {
if data != nil {
// this means the forge.text file exists and was read
if len(data) != 0 {
if err = c.UnmarshalTEXT(data); err != nil {
log.Info("forge.ConfigLoad()", len(c.ForgeConfigs), "entries in ~/.config/forge")
// forge.pb file was broken. save on load right away
log.Info("attempting forge.ConfigSave()")
c.ConfigSave()
return nil
}
// todo: error out if the file is empty?
}
}
if err = c.UnmarshalTEXT(data); err != nil {
log.Warn("broken forge.text config file")
return err
}
log.Info("found", len(c.ForgeConfigs), "entries in ~/.config/forge")
return nil
}
// forge.text doesn't exist. try forge.json
// this lets the user hand edit the config
if data, err = loadFile("forge.json"); err != nil {
// something went wrong loading the file
return err
if data, err := loadFile("forge.json"); err != nil {
if data != nil {
// this means the forge.json file exists and was read
if len(data) != 0 {
if err = c.UnmarshalJSON(data); err == nil {
log.Info("forge.ConfigLoad()", len(c.ForgeConfigs), "entries in ~/.config/forge")
// forge.pb file was broken. save on load right away
log.Info("attempting forge.ConfigSave()")
c.ConfigSave()
return nil
}
}
}
}
if data != nil {
// this means the forge.text file exists and was read
if len(data) == 0 {
// todo: error out if the file is empty?
}
if err = c.UnmarshalJSON(data); err != nil {
log.Warn("broken forge.json config file")
return err
}
log.Info("found", len(c.ForgeConfigs), "entries in ~/.config/forge")
return nil
cpath := filepath.Join(os.Getenv("FORGE_CONFIG"), ".")
if _, err := os.Stat(cpath); err == nil {
log.Info("Something has gone wrong. Your", os.Getenv("FORGE_CONFIG"), "directory exists")
log.Info("However, the config files could not be loaded")
time.Sleep(2 * time.Second)
os.Exit(-1)
// return errors.New("config files can not be loaded from" + os.Getenv("FORGE_CONFIG"))
}
// first time user. make a template config file
@ -123,7 +132,7 @@ func (c *ForgeConfigs) ConfigLoad() error {
}
func loadFile(filename string) ([]byte, error) {
fullname := filepath.Join(os.Getenv("FORGE_HOME"), filename)
fullname := filepath.Join(os.Getenv("FORGE_CONFIG"), filename)
data, err := os.ReadFile(fullname)
if errors.Is(err, os.ErrNotExist) {
// if file does not exist, just return nil. this
@ -139,7 +148,7 @@ func loadFile(filename string) ([]byte, error) {
}
func configWrite(filename string, data []byte) error {
fullname := filepath.Join(os.Getenv("FORGE_HOME"), filename)
fullname := filepath.Join(os.Getenv("FORGE_CONFIG"), filename)
cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE, 0666)
defer cfgfile.Close()

View File

@ -18,8 +18,8 @@ func backupConfig() error {
now := time.Now()
// timestamp := now.Format("2022.07.18.190545") // 50yr shout out to K&R
timestamp := now.Format("2006.01.02.150405") // bummer. other date doesn't work?
srcDir := filepath.Join(os.Getenv("FORGE_HOME"))
destDir := filepath.Join(os.Getenv("FORGE_HOME"), timestamp)
srcDir := filepath.Join(os.Getenv("FORGE_CONFIG"))
destDir := filepath.Join(os.Getenv("FORGE_CONFIG"), timestamp)
return backupFiles(srcDir, destDir)
}

View File

@ -27,10 +27,11 @@ message ForgeConfig {
string userBranchName = 10; // whatever your username branch is
string debName = 11; // the actual name used with 'apt install' (or distro apt equivalent.
// todo: appeal to everyone to alias 'apt' on rhat, gentoo, arch, etc to alias 'apt install'
// todo: appeal to everyone to alias 'apt' on fedora, gentoo, arch, etc to alias 'apt install'
// so we can make easier instructions for new linux users. KISS
google.protobuf.Timestamp verstamp = 12; // the git commit timestamp of the version
string goSrc = 13; // is ~/go/src unless a go.work file is found
}
message ForgeConfigs { // `autogenpb:marshal`

15
init.go
View File

@ -2,6 +2,7 @@ package forgepb
import (
"os"
"path/filepath"
"go.wit.com/lib/protobuf/gitpb"
"go.wit.com/lib/protobuf/zoopb"
@ -23,6 +24,13 @@ func Init() *Forge {
}
f.goSrc = os.Getenv("FORGE_GOSRC")
// also rethink this, but maybe this is the right thing to do
if os.Getenv("FORGE_CONFIG") == "" {
homeDir, _ := os.UserHomeDir()
fullpath := filepath.Join(homeDir, ".config/forge")
os.Setenv("FORGE_CONFIG", fullpath)
}
// cache.go has Do()
// f.initOnce.Do(f.initWork)
@ -42,10 +50,11 @@ func Init() *Forge {
log.Warn("zoopb.ConfigLoad() failed", err)
os.Exit(-1)
}
f.Machine.InitWit()
// f.Machine.InitWit()
log.Info("forge pre scan ", f.Repos.Len(), "repos in", f.goSrc)
start := f.Repos.Len()
f.ScanGoSrc()
log.Info("forge.Init() found", f.Repos.Len(), "repos in", f.goSrc)
end := f.Repos.Len()
log.Info("forge.ScanGoSrc() Found", end-start, "new repos in", f.goSrc)
return f
}