mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-19 21:21:39 +02:00
Create a struct with all of Hugo's config options
Primary motivation is documentation, but it will also hopefully simplify the code. Also, * Lower case the default output format names; this is in line with the custom ones (map keys) and how it's treated all the places. This avoids doing `stringds.EqualFold` everywhere. Closes #10896 Closes #10620
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Copyright 2015 The Hugo Authors. All rights reserved.
|
||||
// Copyright 2023 The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -11,13 +11,18 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package source
|
||||
package source_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/gohugoio/hugo/config"
|
||||
"github.com/gohugoio/hugo/config/testconfig"
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
"github.com/gohugoio/hugo/source"
|
||||
"github.com/spf13/afero"
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
"github.com/gohugoio/hugo/hugofs"
|
||||
@@ -45,22 +50,30 @@ func TestIgnoreDotFilesAndDirectories(t *testing.T) {
|
||||
{"foobar/foo.md", true, []string{"\\.md$", "\\.boo$"}},
|
||||
{"foobar/foo.html", false, []string{"\\.md$", "\\.boo$"}},
|
||||
{"foobar/foo.md", true, []string{"foo.md$"}},
|
||||
{"foobar/foo.md", true, []string{"*", "\\.md$", "\\.boo$"}},
|
||||
{"foobar/foo.md", true, []string{".*", "\\.md$", "\\.boo$"}},
|
||||
{"foobar/.#content.md", true, []string{"/\\.#"}},
|
||||
{".#foobar.md", true, []string{"^\\.#"}},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
v := newTestConfig()
|
||||
v.Set("ignoreFiles", test.ignoreFilesRegexpes)
|
||||
fs := hugofs.NewMem(v)
|
||||
ps, err := helpers.NewPathSpec(fs, v, nil)
|
||||
c.Assert(err, qt.IsNil)
|
||||
test := test
|
||||
c.Run(fmt.Sprintf("[%d] %s", i, test.path), func(c *qt.C) {
|
||||
c.Parallel()
|
||||
v := config.New()
|
||||
v.Set("ignoreFiles", test.ignoreFilesRegexpes)
|
||||
v.Set("publishDir", "public")
|
||||
afs := afero.NewMemMapFs()
|
||||
conf := testconfig.GetTestConfig(afs, v)
|
||||
fs := hugofs.NewFromOld(afs, v)
|
||||
ps, err := helpers.NewPathSpec(fs, conf, nil)
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
s := NewSourceSpec(ps, nil, fs.Source)
|
||||
s := source.NewSourceSpec(ps, nil, fs.Source)
|
||||
|
||||
if ignored := s.IgnoreFile(filepath.FromSlash(test.path)); test.ignore != ignored {
|
||||
t.Errorf("[%d] File not ignored", i)
|
||||
}
|
||||
})
|
||||
|
||||
if ignored := s.IgnoreFile(filepath.FromSlash(test.path)); test.ignore != ignored {
|
||||
t.Errorf("[%d] File not ignored", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -96,6 +96,7 @@ type FileWithoutOverlap interface {
|
||||
// Hugo content files being one of them, considered to be unique.
|
||||
UniqueID() string
|
||||
|
||||
// For internal use only.
|
||||
FileInfo() hugofs.FileMetaInfo
|
||||
}
|
||||
|
||||
@@ -182,6 +183,7 @@ func (fi *FileInfo) UniqueID() string {
|
||||
}
|
||||
|
||||
// FileInfo returns a file's underlying os.FileInfo.
|
||||
// For internal use only.
|
||||
func (fi *FileInfo) FileInfo() hugofs.FileMetaInfo { return fi.fi }
|
||||
|
||||
func (fi *FileInfo) String() string { return fi.BaseFileName() }
|
||||
|
@@ -11,7 +11,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package source
|
||||
package source_test
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"testing"
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
"github.com/gohugoio/hugo/source"
|
||||
)
|
||||
|
||||
func TestFileInfo(t *testing.T) {
|
||||
@@ -29,9 +30,9 @@ func TestFileInfo(t *testing.T) {
|
||||
for _, this := range []struct {
|
||||
base string
|
||||
filename string
|
||||
assert func(f *FileInfo)
|
||||
assert func(f *source.FileInfo)
|
||||
}{
|
||||
{filepath.FromSlash("/a/"), filepath.FromSlash("/a/b/page.md"), func(f *FileInfo) {
|
||||
{filepath.FromSlash("/a/"), filepath.FromSlash("/a/b/page.md"), func(f *source.FileInfo) {
|
||||
c.Assert(f.Filename(), qt.Equals, filepath.FromSlash("/a/b/page.md"))
|
||||
c.Assert(f.Dir(), qt.Equals, filepath.FromSlash("b/"))
|
||||
c.Assert(f.Path(), qt.Equals, filepath.FromSlash("b/page.md"))
|
||||
@@ -39,10 +40,10 @@ func TestFileInfo(t *testing.T) {
|
||||
c.Assert(f.TranslationBaseName(), qt.Equals, filepath.FromSlash("page"))
|
||||
c.Assert(f.BaseFileName(), qt.Equals, filepath.FromSlash("page"))
|
||||
}},
|
||||
{filepath.FromSlash("/a/"), filepath.FromSlash("/a/b/c/d/page.md"), func(f *FileInfo) {
|
||||
{filepath.FromSlash("/a/"), filepath.FromSlash("/a/b/c/d/page.md"), func(f *source.FileInfo) {
|
||||
c.Assert(f.Section(), qt.Equals, "b")
|
||||
}},
|
||||
{filepath.FromSlash("/a/"), filepath.FromSlash("/a/b/page.en.MD"), func(f *FileInfo) {
|
||||
{filepath.FromSlash("/a/"), filepath.FromSlash("/a/b/page.en.MD"), func(f *source.FileInfo) {
|
||||
c.Assert(f.Section(), qt.Equals, "b")
|
||||
c.Assert(f.Path(), qt.Equals, filepath.FromSlash("b/page.en.MD"))
|
||||
c.Assert(f.TranslationBaseName(), qt.Equals, filepath.FromSlash("page"))
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright 2015 The Hugo Authors. All rights reserved.
|
||||
// Copyright 2023 The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -11,7 +11,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package source
|
||||
package source_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -19,17 +19,14 @@ import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/gohugoio/hugo/config"
|
||||
|
||||
"github.com/gohugoio/hugo/modules"
|
||||
|
||||
"github.com/gohugoio/hugo/langs"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
"github.com/gohugoio/hugo/config"
|
||||
"github.com/gohugoio/hugo/config/testconfig"
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
"github.com/gohugoio/hugo/hugofs"
|
||||
"github.com/gohugoio/hugo/source"
|
||||
)
|
||||
|
||||
func TestEmptySourceFilesystem(t *testing.T) {
|
||||
@@ -60,13 +57,11 @@ func TestUnicodeNorm(t *testing.T) {
|
||||
}
|
||||
|
||||
ss := newTestSourceSpec()
|
||||
fi := hugofs.NewFileMetaInfo(nil, hugofs.NewFileMeta())
|
||||
|
||||
for i, path := range paths {
|
||||
base := fmt.Sprintf("base%d", i)
|
||||
c.Assert(afero.WriteFile(ss.Fs.Source, filepath.Join(base, path.NFD), []byte("some data"), 0777), qt.IsNil)
|
||||
src := ss.NewFilesystem(base)
|
||||
_ = src.add(path.NFD, fi)
|
||||
files, err := src.Files()
|
||||
c.Assert(err, qt.IsNil)
|
||||
f := files[0]
|
||||
@@ -76,27 +71,14 @@ func TestUnicodeNorm(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func newTestConfig() config.Provider {
|
||||
v := config.NewWithTestDefaults()
|
||||
_, err := langs.LoadLanguageSettings(v, nil)
|
||||
func newTestSourceSpec() *source.SourceSpec {
|
||||
v := config.New()
|
||||
afs := hugofs.NewBaseFileDecorator(afero.NewMemMapFs())
|
||||
conf := testconfig.GetTestConfig(afs, v)
|
||||
fs := hugofs.NewFrom(afs, conf.BaseConfig())
|
||||
ps, err := helpers.NewPathSpec(fs, conf, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mod, err := modules.CreateProjectModule(v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
v.Set("allModules", modules.Modules{mod})
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func newTestSourceSpec() *SourceSpec {
|
||||
v := newTestConfig()
|
||||
fs := hugofs.NewFrom(hugofs.NewBaseFileDecorator(afero.NewMemMapFs()), v)
|
||||
ps, err := helpers.NewPathSpec(fs, v, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return NewSourceSpec(ps, nil, fs.Source)
|
||||
return source.NewSourceSpec(ps, nil, fs.Source)
|
||||
}
|
||||
|
@@ -17,16 +17,13 @@ package source
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
|
||||
"github.com/gohugoio/hugo/hugofs/glob"
|
||||
|
||||
"github.com/gohugoio/hugo/langs"
|
||||
"github.com/spf13/afero"
|
||||
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
// SourceSpec abstracts language-specific file creation.
|
||||
@@ -37,56 +34,23 @@ type SourceSpec struct {
|
||||
SourceFs afero.Fs
|
||||
|
||||
shouldInclude func(filename string) bool
|
||||
|
||||
Languages map[string]any
|
||||
DefaultContentLanguage string
|
||||
DisabledLanguages map[string]bool
|
||||
}
|
||||
|
||||
// NewSourceSpec initializes SourceSpec using languages the given filesystem and PathSpec.
|
||||
func NewSourceSpec(ps *helpers.PathSpec, inclusionFilter *glob.FilenameFilter, fs afero.Fs) *SourceSpec {
|
||||
cfg := ps.Cfg
|
||||
defaultLang := cfg.GetString("defaultContentLanguage")
|
||||
languages := cfg.GetStringMap("languages")
|
||||
|
||||
disabledLangsSet := make(map[string]bool)
|
||||
|
||||
for _, disabledLang := range cfg.GetStringSlice("disableLanguages") {
|
||||
disabledLangsSet[disabledLang] = true
|
||||
}
|
||||
|
||||
if len(languages) == 0 {
|
||||
l := langs.NewDefaultLanguage(cfg)
|
||||
languages[l.Lang] = l
|
||||
defaultLang = l.Lang
|
||||
}
|
||||
|
||||
ignoreFiles := cast.ToStringSlice(cfg.Get("ignoreFiles"))
|
||||
var regexps []*regexp.Regexp
|
||||
if len(ignoreFiles) > 0 {
|
||||
for _, ignorePattern := range ignoreFiles {
|
||||
re, err := regexp.Compile(ignorePattern)
|
||||
if err != nil {
|
||||
helpers.DistinctErrorLog.Printf("Invalid regexp %q in ignoreFiles: %s", ignorePattern, err)
|
||||
} else {
|
||||
regexps = append(regexps, re)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
shouldInclude := func(filename string) bool {
|
||||
if !inclusionFilter.Match(filename, false) {
|
||||
return false
|
||||
}
|
||||
for _, r := range regexps {
|
||||
if r.MatchString(filename) {
|
||||
return false
|
||||
}
|
||||
if ps.Cfg.IgnoreFile(filename) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return &SourceSpec{shouldInclude: shouldInclude, PathSpec: ps, SourceFs: fs, Languages: languages, DefaultContentLanguage: defaultLang, DisabledLanguages: disabledLangsSet}
|
||||
return &SourceSpec{shouldInclude: shouldInclude, PathSpec: ps, SourceFs: fs}
|
||||
}
|
||||
|
||||
// IgnoreFile returns whether a given file should be ignored.
|
||||
|
Reference in New Issue
Block a user