Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions common/hstrings/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,16 @@ func GetOrCompileRegexp(pattern string) (re *regexp.Regexp, err error) {
return reCache.getOrCompileRegexp(pattern)
}

// HasAnyPrefix checks if the string s has any of the prefixes given.
func HasAnyPrefix(s string, prefixes ...string) bool {
for _, p := range prefixes {
if strings.HasPrefix(s, p) {
return true
}
}
return false
}

// InSlice checks if a string is an element of a slice of strings
// and returns a boolean value.
func InSlice(arr []string, el string) bool {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ require (
github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69
github.com/JohannesKaufmann/html-to-markdown/v2 v2.4.0
github.com/alecthomas/chroma/v2 v2.20.0
github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c
github.com/aws/aws-sdk-go-v2 v1.40.0
github.com/aws/aws-sdk-go-v2/service/cloudfront v1.57.0
github.com/bep/clocks v0.5.0
Expand Down Expand Up @@ -38,6 +37,7 @@ require (
github.com/gobwas/glob v0.2.3
github.com/goccy/go-yaml v1.18.0
github.com/gohugoio/go-i18n/v2 v2.1.3-0.20251018145728-cfcc22d823c6
github.com/gohugoio/go-radix v1.2.0
github.com/gohugoio/hashstructure v0.6.0
github.com/gohugoio/httpcache v0.8.0
github.com/gohugoio/hugo-goldmark-extensions/extras v0.5.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,6 @@ github.com/alecthomas/chroma/v2 v2.20.0 h1:sfIHpxPyR07/Oylvmcai3X/exDlE8+FA820NT
github.com/alecthomas/chroma/v2 v2.20.0/go.mod h1:e7tViK0xh/Nf4BYHl00ycY6rV7b8iXBksI9E359yNmA=
github.com/alecthomas/repr v0.5.1 h1:E3G4t2QbHTSNpPKBgMTln5KLkZHLOcU7r37J4pXBuIg=
github.com/alecthomas/repr v0.5.1/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c h1:651/eoCRnQ7YtSjAnSzRucrJz+3iGEFt+ysraELS81M=
github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE=
github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
github.com/aws/aws-sdk-go-v2 v1.40.0 h1:/WMUA0kjhZExjOQN2z3oLALDREea1A7TobfuiBrKlwc=
Expand Down Expand Up @@ -276,6 +274,8 @@ github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/gohugoio/go-i18n/v2 v2.1.3-0.20251018145728-cfcc22d823c6 h1:pxlAea9eRwuAnt/zKbGqlFO2ZszpIe24YpOVLf+N+4I=
github.com/gohugoio/go-i18n/v2 v2.1.3-0.20251018145728-cfcc22d823c6/go.mod h1:m5hu1im5Qc7LDycVLvee6MPobJiRLBYHklypFJR0/aE=
github.com/gohugoio/go-radix v1.2.0 h1:D5GTk8jIoeXirBSc2P4E4NdHKDrenk9k9N0ctU5Yrhg=
github.com/gohugoio/go-radix v1.2.0/go.mod h1:k6vDa0ebpbpgtzSj9lPGJcA4AZwJ9xUNObUy2vczPFM=
github.com/gohugoio/hashstructure v0.6.0 h1:7wMB/2CfXoThFYhdWRGv3u3rUM761Cq29CxUW+NltUg=
github.com/gohugoio/hashstructure v0.6.0/go.mod h1:lapVLk9XidheHG1IQ4ZSbyYrXcaILU1ZEP/+vno5rBQ=
github.com/gohugoio/httpcache v0.8.0 h1:hNdsmGSELztetYCsPVgjA960zSa4dfEqqF/SficorCU=
Expand Down
83 changes: 37 additions & 46 deletions hugofs/rootmapping_fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
"github.com/gohugoio/hugo/hugofs/files"
"github.com/gohugoio/hugo/hugofs/hglob"

radix "github.com/armon/go-radix"
radix "github.com/gohugoio/go-radix"
"github.com/spf13/afero"
)

Expand All @@ -42,17 +42,12 @@ var _ ReverseLookupProvder = (*RootMappingFs)(nil)
// root mappings with some optional metadata about the root.
// Note that From represents a virtual root that maps to the actual filename in To.
func NewRootMappingFs(fs afero.Fs, rms ...*RootMapping) (*RootMappingFs, error) {
rootMapToReal := radix.New()
realMapToRoot := radix.New()
rootMapToReal := radix.New[[]*RootMapping]()
realMapToRoot := radix.New[[]*RootMapping]()
id := fmt.Sprintf("rfs-%d", rootMappingFsCounter.Add(1))

addMapping := func(key string, rm *RootMapping, to *radix.Tree) {
var mappings []*RootMapping
v, found := to.Get(key)
if found {
// There may be more than one language pointing to the same root.
mappings = v.([]*RootMapping)
}
addMapping := func(key string, rm *RootMapping, to *radix.Tree[[]*RootMapping]) {
mappings, _ := to.Get(key)
mappings = append(mappings, rm)
to.Insert(key, mappings)
}
Expand Down Expand Up @@ -232,8 +227,8 @@ var _ FilesystemUnwrapper = (*RootMappingFs)(nil)
type RootMappingFs struct {
id string
afero.Fs
rootMapToReal *radix.Tree
realMapToRoot *radix.Tree
rootMapToReal *radix.Tree[[]*RootMapping]
realMapToRoot *radix.Tree[[]*RootMapping]
}

var rootMappingFsCounter atomic.Int32
Expand Down Expand Up @@ -279,9 +274,8 @@ func (fs *RootMappingFs) UnwrapFilesystem() afero.Fs {

// Filter creates a copy of this filesystem with only mappings matching a filter.
func (fs RootMappingFs) Filter(f func(m *RootMapping) bool) *RootMappingFs {
rootMapToReal := radix.New()
fs.rootMapToReal.Walk(func(b string, v any) bool {
rms := v.([]*RootMapping)
rootMapToReal := radix.New[[]*RootMapping]()
var walkFn radix.WalkFn[[]*RootMapping] = func(b string, rms []*RootMapping) (radix.WalkFlag, []*RootMapping, error) {
var nrms []*RootMapping
for _, rm := range rms {
if f(rm) {
Expand All @@ -291,8 +285,9 @@ func (fs RootMappingFs) Filter(f func(m *RootMapping) bool) *RootMappingFs {
if len(nrms) != 0 {
rootMapToReal.Insert(b, nrms)
}
return false
})
return radix.WalkContinue, nil, nil
}
fs.rootMapToReal.Walk(walkFn)

fs.rootMapToReal = rootMapToReal

Expand Down Expand Up @@ -385,21 +380,18 @@ func (fs *RootMappingFs) ReverseLookupComponent(component, filename string) ([]C

func (fs *RootMappingFs) hasPrefix(prefix string) bool {
hasPrefix := false
fs.rootMapToReal.WalkPrefix(prefix, func(b string, v any) bool {
var walkFn radix.WalkFn[[]*RootMapping] = func(b string, rms []*RootMapping) (radix.WalkFlag, []*RootMapping, error) {
hasPrefix = true
return true
})
return radix.WalkStop, nil, nil
}
fs.rootMapToReal.WalkPrefix(prefix, walkFn)

return hasPrefix
}

func (fs *RootMappingFs) getRoot(key string) []*RootMapping {
v, found := fs.rootMapToReal.Get(key)
if !found {
return nil
}

return v.([]*RootMapping)
v, _ := fs.rootMapToReal.Get(key)
return v
}

func (fs *RootMappingFs) getRoots(key string) (string, []*RootMapping) {
Expand All @@ -418,7 +410,7 @@ func (fs *RootMappingFs) getRoots(key string) (string, []*RootMapping) {
break
}

for _, rm := range vv.([]*RootMapping) {
for _, rm := range vv {
if !seen[rm] {
seen[rm] = true
roots = append(roots, rm)
Expand All @@ -439,34 +431,33 @@ func (fs *RootMappingFs) getRoots(key string) (string, []*RootMapping) {

func (fs *RootMappingFs) getRootsReverse(key string) (string, []*RootMapping) {
tree := fs.realMapToRoot
s, v, found := tree.LongestPrefix(key)
if !found {
return "", nil
}
return s, v.([]*RootMapping)
s, v, _ := tree.LongestPrefix(key)
return s, v
}

func (fs *RootMappingFs) getRootsWithPrefix(prefix string) []*RootMapping {
var roots []*RootMapping
fs.rootMapToReal.WalkPrefix(prefix, func(b string, v any) bool {
roots = append(roots, v.([]*RootMapping)...)
return false
})
var walkFn radix.WalkFn[[]*RootMapping] = func(b string, v []*RootMapping) (radix.WalkFlag, []*RootMapping, error) {
roots = append(roots, v...)
return radix.WalkContinue, nil, nil
}
fs.rootMapToReal.WalkPrefix(prefix, walkFn)

return roots
}

func (fs *RootMappingFs) getAncestors(prefix string) []keyRootMappings {
var roots []keyRootMappings
fs.rootMapToReal.WalkPath(prefix, func(s string, v any) bool {
var walkFn radix.WalkFn[[]*RootMapping] = func(s string, v []*RootMapping) (radix.WalkFlag, []*RootMapping, error) {
if strings.HasPrefix(prefix, s+filepathSeparator) {
roots = append(roots, keyRootMappings{
key: s,
roots: v.([]*RootMapping),
roots: v,
})
}
return false
})
return radix.WalkContinue, nil, nil
}
fs.rootMapToReal.WalkPath(prefix, walkFn)

return roots
}
Expand Down Expand Up @@ -593,7 +584,7 @@ func (rfs *RootMappingFs) collectDirEntries(prefix string) ([]iofs.DirEntry, err

// Next add any file mounts inside the given directory.
prefixInside := prefix + filepathSeparator
rfs.rootMapToReal.WalkPrefix(prefixInside, func(s string, v any) bool {
var walkFn radix.WalkFn[[]*RootMapping] = func(s string, rms []*RootMapping) (radix.WalkFlag, []*RootMapping, error) {
if (strings.Count(s, filepathSeparator) - level) != 1 {
// This directory is not part of the current, but we
// need to include the first name part to make it
Expand All @@ -603,7 +594,7 @@ func (rfs *RootMappingFs) collectDirEntries(prefix string) ([]iofs.DirEntry, err
name := parts[0]

if seen[name] {
return false
return radix.WalkContinue, nil, nil
}
seen[name] = true
opener := func() (afero.File, error) {
Expand All @@ -613,10 +604,9 @@ func (rfs *RootMappingFs) collectDirEntries(prefix string) ([]iofs.DirEntry, err
fi := newDirNameOnlyFileInfo(name, nil, opener)
fis = append(fis, fi)

return false
return radix.WalkContinue, nil, nil
}

rms := v.([]*RootMapping)
for _, rm := range rms {
name := filepath.Base(rm.From)
if seen[name] {
Expand All @@ -630,8 +620,9 @@ func (rfs *RootMappingFs) collectDirEntries(prefix string) ([]iofs.DirEntry, err
fis = append(fis, fi)
}

return false
})
return radix.WalkContinue, nil, nil
}
rfs.rootMapToReal.WalkPrefix(prefixInside, walkFn)

// Finally add any ancestor dirs with files in this directory.
ancestors := rfs.getAncestors(prefix)
Expand Down
4 changes: 2 additions & 2 deletions hugolib/content_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,8 @@ func (m *pageMap) AddFi(fi hugofs.FileMetaInfo, buildConfig *BuildCfg) (pageSour
key := pi.Base()
tree := m.treeResources

commit := tree.Lock(true)
defer commit()
tree.Lock(true)
defer tree.Unlock(true)

if pi.IsContent() {
pm, err := h.newPageMetaSourceFromFile(fi)
Expand Down
Loading
Loading