From a3bf678aa43a57c20b0e4cc5658fdf21658141d7 Mon Sep 17 00:00:00 2001 From: Sotirios Mantziaris Date: Sun, 13 Oct 2024 13:47:09 +0300 Subject: [PATCH 1/7] Refactor seesing --- seed/seed.go | 51 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/seed/seed.go b/seed/seed.go index a9d1110..12740e5 100644 --- a/seed/seed.go +++ b/seed/seed.go @@ -68,25 +68,13 @@ func (s *Seeder) Seed(cfg *config.Config) error { slog.Debug("seed applied", "value", f, "name", f.Name()) seedMap[f] = true } - key, ok := ss[config.SourceEnv] - if ok { //nolint:nestif - val, ok := os.LookupEnv(key) - if ok { - err := f.Set(val, 0) - if err != nil { - return err - } - slog.Debug("env var applied", "value", f, "name", f.Name()) - seedMap[f] = true - } else { - if seedMap[f] { - slog.Debug("env var did not exist", "key", key, "name", f.Name()) - } else { - slog.Debug("env var did not exist and no seed value provided", "key", key, "name", f.Name()) - } - } + + err := processEnvField(f, seedMap) + if err != nil { + return err } - key, ok = ss[config.SourceFlag] + + key, ok := ss[config.SourceFlag] if ok { var val string flagSet.StringVar(&val, key, "", "") @@ -205,3 +193,30 @@ func (s *Seeder) Seed(cfg *config.Config) error { } return nil } + +func processEnvField(f *config.Field, seedMap map[*config.Field]bool) error { + key, ok := f.Sources()[config.SourceEnv] + if !ok { + return nil + } + val, ok := os.LookupEnv(key) + if !ok { + slog.Debug("env var did not exist", "key", key, "name", f.Name()) + + // if seedMap[f] { + // slog.Debug("env var did not exist", "key", key, "name", f.Name()) + // } else { + // slog.Debug("env var did not exist and no seed value provided", "key", key, "name", f.Name()) + // } + + return nil + } + + err := f.Set(val, 0) + if err != nil { + return err + } + slog.Debug("env var applied", "value", f, "name", f.Name()) + seedMap[f] = true + return nil +} From 8686df5caccdbceca015a6c264d35e0c90db1545 Mon Sep 17 00:00:00 2001 From: Sotirios Mantziaris Date: Sun, 13 Oct 2024 13:56:04 +0300 Subject: [PATCH 2/7] Refactor seeding --- seed/seed.go | 52 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/seed/seed.go b/seed/seed.go index 12740e5..3a27c19 100644 --- a/seed/seed.go +++ b/seed/seed.go @@ -80,21 +80,12 @@ func (s *Seeder) Seed(cfg *config.Config) error { flagSet.StringVar(&val, key, "", "") flagInfos = append(flagInfos, &flagInfo{key, f, &val}) } - key, ok = ss[config.SourceFile] - if ok { - body, err := os.ReadFile(key) - if err != nil { - slog.Error("failed to read file", "file", key, "name", f.Name(), "err", err) - } else { - err := f.Set(string(body), 0) - if err != nil { - return err - } - slog.Debug("file based var applied", "value", f, "field", f.Name()) - seedMap[f] = true - } + err = processFileField(f, seedMap) + if err != nil { + return err } + key, ok = ss[config.SourceConsul] if ok { gtr, ok := s.getters[config.SourceConsul] @@ -201,14 +192,11 @@ func processEnvField(f *config.Field, seedMap map[*config.Field]bool) error { } val, ok := os.LookupEnv(key) if !ok { - slog.Debug("env var did not exist", "key", key, "name", f.Name()) - - // if seedMap[f] { - // slog.Debug("env var did not exist", "key", key, "name", f.Name()) - // } else { - // slog.Debug("env var did not exist and no seed value provided", "key", key, "name", f.Name()) - // } - + if seedMap[f] { + slog.Debug("env var did not exist", "key", key, "name", f.Name()) + } else { + slog.Debug("env var did not exist and no seed value provided", "key", key, "name", f.Name()) + } return nil } @@ -220,3 +208,25 @@ func processEnvField(f *config.Field, seedMap map[*config.Field]bool) error { seedMap[f] = true return nil } + +func processFileField(f *config.Field, seedMap map[*config.Field]bool) error { + key, ok := f.Sources()[config.SourceFile] + if !ok { + return nil + } + + body, err := os.ReadFile(key) + if err != nil { + slog.Error("failed to read file", "file", key, "name", f.Name(), "err", err) + return nil + } + + err = f.Set(string(body), 0) + if err != nil { + return err + } + + slog.Debug("file based var applied", "value", f, "field", f.Name()) + seedMap[f] = true + return nil +} From 61ffbd5b682a10e0acd3e920f45dfef180f3605f Mon Sep 17 00:00:00 2001 From: Sotirios Mantziaris Date: Sun, 13 Oct 2024 14:06:20 +0300 Subject: [PATCH 3/7] Refactor seeding --- seed/seed.go | 102 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/seed/seed.go b/seed/seed.go index 3a27c19..45548b0 100644 --- a/seed/seed.go +++ b/seed/seed.go @@ -86,50 +86,14 @@ func (s *Seeder) Seed(cfg *config.Config) error { return err } - key, ok = ss[config.SourceConsul] - if ok { - gtr, ok := s.getters[config.SourceConsul] - if !ok { - return errors.New("consul getter required") - } - value, version, err := gtr.Get(key) - if err != nil { - slog.Error("failed to get consul", "key", key, "field", f.Name(), "err", err) - continue - } - if value == nil { - slog.Error("consul key does not exist", "key", key, "field", f.Name()) - continue - } - err = f.Set(*value, version) - if err != nil { - return err - } - slog.Debug("consul value applied", "value", f, "field", f.Name()) - seedMap[f] = true + err = s.processConsulField(f, seedMap) + if err != nil { + return err } - key, ok = ss[config.SourceRedis] - if ok { - gtr, ok := s.getters[config.SourceRedis] - if !ok { - return errors.New("redis getter required") - } - value, version, err := gtr.Get(key) - if err != nil { - slog.Error("failed to get redis", "key", key, "field", f.Name(), "err", err) - continue - } - if value == nil { - slog.Error("redis key does not exist", "key", key, "field", f.Name()) - continue - } - err = f.Set(*value, version) - if err != nil { - return err - } - slog.Debug("redis value applied", "value", f, "field", f.Name()) - seedMap[f] = true + err = s.processRedisField(f, seedMap) + if err != nil { + return err } } @@ -230,3 +194,57 @@ func processFileField(f *config.Field, seedMap map[*config.Field]bool) error { seedMap[f] = true return nil } + +func (s *Seeder) processConsulField(f *config.Field, seedMap map[*config.Field]bool) error { + key, ok := f.Sources()[config.SourceConsul] + if !ok { + return nil + } + gtr, ok := s.getters[config.SourceConsul] + if !ok { + return errors.New("consul getter required") + } + value, version, err := gtr.Get(key) + if err != nil { + slog.Error("failed to get consul", "key", key, "field", f.Name(), "err", err) + return nil + } + if value == nil { + slog.Error("consul key does not exist", "key", key, "field", f.Name()) + return nil + } + err = f.Set(*value, version) + if err != nil { + return err + } + slog.Debug("consul value applied", "value", f, "field", f.Name()) + seedMap[f] = true + return nil +} + +func (s *Seeder) processRedisField(f *config.Field, seedMap map[*config.Field]bool) error { + key, ok := f.Sources()[config.SourceRedis] + if !ok { + return nil + } + gtr, ok := s.getters[config.SourceRedis] + if !ok { + return errors.New("redis getter required") + } + value, version, err := gtr.Get(key) + if err != nil { + slog.Error("failed to get redis", "key", key, "field", f.Name(), "err", err) + return nil + } + if value == nil { + slog.Error("redis key does not exist", "key", key, "field", f.Name()) + return nil + } + err = f.Set(*value, version) + if err != nil { + return err + } + slog.Debug("redis value applied", "value", f, "field", f.Name()) + seedMap[f] = true + return nil +} From 2a6433a542025fc0671f4aacd2f018547ea67f03 Mon Sep 17 00:00:00 2001 From: Sotirios Mantziaris Date: Sun, 13 Oct 2024 14:23:54 +0300 Subject: [PATCH 4/7] Refactor seeding --- seed/seed.go | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/seed/seed.go b/seed/seed.go index 45548b0..0559c02 100644 --- a/seed/seed.go +++ b/seed/seed.go @@ -58,23 +58,18 @@ func (s *Seeder) Seed(cfg *config.Config) error { var flagInfos []*flagInfo for _, f := range cfg.Fields { seedMap[f] = false - ss := f.Sources() - val, ok := ss[config.SourceSeed] - if ok { - err := f.Set(val, 0) - if err != nil { - return err - } - slog.Debug("seed applied", "value", f, "name", f.Name()) - seedMap[f] = true + + err := processSeedField(f, seedMap) + if err != nil { + return err } - err := processEnvField(f, seedMap) + err = processEnvField(f, seedMap) if err != nil { return err } - key, ok := ss[config.SourceFlag] + key, ok := f.Sources()[config.SourceFlag] if ok { var val string flagSet.StringVar(&val, key, "", "") @@ -149,6 +144,20 @@ func (s *Seeder) Seed(cfg *config.Config) error { return nil } +func processSeedField(f *config.Field, seedMap map[*config.Field]bool) error { + val, ok := f.Sources()[config.SourceSeed] + if !ok { + return nil + } + err := f.Set(val, 0) + if err != nil { + return err + } + slog.Debug("seed applied", "value", f, "name", f.Name()) + seedMap[f] = true + return nil +} + func processEnvField(f *config.Field, seedMap map[*config.Field]bool) error { key, ok := f.Sources()[config.SourceEnv] if !ok { From 27263525132604d529000e3ccb8fbfec45d6ce8f Mon Sep 17 00:00:00 2001 From: Sotirios Mantziaris Date: Sun, 13 Oct 2024 15:24:19 +0300 Subject: [PATCH 5/7] Refactor seeding --- seed/seed.go | 109 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 44 deletions(-) diff --git a/seed/seed.go b/seed/seed.go index 0559c02..28cabce 100644 --- a/seed/seed.go +++ b/seed/seed.go @@ -46,15 +46,17 @@ func New(pp ...Param) *Seeder { return &Seeder{getters: gg} } +type flagInfo struct { + key string + field *config.Field + value *string +} + // Seed the provided config with values for their sources. func (s *Seeder) Seed(cfg *config.Config) error { seedMap := make(map[*config.Field]bool, len(cfg.Fields)) flagSet := flag.NewFlagSet("Harvester flags", flag.ContinueOnError) - type flagInfo struct { - key string - field *config.Field - value *string - } + var flagInfos []*flagInfo for _, f := range cfg.Fields { seedMap[f] = false @@ -69,11 +71,9 @@ func (s *Seeder) Seed(cfg *config.Config) error { return err } - key, ok := f.Sources()[config.SourceFlag] + fi, ok := processFlagField(f, flagSet) if ok { - var val string - flagSet.StringVar(&val, key, "", "") - flagInfos = append(flagInfos, &flagInfo{key, f, &val}) + flagInfos = append(flagInfos, fi) } err = processFileField(f, seedMap) @@ -92,41 +92,9 @@ func (s *Seeder) Seed(cfg *config.Config) error { } } - if len(flagInfos) > 0 { //nolint:nestif - if !flagSet.Parsed() { - // Set the flagSet output to something that will not be displayed, otherwise in case of an error - // it will display the usage, which we don't want. - flagSet.SetOutput(io.Discard) - - // Try to parse each flag independently so that if we encounter any unexpected flag (maybe used elsewhere), - // the parsing won't stop, and we make sure we try to parse every flag passed when running the command. - for _, arg := range os.Args[1:] { - if err := flagSet.Parse([]string{arg}); err != nil { - // Simply log errors that can happen, such as parsing unexpected flags. We want this to be silent, - // and we won't want to stop the execution. - slog.Error("could not parse flagSet", "err", err) - } - } - } - for _, flagInfo := range flagInfos { - hasFlag := false - flagSet.Visit(func(f *flag.Flag) { - if f.Name == flagInfo.key { - hasFlag = true - return - } - }) - if hasFlag && flagInfo.value != nil { - err := flagInfo.field.Set(*flagInfo.value, 0) - if err != nil { - return err - } - slog.Debug("flag value applied", "value", flagInfo.field, "field", flagInfo.field.Name()) - seedMap[flagInfo.field] = true - } else { - slog.Debug("flag var did not exist", "key", flagInfo.key, "field", flagInfo.field.Name()) - } - } + err := processFlags(flagInfos, flagSet, seedMap) + if err != nil { + return err } sb := strings.Builder{} @@ -257,3 +225,56 @@ func (s *Seeder) processRedisField(f *config.Field, seedMap map[*config.Field]bo seedMap[f] = true return nil } + +func processFlagField(f *config.Field, flagSet *flag.FlagSet) (*flagInfo, bool) { + key, ok := f.Sources()[config.SourceFlag] + if !ok { + return nil, false + } + var val string + flagSet.StringVar(&val, key, "", "") + return &flagInfo{key, f, &val}, true +} + +func processFlags(infos []*flagInfo, flagSet *flag.FlagSet, seedMap map[*config.Field]bool) error { + if len(infos) == 0 { + return nil + } + + if !flagSet.Parsed() { + // Set the flagSet output to something that will not be displayed, otherwise in case of an error + // it will display the usage, which we don't want. + flagSet.SetOutput(io.Discard) + + // Try to parse each flag independently so that if we encounter any unexpected flag (maybe used elsewhere), + // the parsing won't stop, and we make sure we try to parse every flag passed when running the command. + for _, arg := range os.Args[1:] { + if err := flagSet.Parse([]string{arg}); err != nil { + // Simply log errors that can happen, such as parsing unexpected flags. We want this to be silent, + // and we won't want to stop the execution. + slog.Error("could not parse flagSet", "err", err) + } + } + } + + for _, info := range infos { + hasFlag := false + flagSet.Visit(func(f *flag.Flag) { + if f.Name == info.key { + hasFlag = true + return + } + }) + if hasFlag && info.value != nil { + err := info.field.Set(*info.value, 0) + if err != nil { + return err + } + slog.Debug("flag value applied", "value", info.field, "field", info.field.Name()) + seedMap[info.field] = true + } else { + slog.Debug("flag var did not exist", "key", info.key, "field", info.field.Name()) + } + } + return nil +} From d2dfa1bb7ff87a2e22d4d3808d6f2290cbfabcd3 Mon Sep 17 00:00:00 2001 From: Sotirios Mantziaris Date: Sun, 13 Oct 2024 15:30:14 +0300 Subject: [PATCH 6/7] Refactor seeding --- seed/seed.go | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/seed/seed.go b/seed/seed.go index 28cabce..af43421 100644 --- a/seed/seed.go +++ b/seed/seed.go @@ -97,19 +97,7 @@ func (s *Seeder) Seed(cfg *config.Config) error { return err } - sb := strings.Builder{} - for f, seeded := range seedMap { - if !seeded { - _, err := sb.WriteString(fmt.Sprintf("field %s not seeded", f.Name())) - if err != nil { - return err - } - } - } - if sb.Len() > 0 { - return errors.New(sb.String()) - } - return nil + return evaluateSeedMap(seedMap) } func processSeedField(f *config.Field, seedMap map[*config.Field]bool) error { @@ -278,3 +266,19 @@ func processFlags(infos []*flagInfo, flagSet *flag.FlagSet, seedMap map[*config. } return nil } + +func evaluateSeedMap(seedMap map[*config.Field]bool) error { + sb := strings.Builder{} + for f, seeded := range seedMap { + if !seeded { + _, err := sb.WriteString(fmt.Sprintf("field %s not seeded", f.Name())) + if err != nil { + return err + } + } + } + if sb.Len() > 0 { + return errors.New(sb.String()) + } + return nil +} From 9366c077831e7b0161c1e04ac89b37d0ad747953 Mon Sep 17 00:00:00 2001 From: Sotirios Mantziaris Date: Sun, 13 Oct 2024 15:44:45 +0300 Subject: [PATCH 7/7] Refactor seeding --- seed/seed.go | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/seed/seed.go b/seed/seed.go index af43421..1c95fa0 100644 --- a/seed/seed.go +++ b/seed/seed.go @@ -46,6 +46,8 @@ func New(pp ...Param) *Seeder { return &Seeder{getters: gg} } +type fieldMap map[*config.Field]bool + type flagInfo struct { key string field *config.Field @@ -54,19 +56,19 @@ type flagInfo struct { // Seed the provided config with values for their sources. func (s *Seeder) Seed(cfg *config.Config) error { - seedMap := make(map[*config.Field]bool, len(cfg.Fields)) + seeded := make(fieldMap, len(cfg.Fields)) flagSet := flag.NewFlagSet("Harvester flags", flag.ContinueOnError) var flagInfos []*flagInfo for _, f := range cfg.Fields { - seedMap[f] = false + seeded[f] = false - err := processSeedField(f, seedMap) + err := processSeedField(f, seeded) if err != nil { return err } - err = processEnvField(f, seedMap) + err = processEnvField(f, seeded) if err != nil { return err } @@ -76,31 +78,31 @@ func (s *Seeder) Seed(cfg *config.Config) error { flagInfos = append(flagInfos, fi) } - err = processFileField(f, seedMap) + err = processFileField(f, seeded) if err != nil { return err } - err = s.processConsulField(f, seedMap) + err = s.processConsulField(f, seeded) if err != nil { return err } - err = s.processRedisField(f, seedMap) + err = s.processRedisField(f, seeded) if err != nil { return err } } - err := processFlags(flagInfos, flagSet, seedMap) + err := processFlags(flagInfos, flagSet, seeded) if err != nil { return err } - return evaluateSeedMap(seedMap) + return evaluateSeedMap(seeded) } -func processSeedField(f *config.Field, seedMap map[*config.Field]bool) error { +func processSeedField(f *config.Field, seedMap fieldMap) error { val, ok := f.Sources()[config.SourceSeed] if !ok { return nil @@ -114,7 +116,7 @@ func processSeedField(f *config.Field, seedMap map[*config.Field]bool) error { return nil } -func processEnvField(f *config.Field, seedMap map[*config.Field]bool) error { +func processEnvField(f *config.Field, seedMap fieldMap) error { key, ok := f.Sources()[config.SourceEnv] if !ok { return nil @@ -138,7 +140,7 @@ func processEnvField(f *config.Field, seedMap map[*config.Field]bool) error { return nil } -func processFileField(f *config.Field, seedMap map[*config.Field]bool) error { +func processFileField(f *config.Field, seedMap fieldMap) error { key, ok := f.Sources()[config.SourceFile] if !ok { return nil @@ -160,7 +162,7 @@ func processFileField(f *config.Field, seedMap map[*config.Field]bool) error { return nil } -func (s *Seeder) processConsulField(f *config.Field, seedMap map[*config.Field]bool) error { +func (s *Seeder) processConsulField(f *config.Field, seedMap fieldMap) error { key, ok := f.Sources()[config.SourceConsul] if !ok { return nil @@ -187,7 +189,7 @@ func (s *Seeder) processConsulField(f *config.Field, seedMap map[*config.Field]b return nil } -func (s *Seeder) processRedisField(f *config.Field, seedMap map[*config.Field]bool) error { +func (s *Seeder) processRedisField(f *config.Field, seedMap fieldMap) error { key, ok := f.Sources()[config.SourceRedis] if !ok { return nil @@ -224,7 +226,7 @@ func processFlagField(f *config.Field, flagSet *flag.FlagSet) (*flagInfo, bool) return &flagInfo{key, f, &val}, true } -func processFlags(infos []*flagInfo, flagSet *flag.FlagSet, seedMap map[*config.Field]bool) error { +func processFlags(infos []*flagInfo, flagSet *flag.FlagSet, seedMap fieldMap) error { if len(infos) == 0 { return nil } @@ -267,7 +269,7 @@ func processFlags(infos []*flagInfo, flagSet *flag.FlagSet, seedMap map[*config. return nil } -func evaluateSeedMap(seedMap map[*config.Field]bool) error { +func evaluateSeedMap(seedMap fieldMap) error { sb := strings.Builder{} for f, seeded := range seedMap { if !seeded {