summaryrefslogtreecommitdiffstats
path: root/hugolib
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-03-18 11:07:24 +0100
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-03-21 09:22:19 +0100
commite9c7b6205f94a7edac0e0df2cd18d1456cb26a06 (patch)
tree7c71d49c556f22497c3e0072ac25a3375f690074 /hugolib
parent3d1a6e109ce9b25fc2e9731098a82fb4c0abff68 (diff)
Allow themes to define output formats, media types and params
This allows a `config.toml` (or `yaml`, ´yml`, or `json`) in the theme to set: 1) `params` (but cannot override params in project. Will also get its own "namespace", i.e. `{{ .Site.Params.mytheme.my_param }}` will be the same as `{{ .Site.Params.my_param }}` providing that the main project does not define a param with that key. 2) `menu` -- but cannot redefine/add menus in the project. Must create its own menus with its own identifiers. 3) `languages` -- only `params` and `menu`. Same rules as above. 4) **new** `outputFormats` 5) **new** `mediaTypes` This should help with the "theme portability" issue and people having to copy and paste lots of setting into their projects. Fixes #4490
Diffstat (limited to 'hugolib')
-rw-r--r--hugolib/case_insensitive_test.go2
-rw-r--r--hugolib/config.go204
-rw-r--r--hugolib/config_test.go314
-rw-r--r--hugolib/page_bundler_test.go3
-rw-r--r--hugolib/site.go2
-rw-r--r--hugolib/testhelpers_test.go41
6 files changed, 536 insertions, 30 deletions
diff --git a/hugolib/case_insensitive_test.go b/hugolib/case_insensitive_test.go
index 680a701aa..52ef198a5 100644
--- a/hugolib/case_insensitive_test.go
+++ b/hugolib/case_insensitive_test.go
@@ -149,7 +149,7 @@ func TestCaseInsensitiveConfigurationVariations(t *testing.T) {
caseMixingTestsWriteCommonSources(t, mm)
- cfg, err := LoadConfig(ConfigSourceDescriptor{Fs: mm})
+ cfg, _, err := LoadConfig(ConfigSourceDescriptor{Fs: mm, Filename: "config.toml"})
require.NoError(t, err)
fs := hugofs.NewFrom(mm, cfg)
diff --git a/hugolib/config.go b/hugolib/config.go
index e47e65435..6eca1a969 100644
--- a/hugolib/config.go
+++ b/hugolib/config.go
@@ -16,6 +16,7 @@ package hugolib
import (
"errors"
"fmt"
+ "path/filepath"
"io"
"strings"
@@ -28,64 +29,91 @@ import (
// ConfigSourceDescriptor describes where to find the config (e.g. config.toml etc.).
type ConfigSourceDescriptor struct {
- Fs afero.Fs
- Src string
- Name string
+ Fs afero.Fs
+
+ // Full path to the config file to use, i.e. /my/project/config.toml
+ Filename string
+
+ // The path to the directory to look for configuration. Is used if Filename is not
+ // set.
+ Path string
+
+ // The project's working dir. Is used to look for additional theme config.
+ WorkingDir string
}
func (d ConfigSourceDescriptor) configFilenames() []string {
- return strings.Split(d.Name, ",")
+ return strings.Split(d.Filename, ",")
}
// LoadConfigDefault is a convenience method to load the default "config.toml" config.
func LoadConfigDefault(fs afero.Fs) (*viper.Viper, error) {
- return LoadConfig(ConfigSourceDescriptor{Fs: fs, Name: "config.toml"})
+ v, _, err := LoadConfig(ConfigSourceDescriptor{Fs: fs, Filename: "config.toml"})
+ return v, err
}
// LoadConfig loads Hugo configuration into a new Viper and then adds
// a set of defaults.
-func LoadConfig(d ConfigSourceDescriptor) (*viper.Viper, error) {
+func LoadConfig(d ConfigSourceDescriptor) (*viper.Viper, []string, error) {
+ var configFiles []string
+
fs := d.Fs
v := viper.New()
v.SetFs(fs)
- if d.Name == "" {
- d.Name = "config.toml"
- }
-
- if d.Src == "" {
- d.Src = "."
+ if d.Path == "" {
+ d.Path = "."
}
configFilenames := d.configFilenames()
v.AutomaticEnv()
v.SetEnvPrefix("hugo")
v.SetConfigFile(configFilenames[0])
- v.AddConfigPath(d.Src)
+ v.AddConfigPath(d.Path)
err := v.ReadInConfig()
if err != nil {
if _, ok := err.(viper.ConfigParseError); ok {
- return nil, err
+ return nil, configFiles, err
}
- return nil, fmt.Errorf("Unable to locate Config file. Perhaps you need to create a new site.\n Run `hugo help new` for details. (%s)\n", err)
+ return nil, configFiles, fmt.Errorf("Unable to locate Config file. Perhaps you need to create a new site.\n Run `hugo help new` for details. (%s)\n", err)
+ }
+
+ if cf := v.ConfigFileUsed(); cf != "" {
+ configFiles = append(configFiles, cf)
}
+
for _, configFile := range configFilenames[1:] {
var r io.Reader
var err error
if r, err = fs.Open(configFile); err != nil {
- return nil, fmt.Errorf("Unable to open Config file.\n (%s)\n", err)
+ return nil, configFiles, fmt.Errorf("Unable to open Config file.\n (%s)\n", err)
}
if err = v.MergeConfig(r); err != nil {
- return nil, fmt.Errorf("Unable to parse/merge Config file (%s).\n (%s)\n", configFile, err)
+ return nil, configFiles, fmt.Errorf("Unable to parse/merge Config file (%s).\n (%s)\n", configFile, err)
}
+ configFiles = append(configFiles, configFile)
}
if err := loadDefaultSettingsFor(v); err != nil {
- return v, err
+ return v, configFiles, err
}
- return v, nil
+ themeConfigFile, err := loadThemeConfig(d, v)
+ if err != nil {
+ return v, configFiles, err
+ }
+
+ if themeConfigFile != "" {
+ configFiles = append(configFiles, themeConfigFile)
+ }
+
+ if err := loadLanguageSettings(v, nil); err != nil {
+ return v, configFiles, err
+ }
+
+ return v, configFiles, nil
+
}
func loadLanguageSettings(cfg config.Provider, oldLangs helpers.Languages) error {
@@ -201,6 +229,142 @@ func loadLanguageSettings(cfg config.Provider, oldLangs helpers.Languages) error
return nil
}
+func loadThemeConfig(d ConfigSourceDescriptor, v1 *viper.Viper) (string, error) {
+
+ theme := v1.GetString("theme")
+ if theme == "" {
+ return "", nil
+ }
+
+ themesDir := helpers.AbsPathify(d.WorkingDir, v1.GetString("themesDir"))
+ configDir := filepath.Join(themesDir, theme)
+
+ var (
+ configPath string
+ exists bool
+ err error
+ )
+
+ // Viper supports more, but this is the sub-set supported by Hugo.
+ for _, configFormats := range []string{"toml", "yaml", "yml", "json"} {
+ configPath = filepath.Join(configDir, "config."+configFormats)
+ exists, err = helpers.Exists(configPath, d.Fs)
+ if err != nil {
+ return "", err
+ }
+ if exists {
+ break
+ }
+ }
+
+ if !exists {
+ // No theme config set.
+ return "", nil
+ }
+
+ v2 := viper.New()
+ v2.SetFs(d.Fs)
+ v2.AutomaticEnv()
+ v2.SetEnvPrefix("hugo")
+ v2.SetConfigFile(configPath)
+
+ err = v2.ReadInConfig()
+ if err != nil {
+ return "", err
+ }
+
+ const (
+ paramsKey = "params"
+ languagesKey = "languages"
+ menuKey = "menu"
+ )
+
+ for _, key := range []string{paramsKey, "outputformats", "mediatypes"} {
+ mergeStringMapKeepLeft("", key, v1, v2)
+ }
+
+ themeLower := strings.ToLower(theme)
+ themeParamsNamespace := paramsKey + "." + themeLower
+
+ // Set namespaced params
+ if v2.IsSet(paramsKey) && !v1.IsSet(themeParamsNamespace) {
+ // Set it in the default store to make sure it gets in the same or
+ // behind the others.
+ v1.SetDefault(themeParamsNamespace, v2.Get(paramsKey))
+ }
+
+ // Only add params and new menu entries, we do not add language definitions.
+ if v1.IsSet(languagesKey) && v2.IsSet(languagesKey) {
+ v1Langs := v1.GetStringMap(languagesKey)
+ for k, _ := range v1Langs {
+ langParamsKey := languagesKey + "." + k + "." + paramsKey
+ mergeStringMapKeepLeft(paramsKey, langParamsKey, v1, v2)
+ }
+ v2Langs := v2.GetStringMap(languagesKey)
+ for k, _ := range v2Langs {
+ if k == "" {
+ continue
+ }
+ langParamsKey := languagesKey + "." + k + "." + paramsKey
+ langParamsThemeNamespace := langParamsKey + "." + themeLower
+ // Set namespaced params
+ if v2.IsSet(langParamsKey) && !v1.IsSet(langParamsThemeNamespace) {
+ v1.SetDefault(langParamsThemeNamespace, v2.Get(langParamsKey))
+ }
+
+ langMenuKey := languagesKey + "." + k + "." + menuKey
+ if v2.IsSet(langMenuKey) {
+ // Only add if not in the main config.
+ v2menus := v2.GetStringMap(langMenuKey)
+ for k, v := range v2menus {
+ menuEntry := menuKey + "." + k
+ menuLangEntry := langMenuKey + "." + k
+ if !v1.IsSet(menuEntry) && !v1.IsSet(menuLangEntry) {
+ v1.Set(menuLangEntry, v)
+ }
+ }
+ }
+ }
+ }
+
+ // Add menu definitions from theme not found in project
+ if v2.IsSet("menu") {
+ v2menus := v2.GetStringMap(menuKey)
+ for k, v := range v2menus {
+ menuEntry := menuKey + "." + k
+ if !v1.IsSet(menuEntry) {
+ v1.SetDefault(menuEntry, v)
+ }
+ }
+ }
+
+ return v2.ConfigFileUsed(), nil
+
+}
+
+func mergeStringMapKeepLeft(rootKey, key string, v1, v2 *viper.Viper) {
+ if !v2.IsSet(key) {
+ return
+ }
+
+ if !v1.IsSet(key) && !(rootKey != "" && rootKey != key && v1.IsSet(rootKey)) {
+ v1.Set(key, v2.Get(key))
+ return
+ }
+
+ m1 := v1.GetStringMap(key)
+ m2 := v2.GetStringMap(key)
+
+ for k, v := range m2 {
+ if _, found := m1[k]; !found {
+ if rootKey != "" && v1.IsSet(rootKey+"."+k) {
+ continue
+ }
+ m1[k] = v
+ }
+ }
+}
+
func loadDefaultSettingsFor(v *viper.Viper) error {
c, err := helpers.NewContentSpec(v)
@@ -281,5 +445,5 @@ lastmod = ["lastmod" ,":fileModTime", ":default"]
}
- return loadLanguageSettings(v, nil)
+ return nil
}
diff --git a/hugolib/config_test.go b/hugolib/config_test.go
index ec543d93d..441bcf541 100644
--- a/hugolib/config_test.go
+++ b/hugolib/config_test.go
@@ -17,13 +17,15 @@ import (
"testing"
"github.com/spf13/afero"
- "github.com/stretchr/testify/assert"
+ "github.com/spf13/viper"
"github.com/stretchr/testify/require"
)
func TestLoadConfig(t *testing.T) {
t.Parallel()
+ assert := require.New(t)
+
// Add a random config variable for testing.
// side = page in Norwegian.
configContent := `
@@ -34,16 +36,19 @@ func TestLoadConfig(t *testing.T) {
writeToFs(t, mm, "hugo.toml", configContent)
- cfg, err := LoadConfig(ConfigSourceDescriptor{Fs: mm, Name: "hugo.toml"})
+ cfg, _, err := LoadConfig(ConfigSourceDescriptor{Fs: mm, Filename: "hugo.toml"})
require.NoError(t, err)
- assert.Equal(t, "side", cfg.GetString("paginatePath"))
+ assert.Equal("side", cfg.GetString("paginatePath"))
// default
- assert.Equal(t, "layouts", cfg.GetString("layoutDir"))
+ assert.Equal("layouts", cfg.GetString("layoutDir"))
}
+
func TestLoadMultiConfig(t *testing.T) {
t.Parallel()
+ assert := require.New(t)
+
// Add a random config variable for testing.
// side = page in Norwegian.
configContentBase := `
@@ -59,9 +64,304 @@ func TestLoadMultiConfig(t *testing.T) {
writeToFs(t, mm, "override.toml", configContentSub)
- cfg, err := LoadConfig(ConfigSourceDescriptor{Fs: mm, Name: "base.toml,override.toml"})
+ cfg, _, err := LoadConfig(ConfigSourceDescriptor{Fs: mm, Filename: "base.toml,override.toml"})
require.NoError(t, err)
- assert.Equal(t, "top", cfg.GetString("paginatePath"))
- assert.Equal(t, "same", cfg.GetString("DontChange"))
+ assert.Equal("top", cfg.GetString("paginatePath"))
+ assert.Equal("same", cfg.GetString("DontChange"))
+}
+
+func TestLoadConfigFromTheme(t *testing.T) {
+ t.Parallel()
+
+ assert := require.New(t)
+
+ mainConfigBasic := `
+theme = "test-theme"
+baseURL = "https://example.com/"
+
+`
+ mainConfig := `
+theme = "test-theme"
+baseURL = "https://example.com/"
+
+[frontmatter]
+date = ["date","publishDate"]
+
+[params]
+p1 = "p1 main"
+p2 = "p2 main"
+top = "top"
+
+[mediaTypes]
+[mediaTypes."text/m1"]
+suffix = "m1main"
+
+[outputFormats.o1]
+mediaType = "text/m1"
+baseName = "o1main"
+
+[languages]
+[languages.en]
+languageName = "English"
+[languages.en.params]
+pl1 = "p1-en-main"
+[languages.nb]
+languageName = "Norsk"
+[languages.nb.params]
+pl1 = "p1-nb-main"
+
+[[menu.main]]
+name = "menu-main-main"
+
+[[menu.top]]
+name = "menu-top-main"
+
+`
+
+ themeConfig := `
+baseURL = "http://bep.is/"
+
+# Can not be set in theme.
+[frontmatter]
+expiryDate = ["date"]
+
+[params]
+p1 = "p1 theme"
+p2 = "p2 theme"
+p3 = "p3 theme"
+
+[mediaTypes]
+[mediaTypes."text/m1"]
+suffix = "m1theme"
+[mediaTypes."text/m2"]
+suffix = "m2theme"
+
+[outputFormats.o1]
+mediaType = "text/m1"
+baseName = "o1theme"
+[outputFormats.o2]
+mediaType = "text/m2"
+baseName = "o2theme"
+
+[languages]
+[languages.en]
+languageName = "English2"
+[languages.en.params]
+pl1 = "p1-en-theme"
+pl2 = "p2-en-theme"
+[[languages.en.menu.main]]
+name = "menu-lang-en-main"
+[[languages.en.menu.theme]]
+name = "menu-lang-en-theme"
+[languages.nb]
+languageName = "Norsk2"
+[languages.nb.params]
+pl1 = "p1-nb-theme"
+pl2 = "p2-nb-theme"
+top = "top-nb-theme"
+[[languages.nb.menu.main]]
+name = "menu-lang-nb-main"
+[[languages.nb.menu.theme]]
+name = "menu-lang-nb-theme"
+[[languages.nb.menu.top]]
+name = "menu-lang-nb-top"
+
+[[menu.main]]
+name = "menu-main-theme"
+
+[[menu.thememenu]]
+name = "menu-theme"
+
+`
+
+ b := newTestSitesBuilder(t)
+ b.WithConfigFile("toml", mainConfig).WithThemeConfigFile("toml", themeConfig)
+ b.CreateSites().Build(BuildCfg{})
+
+ got := b.Cfg.(*viper.Viper).AllSettings()
+
+ b.AssertObject(`
+map[string]interface {}{
+ "p1": "p1 main",
+ "p2": "p2 main",
+ "p3": "p3 theme",
+ "test-theme": map[string]interface {}{
+ "p1": "p1 theme",
+ "p2": "p2 theme",
+ "p3": "p3 theme",
+ },
+ "top": "top",
+}`, got["params"])
+
+ b.AssertObject(`
+map[string]interface {}{
+ "date": []interface {}{
+ "date",
+ "publishDate",
+ },
+}`, got["frontmatter"])
+
+ b.AssertObject(`
+map[string]interface {}{
+ "text/m1": map[string]interface {}{
+ "suffix": "m1main",
+ },
+ "text/m2": map[string]interface {}{
+ "suffix": "m2theme",
+ },
+}`, got["mediatypes"])
+
+ b.AssertObject(`
+map[string]interface {}{
+ "o1": map[string]interface {}{
+ "basename": "o1main",
+ "mediatype": Type{
+ MainType: "text",
+ SubType: "m1",
+ Suffix: "m1main",
+ Delimiter: ".",
+ },
+ },
+ "o2": map[string]interface {}{
+ "basename": "o2theme",
+ "mediatype": Type{
+ MainType: "text",
+ SubType: "m2",
+ Suffix: "m2theme",
+ Delimiter: ".",
+ },
+ },
+}`, got["outputformats"])
+
+ b.AssertObject(`map[string]interface {}{
+ "en": map[string]interface {}{
+ "languagename": "English",
+ "menu": map[string]interface {}{
+ "theme": []interface {}{
+ map[string]interface {}{
+ "name": "menu-lang-en-theme",
+ },
+ },
+ },
+ "params": map[string]interface {}{
+ "pl1": "p1-en-main",
+ "pl2": "p2-en-theme",
+ "test-theme": map[string]interface {}{
+ "pl1": "p1-en-theme",
+ "pl2": "p2-en-theme",
+ },
+ },
+ },
+ "nb": map[string]interface {}{
+ "languagename": "Norsk",
+ "menu": map[string]interface {}{
+ "theme": []interface {}{
+ map[string]interface {}{
+ "name": "menu-lang-nb-theme",
+ },
+ },
+ },
+ "params": map[string]interface {}{
+ "pl1": "p1-nb-main",
+ "pl2": "p2-nb-theme",
+ "test-theme": map[string]interface {}{
+ "pl1": "p1-nb-theme",
+ "pl2": "p2-nb-theme",
+ "top": "top-nb-theme",
+ },
+ },
+ },
+}
+`, got["languages"])
+
+ b.AssertObject(`
+map[string]interface {}{
+ "main": []interface {}{
+ map[string]interface {}{
+ "name": "menu-main-main",
+ },
+ },
+ "thememenu": []interface {}{
+ map[string]interface {}{
+ "name": "menu-theme",
+ },
+ },
+ "top": []interface {}{
+ map[string]interface {}{
+ "name": "menu-top-main",
+ },
+ },
+}
+`, got["menu"])
+
+ assert.Equal("https://example.com/", got["baseurl"])
+
+ if true {
+ return
+ }
+ // Test variants with only values from theme
+ b = newTestSitesBuilder(t)
+ b.WithConfigFile("toml", mainConfigBasic).WithThemeConfigFile("toml", themeConfig)
+ b.CreateSites().Build(BuildCfg{})
+
+ got = b.Cfg.(*viper.Viper).AllSettings()
+
+ b.AssertObject(`map[string]interface {}{
+ "p1": "p1 theme",
+ "p2": "p2 theme",
+ "p3": "p3 theme",
+ "test-theme": map[string]interface {}{
+ "p1": "p1 theme",
+ "p2": "p2 theme",
+ "p3": "p3 theme",
+ },
+}`, got["params"])
+
+ assert.Nil(got["languages"])
+ b.AssertObject(`
+map[string]interface {}{
+ "text/m1": map[string]interface {}{
+ "suffix": "m1theme",
+ },
+ "text/m2": map[string]interface {}{
+ "suffix": "m2theme",
+ },
+}`, got["mediatypes"])
+
+ b.AssertObject(`
+map[string]interface {}{
+ "o1": map[string]interface {}{
+ "basename": "o1theme",
+ "mediatype": Type{
+ MainType: "text",
+ SubType: "m1",
+ Suffix: "m1theme",
+ Delimiter: ".",
+ },
+ },
+ "o2": map[string]interface {}{
+ "basename": "o2theme",
+ "mediatype": Type{
+ MainType: "text",
+ SubType: "m2",
+ Suffix: "m2theme",
+ Delimiter: ".",
+ },
+ },
+}`, got["outputformats"])
+ b.AssertObject(`
+map[string]interface {}{
+ "main": []interface {}{
+ map[string]interface {}{
+ "name": "menu-main-theme",
+ },
+ },
+ "thememenu": []interface {}{
+ map[string]interface {}{
+ "name": "menu-theme",
+ },
+ },
+}`, got["menu"])
+
}
diff --git a/hugolib/page_bundler_test.go b/hugolib/page_bundler_test.go
index bf79d2f86..572d84bcd 100644
--- a/hugolib/page_bundler_test.go
+++ b/hugolib/page_bundler_test.go
@@ -200,6 +200,7 @@ func TestPageBundlerSiteMultilingual(t *testing.T) {
cfg.Set("uglyURLs", ugly)
assert.NoError(loadDefaultSettingsFor(cfg))
+ assert.NoError(loadLanguageSettings(cfg, nil))
sites, err := NewHugoSites(deps.DepsCfg{Fs: fs, Cfg: cfg})
assert.NoError(err)
assert.Equal(2, len(sites.Sites))
@@ -264,6 +265,8 @@ func TestMultilingualDisableDefaultLanguage(t *testing.T) {
cfg.Set("disableLanguages", []string{"en"})
err := loadDefaultSettingsFor(cfg)
+ assert.NoError(err)
+ err = loadLanguageSettings(cfg, nil)
assert.Error(err)
assert.Contains(err.Error(), "cannot disable default language")
}
diff --git a/hugolib/site.go b/hugolib/site.go
index 2e8898bd6..0ffe153e9 100644
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -296,6 +296,7 @@ func NewSite(cfg deps.DepsCfg) (*Site, error) {
// NewSiteDefaultLang creates a new site in the default language.
// The site will have a template system loaded and ready to use.
// Note: This is mainly used in single site tests.
+// TODO(bep) test refactor -- remove
func NewSiteDefaultLang(withTemplate ...func(templ tpl.TemplateHandler) error) (*Site, error) {
v := viper.New()
if err := loadDefaultSettingsFor(v); err != nil {
@@ -307,6 +308,7 @@ func NewSiteDefaultLang(withTemplate ...func(templ tpl.TemplateHandler) error) (
// NewEnglishSite creates a new site in English language.
// The site will have a template system loaded and ready to use.
// Note: This is mainly used in single site tests.
+// TODO(bep) test refactor -- remove
func NewEnglishSite(withTemplate ...func(templ tpl.TemplateHandler) error) (*Site, error) {
v := viper.New()
if err := loadDefaultSettingsFor(v); err != nil {
diff --git a/hugolib/testhelpers_test.go b/hugolib/testhelpers_test.go
index ab23b343c..1f22e428d 100644
--- a/hugolib/testhelpers_test.go
+++ b/hugolib/testhelpers_test.go
@@ -10,6 +10,8 @@ import (
"strings"
"text/template"
+ "github.com/sanity-io/litter"
+
jww "github.com/spf13/jwalterweatherman"
"github.com/gohugoio/hugo/config"
@@ -37,11 +39,15 @@ type sitesBuilder struct {
Fs *hugofs.Fs
T testing.TB
+ dumper litter.Options
+
// Aka the Hugo server mode.
running bool
H *HugoSites
+ theme string
+
// Default toml
configFormat string
@@ -63,7 +69,13 @@ func newTestSitesBuilder(t testing.TB) *sitesBuilder {
v := viper.New()
fs := hugofs.NewMem(v)
- return &sitesBuilder{T: t, Fs: fs, configFormat: "toml"}
+ litterOptions := litter.Options{
+ HidePrivateFields: true,
+ StripPackageNames: true,
+ Separator: " ",
+ }
+
+ return &sitesBuilder{T: t, Fs: fs, configFormat: "toml", dumper: litterOptions}
}
func (s *sitesBuilder) Running() *sitesBuilder {
@@ -97,6 +109,15 @@ func (s *sitesBuilder) WithConfigFile(format, conf string) *sitesBuilder {
return s
}
+func (s *sitesBuilder) WithThemeConfigFile(format, conf string) *sitesBuilder {
+ if s.theme == "" {
+ s.theme = "test-theme"
+ }
+ filename := filepath.Join("themes", s.theme, "config."+format)
+ writeSource(s.T, s.Fs, filename, conf)
+ return s
+}
+
func (s *sitesBuilder) WithSimpleConfigFile() *sitesBuilder {
var config = `
baseURL = "http://example.com/"
@@ -229,10 +250,15 @@ func (s *sitesBuilder) CreateSites() *sitesBuilder {
s.writeFilePairs("i18n", s.i18nFilePairsAdded)
if s.Cfg == nil {
- cfg, err := LoadConfig(ConfigSourceDescriptor{Fs: s.Fs.Source, Name: "config." + s.configFormat})
+ cfg, configFiles, err := LoadConfig(ConfigSourceDescriptor{Fs: s.Fs.Source, Filename: "config." + s.configFormat})
if err != nil {
s.Fatalf("Failed to load config: %s", err)
}
+ expectedConfigs := 1
+ if s.theme != "" {
+ expectedConfigs = 2
+ }
+ require.Equal(s.T, expectedConfigs, len(configFiles), fmt.Sprintf("Configs: %v", configFiles))
s.Cfg = cfg
}
@@ -345,6 +371,17 @@ func (s *sitesBuilder) AssertFileContent(filename string, matches ...string) {
}
}
+func (s *sitesBuilder) AssertObject(expected string, object interface{}) {
+ got := s.dumper.Sdump(object)
+ expected = strings.TrimSpace(expected)
+
+ if expected != got {
+ fmt.Println(got)
+ diff := helpers.DiffStrings(expected, got)
+ s.Fatalf("diff:\n%s\nexpected\n%s\ngot\n%s", diff, expected, got)
+ }
+}
+
func (s *sitesBuilder) AssertFileContentRe(filename string, matches ...string) {
content := readDestination(s.T, s.Fs, filename)
for _, match := range matches {