diff options
author | satotake <doublequotation@gmail.com> | 2022-09-21 15:01:54 +0000 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2022-09-23 13:12:57 +0200 |
commit | 281554ee97eb243af097611aaf6bfec8940ad6d1 (patch) | |
tree | e7581707bac6026c78ecc77a23e378e2fc30e68e /hugofs/glob | |
parent | f3560aa0e170f8bbc1e5ab41f1e54bd819da5cc3 (diff) |
hugofs: Fix glob case-sensitivity bug
On Linux, `hugofs.Glob` does not hit any directories which includes
uppercase letters. (This does not happen on macOS.)
Since `resources.GetMatch/Match` uses `Glob`,
```
{{ resources.GetMatch "Foo/bar.css" }}
```
this does not match `assets/Foo/bar.css` .
On the other hand, you can get it with
```
{{ resources.Get "Foo/bar.css" }}
```
Diffstat (limited to 'hugofs/glob')
-rw-r--r-- | hugofs/glob/glob.go | 62 |
1 files changed, 44 insertions, 18 deletions
diff --git a/hugofs/glob/glob.go b/hugofs/glob/glob.go index 9e928ec32..87619802e 100644 --- a/hugofs/glob/glob.go +++ b/hugofs/glob/glob.go @@ -30,15 +30,13 @@ const filepathSeparator = string(os.PathSeparator) var ( isWindows = runtime.GOOS == "windows" defaultGlobCache = &globCache{ - isCaseSensitive: false, - isWindows: isWindows, - cache: make(map[string]globErr), + isWindows: isWindows, + cache: make(map[string]globErr), } filenamesGlobCache = &globCache{ - isCaseSensitive: false, // As long as the search strings are all lower case, this does not allocate. - isWindows: isWindows, - cache: make(map[string]globErr), + isWindows: isWindows, + cache: make(map[string]globErr), } ) @@ -49,8 +47,7 @@ type globErr struct { type globCache struct { // Config - isCaseSensitive bool - isWindows bool + isWindows bool // Cache sync.RWMutex @@ -72,19 +69,12 @@ func (gc *globCache) GetGlob(pattern string) (glob.Glob, error) { var err error pattern = filepath.ToSlash(pattern) - - if gc.isCaseSensitive { - g, err = glob.Compile(pattern, '/') - } else { - g, err = glob.Compile(strings.ToLower(pattern), '/') - - } + g, err = glob.Compile(strings.ToLower(pattern), '/') eg = globErr{ globDecorator{ - g: g, - isCaseSensitive: gc.isCaseSensitive, - isWindows: gc.isWindows}, + g: g, + isWindows: gc.isWindows}, err, } @@ -117,14 +107,50 @@ func (g globDecorator) Match(s string) bool { return g.g.Match(s) } +type globDecoratorDouble struct { + lowerCase glob.Glob + originalCase glob.Glob +} + +func (g globDecoratorDouble) Match(s string) bool { + return g.lowerCase.Match(s) || g.originalCase.Match(s) +} + func GetGlob(pattern string) (glob.Glob, error) { return defaultGlobCache.GetGlob(pattern) } +func GetFilenamesGlob(pattern string) (glob.Glob, error) { + lowered := strings.ToLower(pattern) + hasUpperCase := pattern != lowered + gLowered, err := filenamesGlobCache.GetGlob(lowered) + if err != nil { + return nil, err + } + + if !hasUpperCase { + return gLowered, nil + } + + gSensitive, err := filenamesGlobCache.GetGlob(pattern) + if err != nil { + return nil, err + } + return globDecoratorDouble{ + lowerCase: gLowered, + originalCase: gSensitive, + }, nil + +} + func NormalizePath(p string) string { return strings.Trim(path.Clean(filepath.ToSlash(strings.ToLower(p))), "/.") } +func NormalizePathCaseSensitive(p string) string { + return strings.Trim(path.Clean(filepath.ToSlash(p)), "/.") +} + // ResolveRootDir takes a normalized path on the form "assets/**.json" and // determines any root dir, i.e. any start path without any wildcards. func ResolveRootDir(p string) string { |