aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTulir Asokan <tulir@maunium.net>2018-05-02 22:30:43 +0300
committerTulir Asokan <tulir@maunium.net>2018-05-02 22:30:57 +0300
commitaec3b8d204dd8b4f9308f536e9b5eefcf966f86e (patch)
treee149182b3b085f55e2e9fe2388164dc5a38f68a3 /lib
parent85cbd64c5e78c5b8aad46c96afbd67505987dec9 (diff)
Add tests for PushRule.Match and fork glob to make it compatible with the spec
Diffstat (limited to 'lib')
-rw-r--r--lib/glob/LICENSE22
-rw-r--r--lib/glob/README.md28
-rw-r--r--lib/glob/glob.go108
3 files changed, 158 insertions, 0 deletions
diff --git a/lib/glob/LICENSE b/lib/glob/LICENSE
new file mode 100644
index 0000000..cb00d95
--- /dev/null
+++ b/lib/glob/LICENSE
@@ -0,0 +1,22 @@
+Glob is licensed under the MIT "Expat" License:
+
+Copyright (c) 2016: Zachary Yedidia.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/lib/glob/README.md b/lib/glob/README.md
new file mode 100644
index 0000000..e2e6c64
--- /dev/null
+++ b/lib/glob/README.md
@@ -0,0 +1,28 @@
+# String globbing in Go
+
+[![GoDoc](https://godoc.org/github.com/zyedidia/glob?status.svg)](http://godoc.org/github.com/zyedidia/glob)
+
+This package adds support for globs in Go.
+
+It simply converts glob expressions to regexps. I try to follow the standard defined [here](http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_13).
+
+# Example
+
+```go
+package main
+
+import "github.com/zyedidia/glob"
+
+func main() {
+ glob, err := glob.Compile("{*.go,*.c}")
+ if err != nil {
+ // Error
+ }
+
+ glob.Match([]byte("test.c")) // true
+ glob.Match([]byte("hello.go")) // true
+ glob.Match([]byte("test.d")) // false
+}
+```
+
+You can call all the same functions on a glob that you can call on a regexp.
diff --git a/lib/glob/glob.go b/lib/glob/glob.go
new file mode 100644
index 0000000..c270dbc
--- /dev/null
+++ b/lib/glob/glob.go
@@ -0,0 +1,108 @@
+// Package glob provides objects for matching strings with globs
+package glob
+
+import "regexp"
+
+// Glob is a wrapper of *regexp.Regexp.
+// It should contain a glob expression compiled into a regular expression.
+type Glob struct {
+ *regexp.Regexp
+}
+
+// Compile a takes a glob expression as a string and transforms it
+// into a *Glob object (which is really just a regular expression)
+// Compile also returns a possible error.
+func Compile(pattern string) (*Glob, error) {
+ r, err := globToRegex(pattern)
+ return &Glob{r}, err
+}
+
+func globToRegex(glob string) (*regexp.Regexp, error) {
+ regex := ""
+ inGroup := 0
+ inClass := 0
+ firstIndexInClass := -1
+ arr := []byte(glob)
+
+ hasGlobCharacters := false
+
+ for i := 0; i < len(arr); i++ {
+ ch := arr[i]
+
+ switch ch {
+ case '\\':
+ i++
+ if i >= len(arr) {
+ regex += "\\"
+ } else {
+ next := arr[i]
+ switch next {
+ case ',':
+ // Nothing
+ case 'Q', 'E':
+ regex += "\\\\"
+ default:
+ regex += "\\"
+ }
+ regex += string(next)
+ }
+ case '*':
+ if inClass == 0 {
+ regex += ".*"
+ } else {
+ regex += "*"
+ }
+ hasGlobCharacters = true
+ case '?':
+ if inClass == 0 {
+ regex += "."
+ } else {
+ regex += "?"
+ }
+ hasGlobCharacters = true
+ case '[':
+ inClass++
+ firstIndexInClass = i + 1
+ regex += "["
+ hasGlobCharacters = true
+ case ']':
+ inClass--
+ regex += "]"
+ case '.', '(', ')', '+', '|', '^', '$', '@', '%':
+ if inClass == 0 || (firstIndexInClass == i && ch == '^') {
+ regex += "\\"
+ }
+ regex += string(ch)
+ hasGlobCharacters = true
+ case '!':
+ if firstIndexInClass == i {
+ regex += "^"
+ } else {
+ regex += "!"
+ }
+ hasGlobCharacters = true
+ case '{':
+ inGroup++
+ regex += "("
+ hasGlobCharacters = true
+ case '}':
+ inGroup--
+ regex += ")"
+ case ',':
+ if inGroup > 0 {
+ regex += "|"
+ hasGlobCharacters = true
+ } else {
+ regex += ","
+ }
+ default:
+ regex += string(ch)
+ }
+ }
+
+ if hasGlobCharacters {
+ return regexp.Compile("^" + regex + "$")
+ } else {
+ return regexp.Compile(regex)
+ }
+}