From 8a2461aa05895cc7828bc9619b50fa5dee5ed1f4 Mon Sep 17 00:00:00 2001 From: "Gabriel A. Giovanini" Date: Sat, 4 May 2024 23:16:38 +0200 Subject: feat: Add config parsing --- pkg/config/config.go | 84 +++++++++++++++++++++++++++++++++++++++++++++++ pkg/config/config_test.go | 56 +++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 pkg/config/config.go create mode 100644 pkg/config/config_test.go (limited to 'pkg') diff --git a/pkg/config/config.go b/pkg/config/config.go new file mode 100644 index 0000000..ba1614f --- /dev/null +++ b/pkg/config/config.go @@ -0,0 +1,84 @@ +package config + +import ( + "fmt" + "io" + "strconv" + + "git.sr.ht/~emersion/go-scfg" +) + +type ( + Scan struct { + Path string + Public bool + } + + Configuration struct { + Scan *Scan + } +) + +func Parse(r io.Reader) (*Configuration, error) { + block, err := scfg.Read(r) + if err != nil { + return nil, err + } + + config := defaultConfiguration() + + err = setScan(block, config.Scan) + if err != nil { + return nil, err + } + + return config, nil +} + +func defaultConfiguration() *Configuration { + return &Configuration{ + Scan: &Scan{ + Public: true, + Path: "", + }, + } +} + +func setScan(block scfg.Block, scan *Scan) error { + scanDir := block.Get("scan") + err := setString(scanDir, &scan.Path) + if err != nil { + return err + } + + public := scanDir.Children.Get("public") + return setBool(public, &scan.Public) +} + +func setBool(dir *scfg.Directive, field *bool) error { + + if dir != nil { + p1 := first(dir.Params) + v, err := strconv.ParseBool(p1) + if err != nil { + return fmt.Errorf("Error parsing bool param of %s: %w", dir.Name, err) + } + *field = v + } + return nil +} + +func setString(dir *scfg.Directive, field *string) error { + if dir != nil { + *field = first(dir.Params) + } + return nil +} + +func first[T any](v []T) T { + if len(v) == 0 { + var zero T + return zero + } + return v[0] +} diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go new file mode 100644 index 0000000..c8cd887 --- /dev/null +++ b/pkg/config/config_test.go @@ -0,0 +1,56 @@ +// go:build unit +package config + +import ( + "strings" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestConfig(t *testing.T) { + testCases := []struct { + name string + config string + expectedConfig *Configuration + }{ + { + name: "minimal scan", + config: `scan "/srv/git"`, + expectedConfig: &Configuration{ + Scan: &Scan{ + Public: true, + Path: "/srv/git", + }, + }, + }, + { + name: "complete scan", + config: `scan "/srv/git" { + public false +}`, + expectedConfig: &Configuration{ + Scan: &Scan{ + Public: false, + Path: "/srv/git", + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + r := strings.NewReader(tc.config) + config, err := Parse(r) + if err != nil { + t.Fatalf("Error parsing config %s", err.Error()) + } + + if diff := cmp.Diff(tc.expectedConfig, config); diff != "" { + t.Errorf("Wrong result given - wanted + got\n %s", diff) + } + + }) + + } +} -- cgit v1.2.3