From 7221051867bcad32d58d3d3418909662b611a716 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Tue, 18 Oct 2022 13:25:28 -0400 Subject: [PATCH] feat(config): support json config --- config/config.go | 68 +++++++++++++++++++++++++++++++----------------- go.mod | 1 + go.sum | 8 +++--- 3 files changed, 49 insertions(+), 28 deletions(-) diff --git a/config/config.go b/config/config.go index d64fa9fddf8c7feb87841f3ced52e23e756cbfb7..85e7ce831e16c5c3b075324a1ea6a9d0cc0e3ce3 100644 --- a/config/config.go +++ b/config/config.go @@ -2,6 +2,7 @@ package config import ( "bytes" + "encoding/json" "errors" "io/fs" "log" @@ -17,6 +18,7 @@ import ( "fmt" "os" + "github.com/charmbracelet/soft-serve/git" "github.com/charmbracelet/soft-serve/server/config" "github.com/go-git/go-billy/v5/memfs" ggit "github.com/go-git/go-git/v5" @@ -25,35 +27,40 @@ import ( "github.com/go-git/go-git/v5/storage/memory" ) +var ( + // ErrNoConfig is returned when no config file is found. + ErrNoConfig = errors.New("no config file found") +) + // Config is the Soft Serve configuration. type Config struct { - Name string `yaml:"name"` - Host string `yaml:"host"` - Port int `yaml:"port"` - AnonAccess string `yaml:"anon-access"` - AllowKeyless bool `yaml:"allow-keyless"` - Users []User `yaml:"users"` - Repos []MenuRepo `yaml:"repos"` - Source *RepoSource `yaml:"-"` - Cfg *config.Config `yaml:"-"` + Name string `yaml:"name" json:"name"` + Host string `yaml:"host" json:"host"` + Port int `yaml:"port" json:"port"` + AnonAccess string `yaml:"anon-access" json:"anon-access"` + AllowKeyless bool `yaml:"allow-keyless" json:"allow-keyless"` + Users []User `yaml:"users" json:"users"` + Repos []MenuRepo `yaml:"repos" json:"repos"` + Source *RepoSource `yaml:"-" json:"-"` + Cfg *config.Config `yaml:"-" json:"-"` mtx sync.Mutex } // User contains user-level configuration for a repository. type User struct { - Name string `yaml:"name"` - Admin bool `yaml:"admin"` - PublicKeys []string `yaml:"public-keys"` - CollabRepos []string `yaml:"collab-repos"` + Name string `yaml:"name" json:"name"` + Admin bool `yaml:"admin" json:"admin"` + PublicKeys []string `yaml:"public-keys" json:"public-keys"` + CollabRepos []string `yaml:"collab-repos" json:"collab-repos"` } // Repo contains repository configuration information. type MenuRepo struct { - Name string `yaml:"name"` - Repo string `yaml:"repo"` - Note string `yaml:"note"` - Private bool `yaml:"private"` - Readme string `yaml:"readme"` + Name string `yaml:"name" json:"name"` + Repo string `yaml:"repo" json:"repo"` + Note string `yaml:"note" json:"note"` + Private bool `yaml:"private" json:"private"` + Readme string `yaml:"readme" json:"readme"` } // NewConfig creates a new internal Config struct. @@ -133,13 +140,26 @@ func (cfg *Config) Reload() error { if err != nil { return err } - cs, _, err := cr.LatestFile("config.yaml") - if err != nil { - return err + cy, _, err := cr.LatestFile("config.yaml") + if err != nil && !errors.Is(err, git.ErrFileNotFound) { + return fmt.Errorf("error reading config.yaml: %w", err) } - err = yaml.Unmarshal([]byte(cs), cfg) - if err != nil { - return fmt.Errorf("bad yaml in config.yaml: %s", err) + cj, _, err := cr.LatestFile("config.json") + if err != nil && !errors.Is(err, git.ErrFileNotFound) { + return fmt.Errorf("error reading config.json: %w", err) + } + if cy != "" { + err = yaml.Unmarshal([]byte(cy), cfg) + if err != nil { + return fmt.Errorf("bad yaml in config.yaml: %s", err) + } + } else if cj != "" { + err = json.Unmarshal([]byte(cj), cfg) + if err != nil { + return fmt.Errorf("bad json in config.json: %s", err) + } + } else { + return ErrNoConfig } for _, r := range cfg.Source.AllRepos() { name := r.Name() diff --git a/go.mod b/go.mod index 16a819577062caf7f86bdb938cd90753b7fd68d9..f4ab77a24d34a12806c215216f1b0ad27069d510 100644 --- a/go.mod +++ b/go.mod @@ -66,6 +66,7 @@ require ( github.com/rivo/uniseg v0.2.0 // indirect github.com/sahilm/fuzzy v0.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/testify v1.8.0 // indirect github.com/xanzy/ssh-agent v0.3.1 // indirect github.com/yuin/goldmark v1.5.2 // indirect github.com/yuin/goldmark-emoji v1.0.1 // indirect diff --git a/go.sum b/go.sum index c5d88264ff84a0be95b5b940355f9176823a3247..9f5ee366f1f863eada3139090e31f96bc80d3e12 100644 --- a/go.sum +++ b/go.sum @@ -128,7 +128,6 @@ github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWV github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75 h1:Pijfgr7ZuvX7QIQiEwLdRVr3RoMG+i0SbBO1Qu+7yVk= github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo= -github.com/microcosm-cc/bluemonday v1.0.19 h1:OI7hoF5FY4pFz2VA//RN8TfM0YJ2dJcl4P4APrCWy6c= github.com/microcosm-cc/bluemonday v1.0.19/go.mod h1:QNzV2UbLK2/53oIIwTOyLUSABMkjZ4tqiyC1g/DyqxE= github.com/microcosm-cc/bluemonday v1.0.21 h1:dNH3e4PSyE4vNX+KlRGHT5KrSvjeUkoNPwEORjffHJg= github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= @@ -183,16 +182,18 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xanzy/ssh-agent v0.3.1 h1:AmzO1SSWxw73zxFZPRwaMN1MohDw8UyHnmuxyceTEGo= github.com/xanzy/ssh-agent v0.3.1/go.mod h1:QIE4lCeL7nkC25x+yA3LBIYfwCc1TFziCtG7cBAac6w= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.4 h1:zNWRjYUW32G9KirMXYHQHVNFkXvMI7LpgNW2AgYAoIs= github.com/yuin/goldmark v1.4.4/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg= github.com/yuin/goldmark v1.5.2 h1:ALmeCk/px5FSm1MAcFBAsVKZjDuMVj8Tm7FFIlMJnqU= github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -210,7 +211,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221002022538-bcab6841153b h1:6e93nYa3hNqAvLr0pD4PN1fFS+gKzp2zAXqrnTCstqU= golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=