redo config handling
This commit is contained in:
parent
2b3dfe540c
commit
602e1fc4ae
1
argv.go
1
argv.go
|
@ -20,7 +20,6 @@ type args struct {
|
|||
Clean *CleanCmd `arg:"subcommand:clean" help:"start over at the beginning"`
|
||||
Commit *CommitCmd `arg:"subcommand:commit" help:"'git commit' but errors out if on wrong branch"`
|
||||
Config *ConfigCmd `arg:"subcommand:config" help:"show your .config/forge/ settings"`
|
||||
Debug *EmptyCmd `arg:"subcommand:debug" help:"debug forge"`
|
||||
Dirty *DirtyCmd `arg:"subcommand:dirty" help:"show dirty git repos"`
|
||||
GitFetch *FindCmd `arg:"subcommand:fetch" help:"run 'git fetch master'"`
|
||||
Gui *EmptyCmd `arg:"subcommand:gui" help:"open the gui"`
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
package main
|
||||
|
||||
// functions to import and export the protobuf
|
||||
// data to and from config files
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"go.wit.com/lib/config"
|
||||
"go.wit.com/lib/protobuf/forgepb"
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
func forgeConfigSave() error {
|
||||
return config.ConfigSave(me.forge.Config)
|
||||
}
|
||||
|
||||
func configInit() (*forgepb.ForgeConfigs, error) {
|
||||
/*
|
||||
// the default forged dir is /home/forge
|
||||
if os.Getenv("FORGE_GOSRC") == "" {
|
||||
os.Setenv("FORGE_GOSRC", "/home/forge")
|
||||
}
|
||||
|
||||
if os.Getenv("FORGE_PATCHDIR") == "" {
|
||||
os.Setenv("FORGE_PATCHDIR", "/var/lib/forged")
|
||||
}
|
||||
*/
|
||||
|
||||
me.urlbase = argv.URL
|
||||
if me.urlbase == "" {
|
||||
me.urlbase = "https://go.wit.com/"
|
||||
}
|
||||
if os.Getenv("FORGE_URL") != "" {
|
||||
me.urlbase = os.Getenv("FORGE_URL")
|
||||
log.Info("got forge url", me.urlbase)
|
||||
}
|
||||
me.urlbase = strings.Trim(me.urlbase, "/") // track down why trailing '/' makes http POST not work
|
||||
|
||||
configs := new(forgepb.ForgeConfigs)
|
||||
err := config.ConfigLoad(configs, ARGNAME, "forge")
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
// if forgepb.FirstTimeUser() {
|
||||
log.Info("You are running forge for the first time here")
|
||||
// }
|
||||
configs.ReposDir = "/home/forge"
|
||||
configs.ReposPB = "/home/forge/repos.pb"
|
||||
configs.PatchDir = "/var/lib/forged"
|
||||
if err := forgeConfigSave(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Info("WARNING: made a new default config file here", configs.Filename)
|
||||
okExit("")
|
||||
}
|
||||
if err != nil {
|
||||
}
|
||||
return configs, err
|
||||
}
|
||||
|
||||
func sampleConfig(all *forgepb.ForgeConfigs) {
|
||||
new1 := new(forgepb.ForgeConfig)
|
||||
new1.GoPath = "go.wit.com"
|
||||
new1.Writable = true
|
||||
new1.Directory = true
|
||||
all.Append(new1)
|
||||
|
||||
fmt.Println("first time user. adding an example config file with", len(all.ForgeConfigs), "repos")
|
||||
}
|
168
doDebug.go
168
doDebug.go
|
@ -1,168 +0,0 @@
|
|||
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
|
||||
// Use of this source code is governed by the GPL 3.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"reflect"
|
||||
"unicode/utf8"
|
||||
|
||||
"go.wit.com/lib/protobuf/bugpb"
|
||||
"go.wit.com/lib/protobuf/forgepb"
|
||||
"golang.org/x/text/encoding/charmap"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func doDebug() {
|
||||
me.forge = forgepb.InitPB()
|
||||
me.forge.ScanGoSrc()
|
||||
if err := me.forge.ConfigSave(); err != nil {
|
||||
if err := me.forge.Repos.ConfigSave(); err != nil {
|
||||
err := ValidateProtoUTF8(me.forge.Repos)
|
||||
if err != nil {
|
||||
log.Printf("Protobuf UTF-8 validation failed: %v\n", err)
|
||||
}
|
||||
if err := bugpb.SanitizeProtoUTF8(me.forge.Repos); err != nil {
|
||||
log.Fatalf("Sanitization failed: %v", err)
|
||||
}
|
||||
}
|
||||
// badExit(err)
|
||||
}
|
||||
me.forge.SetConfigSave(true)
|
||||
me.forge.Exit()
|
||||
okExit("this never runs")
|
||||
}
|
||||
|
||||
// ValidateProtoUTF8 checks all string fields in a proto.Message recursively.
|
||||
func ValidateProtoUTF8(msg proto.Message) error {
|
||||
return validateValue(reflect.ValueOf(msg), "")
|
||||
}
|
||||
|
||||
func validateValue(val reflect.Value, path string) error {
|
||||
if !val.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if val.Kind() == reflect.Ptr {
|
||||
if val.IsNil() {
|
||||
return nil
|
||||
}
|
||||
return validateValue(val.Elem(), path)
|
||||
}
|
||||
|
||||
switch val.Kind() {
|
||||
case reflect.Struct:
|
||||
for i := 0; i < val.NumField(); i++ {
|
||||
field := val.Field(i)
|
||||
fieldType := val.Type().Field(i)
|
||||
fieldPath := fmt.Sprintf("%s.%s", path, fieldType.Name)
|
||||
if err := validateValue(field, fieldPath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.String:
|
||||
s := val.String()
|
||||
if !utf8.ValidString(s) {
|
||||
return fmt.Errorf("invalid UTF-8 string at %s: %q", path, s)
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
if val.Type().Elem().Kind() == reflect.Uint8 {
|
||||
return nil // skip []byte
|
||||
}
|
||||
for i := 0; i < val.Len(); i++ {
|
||||
if err := validateValue(val.Index(i), fmt.Sprintf("%s[%d]", path, i)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
for _, key := range val.MapKeys() {
|
||||
valItem := val.MapIndex(key)
|
||||
if err := validateValue(valItem, fmt.Sprintf("%s[%v]", path, key)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SanitizeProtoUTF8 fixes all invalid UTF-8 strings in a proto.Message recursively.
|
||||
func SanitizeProtoUTF8(msg proto.Message) error {
|
||||
return sanitizeValue(reflect.ValueOf(msg), "")
|
||||
}
|
||||
|
||||
func sanitizeValue(val reflect.Value, path string) error {
|
||||
if !val.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if val.Kind() == reflect.Ptr {
|
||||
if val.IsNil() {
|
||||
return nil
|
||||
}
|
||||
return sanitizeValue(val.Elem(), path)
|
||||
}
|
||||
|
||||
switch val.Kind() {
|
||||
case reflect.Struct:
|
||||
for i := 0; i < val.NumField(); i++ {
|
||||
field := val.Field(i)
|
||||
fieldType := val.Type().Field(i)
|
||||
if !field.CanSet() {
|
||||
continue
|
||||
}
|
||||
if err := sanitizeValue(field, fmt.Sprintf("%s.%s", path, fieldType.Name)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.String:
|
||||
s := val.String()
|
||||
if !utf8.ValidString(s) {
|
||||
utf8Str, err := latin1ToUTF8(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to convert %s to UTF-8: %v", path, err)
|
||||
}
|
||||
val.SetString(utf8Str)
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
if val.Type().Elem().Kind() == reflect.Uint8 {
|
||||
return nil // skip []byte
|
||||
}
|
||||
for i := 0; i < val.Len(); i++ {
|
||||
if err := sanitizeValue(val.Index(i), fmt.Sprintf("%s[%d]", path, i)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
for _, key := range val.MapKeys() {
|
||||
valItem := val.MapIndex(key)
|
||||
newItem := reflect.New(valItem.Type()).Elem()
|
||||
newItem.Set(valItem)
|
||||
if err := sanitizeValue(newItem, fmt.Sprintf("%s[%v]", path, key)); err != nil {
|
||||
return err
|
||||
}
|
||||
val.SetMapIndex(key, newItem)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func latin1ToUTF8(input string) (string, error) {
|
||||
reader := charmap.ISO8859_1.NewDecoder().Reader(bytes.NewReader([]byte(input)))
|
||||
result, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(result), nil
|
||||
}
|
36
main.go
36
main.go
|
@ -8,7 +8,6 @@ package main
|
|||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -50,37 +49,12 @@ func main() {
|
|||
me.myGui = prep.Gui() // prepares the GUI package for go-args
|
||||
me.pp = arg.MustParse(&argv)
|
||||
|
||||
/*
|
||||
if argv.Bash {
|
||||
fhelp.DoBash(ARGNAME)
|
||||
os.Exit(0)
|
||||
}
|
||||
if len(argv.BashAuto) != 0 {
|
||||
argv.doBashAuto()
|
||||
os.Exit(0)
|
||||
}
|
||||
*/
|
||||
me.urlbase = argv.URL
|
||||
if me.urlbase == "" {
|
||||
me.urlbase = "https://go.wit.com/"
|
||||
}
|
||||
if os.Getenv("FORGE_URL") != "" {
|
||||
me.urlbase = os.Getenv("FORGE_URL")
|
||||
log.Info("got forge url", me.urlbase)
|
||||
}
|
||||
me.urlbase = strings.Trim(me.urlbase, "/") // track down why trailing '/' makes http POST not work
|
||||
|
||||
// internally debugging can be triggered here before Init()
|
||||
if argv.Debug != nil {
|
||||
doDebug()
|
||||
okExit("")
|
||||
}
|
||||
|
||||
if forgepb.FirstTimeUser() {
|
||||
log.Info("You are running forge for the first time here")
|
||||
}
|
||||
// load the ~/.config/forge/ config
|
||||
me.forge = forgepb.Init()
|
||||
cfg, err := configInit()
|
||||
if err != nil {
|
||||
badExit(err)
|
||||
}
|
||||
me.forge = forgepb.InitFromConfig(cfg)
|
||||
|
||||
// initialize patches
|
||||
doPatchInit()
|
||||
|
|
Loading…
Reference in New Issue