From b64617fe4f90da030bcf4a9c5a4913393ce96b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Mon, 12 Aug 2019 16:43:37 +0200 Subject: Add resources.Match and resources.GetMatch Fix #6190 --- hugofs/glob/glob.go | 81 ++++++++++++++++++++++++++++++++++++++++++++++++ hugofs/glob/glob_test.go | 63 +++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 hugofs/glob/glob.go create mode 100644 hugofs/glob/glob_test.go (limited to 'hugofs/glob') diff --git a/hugofs/glob/glob.go b/hugofs/glob/glob.go new file mode 100644 index 000000000..18d8d44cb --- /dev/null +++ b/hugofs/glob/glob.go @@ -0,0 +1,81 @@ +// Copyright 2019 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. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package glob + +import ( + "path" + "path/filepath" + "strings" + "sync" + + "github.com/gobwas/glob" + "github.com/gobwas/glob/syntax" +) + +var ( + globCache = make(map[string]glob.Glob) + globMu sync.RWMutex +) + +func GetGlob(pattern string) (glob.Glob, error) { + var g glob.Glob + + globMu.RLock() + g, found := globCache[pattern] + globMu.RUnlock() + if !found { + var err error + g, err = glob.Compile(strings.ToLower(pattern), '/') + if err != nil { + return nil, err + } + + globMu.Lock() + globCache[pattern] = g + globMu.Unlock() + } + + return g, nil + +} + +func NormalizePath(p string) string { + return strings.Trim(filepath.ToSlash(strings.ToLower(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 { + parts := strings.Split(path.Dir(p), "/") + var roots []string + for _, part := range parts { + isSpecial := false + for i := 0; i < len(part); i++ { + if syntax.Special(part[i]) { + isSpecial = true + break + } + } + if isSpecial { + break + } + roots = append(roots, part) + } + + if len(roots) == 0 { + return "" + } + + return strings.Join(roots, "/") +} diff --git a/hugofs/glob/glob_test.go b/hugofs/glob/glob_test.go new file mode 100644 index 000000000..2b1c74107 --- /dev/null +++ b/hugofs/glob/glob_test.go @@ -0,0 +1,63 @@ +// Copyright 2019 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. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package glob + +import ( + "path/filepath" + "testing" + + qt "github.com/frankban/quicktest" +) + +func TestResolveRootDir(t *testing.T) { + c := qt.New(t) + + for _, test := range []struct { + in string + expect string + }{ + {"data/foo.json", "data"}, + {"a/b/**/foo.json", "a/b"}, + {"dat?a/foo.json", ""}, + {"a/b[a-c]/foo.json", "a"}, + } { + + c.Assert(ResolveRootDir(test.in), qt.Equals, test.expect) + } +} + +func TestNormalizePath(t *testing.T) { + c := qt.New(t) + + for _, test := range []struct { + in string + expect string + }{ + {filepath.FromSlash("data/FOO.json"), "data/foo.json"}, + {filepath.FromSlash("/data/FOO.json"), "data/foo.json"}, + {filepath.FromSlash("./FOO.json"), "foo.json"}, + {"//", ""}, + } { + + c.Assert(NormalizePath(test.in), qt.Equals, test.expect) + } +} + +func TestGetGlob(t *testing.T) { + c := qt.New(t) + g, err := GetGlob("**.JSON") + c.Assert(err, qt.IsNil) + c.Assert(g.Match("data/my.json"), qt.Equals, true) + +} -- cgit v1.2.3