Skip to content

Commit

Permalink
Misc config loading fixes
Browse files Browse the repository at this point in the history
The main motivation behind this is simplicity and correctnes, but the new small config library is also faster:

```
BenchmarkDefaultConfigProvider/Viper-16         	  252418	      4546 ns/op	    2720 B/op	      30 allocs/op
BenchmarkDefaultConfigProvider/Custom-16        	  450756	      2651 ns/op	    1008 B/op	       6 allocs/op
```

Fixes #8633
Fixes #8618
Fixes #8630
Updates #8591
Closes #6680
Closes #5192
  • Loading branch information
bep committed Jun 14, 2021
1 parent a886dd5 commit d392893
Show file tree
Hide file tree
Showing 107 changed files with 2,115 additions and 1,016 deletions.
7 changes: 6 additions & 1 deletion cache/filecache/filecache_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"strings"
"time"

"github.com/gohugoio/hugo/common/maps"

"github.com/gohugoio/hugo/config"

"github.com/gohugoio/hugo/helpers"
Expand Down Expand Up @@ -123,6 +125,9 @@ func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
_, isOsFs := fs.(*afero.OsFs)

for k, v := range m {
if _, ok := v.(maps.Params); !ok {
continue
}
cc := defaultCacheConfig

dc := &mapstructure.DecoderConfig{
Expand All @@ -137,7 +142,7 @@ func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
}

if err := decoder.Decode(v); err != nil {
return nil, err

This comment was marked as off-topic.

Copy link
@champpp96

champpp96 Aug 10, 2021

145

return nil, errors.Wrap(err, "failed to decode filecache config")
}

if cc.Dir == "" {
Expand Down
5 changes: 2 additions & 3 deletions cache/filecache/filecache_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
"github.com/gohugoio/hugo/config"

qt "github.com/frankban/quicktest"
"github.com/spf13/viper"
)

func TestDecodeConfig(t *testing.T) {
Expand Down Expand Up @@ -178,8 +177,8 @@ dir = "/"
c.Assert(err, qt.Not(qt.IsNil))
}

func newTestConfig() *viper.Viper {
cfg := viper.New()
func newTestConfig() config.Provider {
cfg := config.New()
cfg.Set("workingDir", filepath.FromSlash("/my/cool/hugoproject"))
cfg.Set("contentDir", "content")
cfg.Set("dataDir", "data")
Expand Down
2 changes: 0 additions & 2 deletions commands/commandeer.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,5 @@ func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error {
}
config.Set("cacheDir", cacheDir)

cfg.Logger.Infoln("Using config file:", config.ConfigFileUsed())

return nil
}
9 changes: 5 additions & 4 deletions commands/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"path/filepath"
"testing"

"github.com/gohugoio/hugo/config"

"github.com/gohugoio/hugo/htesting"

"github.com/spf13/afero"
Expand All @@ -29,7 +31,6 @@ import (
"github.com/gohugoio/hugo/common/types"

"github.com/spf13/cobra"
"github.com/spf13/viper"

qt "github.com/frankban/quicktest"
)
Expand Down Expand Up @@ -166,7 +167,7 @@ func TestFlags(t *testing.T) {
name: "ignoreVendor as bool",
args: []string{"server", "--ignoreVendor"},
check: func(c *qt.C, cmd *serverCmd) {
cfg := viper.New()
cfg := config.New()
cmd.flagsToConfig(cfg)
c.Assert(cfg.Get("ignoreVendor"), qt.Equals, true)
},
Expand All @@ -176,7 +177,7 @@ func TestFlags(t *testing.T) {
name: "ignoreVendorPaths",
args: []string{"server", "--ignoreVendorPaths=github.com/**"},
check: func(c *qt.C, cmd *serverCmd) {
cfg := viper.New()
cfg := config.New()
cmd.flagsToConfig(cfg)
c.Assert(cfg.Get("ignoreVendorPaths"), qt.Equals, "github.com/**")
},
Expand Down Expand Up @@ -216,7 +217,7 @@ func TestFlags(t *testing.T) {
c.Assert(sc.serverPort, qt.Equals, 1366)
c.Assert(sc.environment, qt.Equals, "testing")

cfg := viper.New()
cfg := config.New()
sc.flagsToConfig(cfg)
c.Assert(cfg.GetString("publishDir"), qt.Equals, "/tmp/mydestination")
c.Assert(cfg.GetString("contentDir"), qt.Equals, "mycontent")
Expand Down
5 changes: 3 additions & 2 deletions commands/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ import (
"sort"
"strings"

"github.com/gohugoio/hugo/common/maps"

"github.com/gohugoio/hugo/parser"
"github.com/gohugoio/hugo/parser/metadecoders"

"github.com/gohugoio/hugo/modules"

"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var _ cmder = (*configCmd)(nil)
Expand Down Expand Up @@ -81,7 +82,7 @@ func (c *configCmd) printConfig(cmd *cobra.Command, args []string) error {
return err
}

allSettings := cfg.Cfg.(*viper.Viper).AllSettings()
allSettings := cfg.Cfg.Get("").(maps.Params)

// We need to clean up this, but we store objects in the config that
// isn't really interesting to the end user, so filter these.
Expand Down
4 changes: 2 additions & 2 deletions commands/new_site.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"path/filepath"
"strings"

"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/parser/metadecoders"

_errors "github.com/pkg/errors"
Expand All @@ -29,7 +30,6 @@ import (
"github.com/gohugoio/hugo/parser"
"github.com/spf13/cobra"
jww "github.com/spf13/jwalterweatherman"
"github.com/spf13/viper"
)

var _ cmder = (*newSiteCmd)(nil)
Expand Down Expand Up @@ -123,7 +123,7 @@ func (n *newSiteCmd) newSite(cmd *cobra.Command, args []string) error {

forceNew, _ := cmd.Flags().GetBool("force")

return n.doNewSite(hugofs.NewDefault(viper.New()), createpath, forceNew)
return n.doNewSite(hugofs.NewDefault(config.New()), createpath, forceNew)
}

func createConfig(fs *hugofs.Fs, inpath string, kind string) (err error) {
Expand Down
4 changes: 2 additions & 2 deletions commands/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ import (
"testing"
"time"

"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/helpers"

qt "github.com/frankban/quicktest"
"github.com/spf13/viper"
)

func TestServer(t *testing.T) {
Expand Down Expand Up @@ -101,7 +101,7 @@ func TestFixURL(t *testing.T) {
t.Run(test.TestName, func(t *testing.T) {
b := newCommandsBuilder()
s := b.newServerCmd()
v := viper.New()
v := config.New()
baseURL := test.CLIBaseURL
v.Set("baseURL", test.CfgBaseURL)
s.serverAppend = test.AppendPort
Expand Down
77 changes: 44 additions & 33 deletions common/maps/maps.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,53 +18,65 @@ import (
"strings"

"github.com/gobwas/glob"

"github.com/spf13/cast"
)

// ToLower makes all the keys in the given map lower cased and will do so
// recursively.
// Notes:
// * This will modify the map given.
// * Any nested map[interface{}]interface{} will be converted to Params.
func ToLower(m Params) {
for k, v := range m {
var retyped bool
switch v.(type) {
case map[interface{}]interface{}:
var p Params = cast.ToStringMap(v)
v = p
ToLower(p)
retyped = true
case map[string]interface{}:
var p Params = v.(map[string]interface{})
v = p
ToLower(p)
retyped = true
// ToStringMapE converts in to map[string]interface{}.
func ToStringMapE(in interface{}) (map[string]interface{}, error) {
switch vv := in.(type) {
case Params:
return vv, nil
case map[string]string:
var m = map[string]interface{}{}
for k, v := range vv {
m[k] = v
}
return m, nil

lKey := strings.ToLower(k)
if retyped || k != lKey {
delete(m, k)
m[lKey] = v
}
default:
return cast.ToStringMapE(in)
}
}

func ToStringMapE(in interface{}) (map[string]interface{}, error) {
switch in.(type) {
case Params:
return in.(Params), nil
default:
return cast.ToStringMapE(in)
// ToParamsAndPrepare converts in to Params and prepares it for use.
// See PrepareParams.
func ToParamsAndPrepare(in interface{}) (Params, bool) {
m, err := ToStringMapE(in)
if err != nil {
return nil, false
}
PrepareParams(m)
return m, true
}

// ToStringMap converts in to map[string]interface{}.
func ToStringMap(in interface{}) map[string]interface{} {
m, _ := ToStringMapE(in)
return m
}

// ToStringMapStringE converts in to map[string]string.
func ToStringMapStringE(in interface{}) (map[string]string, error) {
m, err := ToStringMapE(in)
if err != nil {
return nil, err
}
return cast.ToStringMapStringE(m)
}

// ToStringMapString converts in to map[string]string.
func ToStringMapString(in interface{}) map[string]string {
m, _ := ToStringMapStringE(in)
return m
}

// ToStringMapBool converts in to bool.
func ToStringMapBool(in interface{}) map[string]bool {
m, _ := ToStringMapE(in)
return cast.ToStringMapBool(m)
}

// ToSliceStringMap converts in to []map[string]interface{}.
func ToSliceStringMap(in interface{}) ([]map[string]interface{}, error) {
switch v := in.(type) {
case []map[string]interface{}:
Expand Down Expand Up @@ -127,9 +139,8 @@ func (KeyRenamer) keyPath(k1, k2 string) string {
k1, k2 = strings.ToLower(k1), strings.ToLower(k2)
if k1 == "" {
return k2
} else {
return k1 + "/" + k2
}
return k1 + "/" + k2
}

func (r KeyRenamer) renamePath(parentKeyPath string, m map[string]interface{}) {
Expand Down
2 changes: 1 addition & 1 deletion common/maps/maps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func TestToLower(t *testing.T) {
for i, test := range tests {
t.Run(fmt.Sprint(i), func(t *testing.T) {
// ToLower modifies input.
ToLower(test.input)
PrepareParams(test.input)
if !reflect.DeepEqual(test.expected, test.input) {
t.Errorf("[%d] Expected\n%#v, got\n%#v\n", i, test.expected, test.input)
}
Expand Down
Loading

0 comments on commit d392893

Please sign in to comment.