mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-11 20:03:58 +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:
103
cache/filecache/filecache_config.go
vendored
103
cache/filecache/filecache_config.go
vendored
@@ -11,6 +11,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package filecache provides a file based cache for Hugo.
|
||||
package filecache
|
||||
|
||||
import (
|
||||
@@ -21,11 +22,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gohugoio/hugo/common/maps"
|
||||
|
||||
"github.com/gohugoio/hugo/config"
|
||||
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
|
||||
"errors"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
@@ -33,98 +31,102 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
cachesConfigKey = "caches"
|
||||
|
||||
resourcesGenDir = ":resourceDir/_gen"
|
||||
cacheDirProject = ":cacheDir/:project"
|
||||
)
|
||||
|
||||
var defaultCacheConfig = Config{
|
||||
var defaultCacheConfig = FileCacheConfig{
|
||||
MaxAge: -1, // Never expire
|
||||
Dir: cacheDirProject,
|
||||
}
|
||||
|
||||
const (
|
||||
cacheKeyGetJSON = "getjson"
|
||||
cacheKeyGetCSV = "getcsv"
|
||||
cacheKeyImages = "images"
|
||||
cacheKeyAssets = "assets"
|
||||
cacheKeyModules = "modules"
|
||||
cacheKeyGetResource = "getresource"
|
||||
CacheKeyGetJSON = "getjson"
|
||||
CacheKeyGetCSV = "getcsv"
|
||||
CacheKeyImages = "images"
|
||||
CacheKeyAssets = "assets"
|
||||
CacheKeyModules = "modules"
|
||||
CacheKeyGetResource = "getresource"
|
||||
)
|
||||
|
||||
type Configs map[string]Config
|
||||
type Configs map[string]FileCacheConfig
|
||||
|
||||
// For internal use.
|
||||
func (c Configs) CacheDirModules() string {
|
||||
return c[cacheKeyModules].Dir
|
||||
return c[CacheKeyModules].DirCompiled
|
||||
}
|
||||
|
||||
var defaultCacheConfigs = Configs{
|
||||
cacheKeyModules: {
|
||||
CacheKeyModules: {
|
||||
MaxAge: -1,
|
||||
Dir: ":cacheDir/modules",
|
||||
},
|
||||
cacheKeyGetJSON: defaultCacheConfig,
|
||||
cacheKeyGetCSV: defaultCacheConfig,
|
||||
cacheKeyImages: {
|
||||
CacheKeyGetJSON: defaultCacheConfig,
|
||||
CacheKeyGetCSV: defaultCacheConfig,
|
||||
CacheKeyImages: {
|
||||
MaxAge: -1,
|
||||
Dir: resourcesGenDir,
|
||||
},
|
||||
cacheKeyAssets: {
|
||||
CacheKeyAssets: {
|
||||
MaxAge: -1,
|
||||
Dir: resourcesGenDir,
|
||||
},
|
||||
cacheKeyGetResource: Config{
|
||||
CacheKeyGetResource: FileCacheConfig{
|
||||
MaxAge: -1, // Never expire
|
||||
Dir: cacheDirProject,
|
||||
},
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
type FileCacheConfig struct {
|
||||
// Max age of cache entries in this cache. Any items older than this will
|
||||
// be removed and not returned from the cache.
|
||||
// a negative value means forever, 0 means cache is disabled.
|
||||
// A negative value means forever, 0 means cache is disabled.
|
||||
// Hugo is leninent with what types it accepts here, but we recommend using
|
||||
// a duration string, a sequence of decimal numbers, each with optional fraction and a unit suffix,
|
||||
// such as "300ms", "1.5h" or "2h45m".
|
||||
// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
MaxAge time.Duration
|
||||
|
||||
// The directory where files are stored.
|
||||
Dir string
|
||||
Dir string
|
||||
DirCompiled string `json:"-"`
|
||||
|
||||
// Will resources/_gen will get its own composite filesystem that
|
||||
// also checks any theme.
|
||||
isResourceDir bool
|
||||
IsResourceDir bool
|
||||
}
|
||||
|
||||
// GetJSONCache gets the file cache for getJSON.
|
||||
func (f Caches) GetJSONCache() *Cache {
|
||||
return f[cacheKeyGetJSON]
|
||||
return f[CacheKeyGetJSON]
|
||||
}
|
||||
|
||||
// GetCSVCache gets the file cache for getCSV.
|
||||
func (f Caches) GetCSVCache() *Cache {
|
||||
return f[cacheKeyGetCSV]
|
||||
return f[CacheKeyGetCSV]
|
||||
}
|
||||
|
||||
// ImageCache gets the file cache for processed images.
|
||||
func (f Caches) ImageCache() *Cache {
|
||||
return f[cacheKeyImages]
|
||||
return f[CacheKeyImages]
|
||||
}
|
||||
|
||||
// ModulesCache gets the file cache for Hugo Modules.
|
||||
func (f Caches) ModulesCache() *Cache {
|
||||
return f[cacheKeyModules]
|
||||
return f[CacheKeyModules]
|
||||
}
|
||||
|
||||
// AssetsCache gets the file cache for assets (processed resources, SCSS etc.).
|
||||
func (f Caches) AssetsCache() *Cache {
|
||||
return f[cacheKeyAssets]
|
||||
return f[CacheKeyAssets]
|
||||
}
|
||||
|
||||
// GetResourceCache gets the file cache for remote resources.
|
||||
func (f Caches) GetResourceCache() *Cache {
|
||||
return f[cacheKeyGetResource]
|
||||
return f[CacheKeyGetResource]
|
||||
}
|
||||
|
||||
func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
|
||||
func DecodeConfig(fs afero.Fs, bcfg config.BaseConfig, m map[string]any) (Configs, error) {
|
||||
c := make(Configs)
|
||||
valid := make(map[string]bool)
|
||||
// Add defaults
|
||||
@@ -133,8 +135,6 @@ func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
|
||||
valid[k] = true
|
||||
}
|
||||
|
||||
m := cfg.GetStringMap(cachesConfigKey)
|
||||
|
||||
_, isOsFs := fs.(*afero.OsFs)
|
||||
|
||||
for k, v := range m {
|
||||
@@ -170,9 +170,6 @@ func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
|
||||
c[name] = cc
|
||||
}
|
||||
|
||||
// This is a very old flag in Hugo, but we need to respect it.
|
||||
disabled := cfg.GetBool("ignoreCache")
|
||||
|
||||
for k, v := range c {
|
||||
dir := filepath.ToSlash(filepath.Clean(v.Dir))
|
||||
hadSlash := strings.HasPrefix(dir, "/")
|
||||
@@ -180,12 +177,12 @@ func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
|
||||
|
||||
for i, part := range parts {
|
||||
if strings.HasPrefix(part, ":") {
|
||||
resolved, isResource, err := resolveDirPlaceholder(fs, cfg, part)
|
||||
resolved, isResource, err := resolveDirPlaceholder(fs, bcfg, part)
|
||||
if err != nil {
|
||||
return c, err
|
||||
}
|
||||
if isResource {
|
||||
v.isResourceDir = true
|
||||
v.IsResourceDir = true
|
||||
}
|
||||
parts[i] = resolved
|
||||
}
|
||||
@@ -195,33 +192,29 @@ func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
|
||||
if hadSlash {
|
||||
dir = "/" + dir
|
||||
}
|
||||
v.Dir = filepath.Clean(filepath.FromSlash(dir))
|
||||
v.DirCompiled = filepath.Clean(filepath.FromSlash(dir))
|
||||
|
||||
if !v.isResourceDir {
|
||||
if isOsFs && !filepath.IsAbs(v.Dir) {
|
||||
return c, fmt.Errorf("%q must resolve to an absolute directory", v.Dir)
|
||||
if !v.IsResourceDir {
|
||||
if isOsFs && !filepath.IsAbs(v.DirCompiled) {
|
||||
return c, fmt.Errorf("%q must resolve to an absolute directory", v.DirCompiled)
|
||||
}
|
||||
|
||||
// Avoid cache in root, e.g. / (Unix) or c:\ (Windows)
|
||||
if len(strings.TrimPrefix(v.Dir, filepath.VolumeName(v.Dir))) == 1 {
|
||||
return c, fmt.Errorf("%q is a root folder and not allowed as cache dir", v.Dir)
|
||||
if len(strings.TrimPrefix(v.DirCompiled, filepath.VolumeName(v.DirCompiled))) == 1 {
|
||||
return c, fmt.Errorf("%q is a root folder and not allowed as cache dir", v.DirCompiled)
|
||||
}
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(v.Dir, "_gen") {
|
||||
if !strings.HasPrefix(v.DirCompiled, "_gen") {
|
||||
// We do cache eviction (file removes) and since the user can set
|
||||
// his/hers own cache directory, we really want to make sure
|
||||
// we do not delete any files that do not belong to this cache.
|
||||
// We do add the cache name as the root, but this is an extra safe
|
||||
// guard. We skip the files inside /resources/_gen/ because
|
||||
// that would be breaking.
|
||||
v.Dir = filepath.Join(v.Dir, filecacheRootDirname, k)
|
||||
v.DirCompiled = filepath.Join(v.DirCompiled, FilecacheRootDirname, k)
|
||||
} else {
|
||||
v.Dir = filepath.Join(v.Dir, k)
|
||||
}
|
||||
|
||||
if disabled {
|
||||
v.MaxAge = 0
|
||||
v.DirCompiled = filepath.Join(v.DirCompiled, k)
|
||||
}
|
||||
|
||||
c[k] = v
|
||||
@@ -231,17 +224,15 @@ func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) {
|
||||
}
|
||||
|
||||
// Resolves :resourceDir => /myproject/resources etc., :cacheDir => ...
|
||||
func resolveDirPlaceholder(fs afero.Fs, cfg config.Provider, placeholder string) (cacheDir string, isResource bool, err error) {
|
||||
workingDir := cfg.GetString("workingDir")
|
||||
func resolveDirPlaceholder(fs afero.Fs, bcfg config.BaseConfig, placeholder string) (cacheDir string, isResource bool, err error) {
|
||||
|
||||
switch strings.ToLower(placeholder) {
|
||||
case ":resourcedir":
|
||||
return "", true, nil
|
||||
case ":cachedir":
|
||||
d, err := helpers.GetCacheDir(fs, cfg)
|
||||
return d, false, err
|
||||
return bcfg.CacheDir, false, nil
|
||||
case ":project":
|
||||
return filepath.Base(workingDir), false, nil
|
||||
return filepath.Base(bcfg.WorkingDir), false, nil
|
||||
}
|
||||
|
||||
return "", false, fmt.Errorf("%q is not a valid placeholder (valid values are :cacheDir or :resourceDir)", placeholder)
|
||||
|
Reference in New Issue
Block a user