until stable: pin-dependency, update-vendor, update-bazel, lint-dep

This commit is contained in:
monopole
2021-03-08 13:28:13 -08:00
parent 6c9460f0b4
commit ba39d22e39
420 changed files with 142058 additions and 6408 deletions

View File

@@ -0,0 +1,6 @@
language: go
go:
- 1.14.x
- master
script:
- go test -v ./...

21
vendor/github.com/monochromegane/go-gitignore/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) [2015] [go-gitignore]
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.

View File

@@ -0,0 +1,95 @@
# go-gitignore [![Build Status](https://travis-ci.org/monochromegane/go-gitignore.svg)](https://travis-ci.org/monochromegane/go-gitignore)
A fast gitignore matching library for Go.
This library use simple tree index for matching, so keep fast if gitignore file has many pattern.
## Usage
```go
gitignore, _ := gitignore.NewGitIgnore("/path/to/gitignore")
path := "/path/to/file"
isDir := false
gitignore.Match(path, isDir)
```
### Specify base directory
go-gitignore treat `path` as a base directory.
If you want to specify other base (e.g. current directory and Global gitignore), you can like the following.
```go
gitignore, _ := gitignore.NewGitIgnore("/home/you/.gitignore", ".")
```
### From io.Reader
go-gitignore can initialize from io.Reader.
```go
gitignore, _ := gitignore.NewGitIgnoreFromReader(base, reader)
```
## Simple tree index
go-gitignore parse gitignore file, and generate a simple tree index for matching like the following.
```
.
├── accept
│   ├── absolute
│   │   └── depth
│   │   ├── initial
│   │   └── other
│   └── relative
│   └── depth
│   ├── initial
│   └── other
└── ignore
├── absolute
│   └── depth
│   ├── initial
│   └── other
└── relative
└── depth
├── initial
└── other
```
## Features
- Support absolute path (/path/to/ignore)
- Support relative path (path/to/ignore)
- Support accept pattern (!path/to/accept)
- Support directory pattern (path/to/directory/)
- Support glob pattern (path/to/\*.txt)
*note: glob pattern*
go-gitignore use [filepath.Match](https://golang.org/pkg/path/filepath/#Match) for matching meta char pattern, so not support recursive pattern (path/`**`/file).
## Installation
```sh
$ go get github.com/monochromegane/go-gitignore
```
## Contribution
1. Fork it
2. Create a feature branch
3. Commit your changes
4. Rebase your local changes against the master branch
5. Run test suite with the `go test ./...` command and confirm that it passes
6. Run `gofmt -s`
7. Create new Pull Request
## License
[MIT](https://github.com/monochromegane/go-gitignore/blob/master/LICENSE)
## Author
[monochromegane](https://github.com/monochromegane)

View File

@@ -0,0 +1,79 @@
package gitignore
import "strings"
const (
asc = iota
desc
)
type depthPatternHolder struct {
patterns depthPatterns
order int
}
func newDepthPatternHolder(order int) depthPatternHolder {
return depthPatternHolder{
patterns: depthPatterns{m: map[int]initialPatternHolder{}},
order: order,
}
}
func (h *depthPatternHolder) add(pattern string) {
count := strings.Count(strings.Trim(pattern, "/"), "/")
h.patterns.set(count+1, pattern)
}
func (h depthPatternHolder) match(path string, isDir bool) bool {
if h.patterns.size() == 0 {
return false
}
for depth := 1; ; depth++ {
var part string
var isLast, isDirCurrent bool
if h.order == asc {
part, isLast = cutN(path, depth)
if isLast {
isDirCurrent = isDir
} else {
isDirCurrent = false
}
} else {
part, isLast = cutLastN(path, depth)
isDirCurrent = isDir
}
if patterns, ok := h.patterns.get(depth); ok {
if patterns.match(part, isDirCurrent) {
return true
}
}
if isLast {
break
}
}
return false
}
type depthPatterns struct {
m map[int]initialPatternHolder
}
func (p *depthPatterns) set(depth int, pattern string) {
if ps, ok := p.m[depth]; ok {
ps.add(pattern)
} else {
holder := newInitialPatternHolder()
holder.add(pattern)
p.m[depth] = holder
}
}
func (p depthPatterns) get(depth int) (initialPatternHolder, bool) {
patterns, ok := p.m[depth]
return patterns, ok
}
func (p depthPatterns) size() int {
return len(p.m)
}

View File

@@ -0,0 +1,31 @@
package gitignore
import "strings"
// Only benchmark use
type fullScanPatterns struct {
absolute patterns
relative patterns
}
func newFullScanPatterns() *fullScanPatterns {
return &fullScanPatterns{
absolute: patterns{},
relative: patterns{},
}
}
func (ps *fullScanPatterns) add(pattern string) {
if strings.HasPrefix(pattern, "/") {
ps.absolute.add(newPattern(pattern))
} else {
ps.relative.add(newPattern(pattern))
}
}
func (ps fullScanPatterns) match(path string, isDir bool) bool {
if ps.absolute.match(path, isDir) {
return true
}
return ps.relative.match(path, isDir)
}

View File

@@ -0,0 +1,80 @@
package gitignore
import (
"bufio"
"io"
"os"
"path/filepath"
"strings"
)
type IgnoreMatcher interface {
Match(path string, isDir bool) bool
}
type DummyIgnoreMatcher bool
func (d DummyIgnoreMatcher) Match(path string, isDir bool) bool {
return bool(d)
}
type gitIgnore struct {
ignorePatterns scanStrategy
acceptPatterns scanStrategy
path string
}
func NewGitIgnore(gitignore string, base ...string) (IgnoreMatcher, error) {
var path string
if len(base) > 0 {
path = base[0]
} else {
path = filepath.Dir(gitignore)
}
file, err := os.Open(gitignore)
if err != nil {
return nil, err
}
defer file.Close()
return NewGitIgnoreFromReader(path, file), nil
}
func NewGitIgnoreFromReader(path string, r io.Reader) IgnoreMatcher {
g := gitIgnore{
ignorePatterns: newIndexScanPatterns(),
acceptPatterns: newIndexScanPatterns(),
path: path,
}
scanner := bufio.NewScanner(r)
for scanner.Scan() {
line := strings.Trim(scanner.Text(), " ")
if len(line) == 0 || strings.HasPrefix(line, "#") {
continue
}
if strings.HasPrefix(line, `\#`) {
line = strings.TrimPrefix(line, `\`)
}
if strings.HasPrefix(line, "!") {
g.acceptPatterns.add(strings.TrimPrefix(line, "!"))
} else {
g.ignorePatterns.add(line)
}
}
return g
}
func (g gitIgnore) Match(path string, isDir bool) bool {
relativePath, err := filepath.Rel(g.path, path)
if err != nil {
return false
}
relativePath = filepath.ToSlash(relativePath)
if g.acceptPatterns.match(relativePath, isDir) {
return false
}
return g.ignorePatterns.match(relativePath, isDir)
}

View File

@@ -0,0 +1,35 @@
package gitignore
import "strings"
type indexScanPatterns struct {
absolute depthPatternHolder
relative depthPatternHolder
}
func newIndexScanPatterns() *indexScanPatterns {
return &indexScanPatterns{
absolute: newDepthPatternHolder(asc),
relative: newDepthPatternHolder(desc),
}
}
func (ps *indexScanPatterns) add(pattern string) {
if strings.HasPrefix(pattern, "/") {
ps.absolute.add(pattern)
} else {
ps.relative.add(pattern)
}
}
func (ps indexScanPatterns) match(path string, isDir bool) bool {
if ps.absolute.match(path, isDir) {
return true
}
return ps.relative.match(path, isDir)
}
type scanStrategy interface {
add(pattern string)
match(path string, isDir bool) bool
}

View File

@@ -0,0 +1,62 @@
package gitignore
import "strings"
const initials = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ."
type initialPatternHolder struct {
patterns initialPatterns
otherPatterns *patterns
}
func newInitialPatternHolder() initialPatternHolder {
return initialPatternHolder{
patterns: initialPatterns{m: map[byte]*patterns{}},
otherPatterns: &patterns{},
}
}
func (h *initialPatternHolder) add(pattern string) {
trimedPattern := strings.TrimPrefix(pattern, "/")
if strings.IndexAny(trimedPattern[0:1], initials) != -1 {
h.patterns.set(trimedPattern[0], newPatternForEqualizedPath(pattern))
} else {
h.otherPatterns.add(newPatternForEqualizedPath(pattern))
}
}
func (h initialPatternHolder) match(path string, isDir bool) bool {
if h.patterns.size() == 0 && h.otherPatterns.size() == 0 {
return false
}
if patterns, ok := h.patterns.get(path[0]); ok {
if patterns.match(path, isDir) {
return true
}
}
return h.otherPatterns.match(path, isDir)
}
type initialPatterns struct {
m map[byte]*patterns
}
func (p *initialPatterns) set(initial byte, pattern pattern) {
if ps, ok := p.m[initial]; ok {
ps.add(pattern)
} else {
patterns := &patterns{}
patterns.add(pattern)
p.m[initial] = patterns
}
}
func (p initialPatterns) get(initial byte) (*patterns, bool) {
patterns, ok := p.m[initial]
return patterns, ok
}
func (p initialPatterns) size() int {
return len(p.m)
}

24
vendor/github.com/monochromegane/go-gitignore/match.go generated vendored Normal file
View File

@@ -0,0 +1,24 @@
package gitignore
import "path/filepath"
type pathMatcher interface {
match(path string) bool
}
type simpleMatcher struct {
path string
}
func (m simpleMatcher) match(path string) bool {
return m.path == path
}
type filepathMatcher struct {
path string
}
func (m filepathMatcher) match(path string) bool {
match, _ := filepath.Match(m.path, path)
return match
}

View File

@@ -0,0 +1,69 @@
package gitignore
import (
"path/filepath"
"strings"
)
var Separator = string(filepath.Separator)
type pattern struct {
hasRootPrefix bool
hasDirSuffix bool
pathDepth int
matcher pathMatcher
onlyEqualizedPath bool
}
func newPattern(path string) pattern {
hasRootPrefix := path[0] == '/'
hasDirSuffix := path[len(path)-1] == '/'
var pathDepth int
if !hasRootPrefix {
pathDepth = strings.Count(path, "/")
}
var matcher pathMatcher
matchingPath := strings.Trim(path, "/")
if hasMeta(path) {
matcher = filepathMatcher{path: matchingPath}
} else {
matcher = simpleMatcher{path: matchingPath}
}
return pattern{
hasRootPrefix: hasRootPrefix,
hasDirSuffix: hasDirSuffix,
pathDepth: pathDepth,
matcher: matcher,
}
}
func newPatternForEqualizedPath(path string) pattern {
pattern := newPattern(path)
pattern.onlyEqualizedPath = true
return pattern
}
func (p pattern) match(path string, isDir bool) bool {
if p.hasDirSuffix && !isDir {
return false
}
var targetPath string
if p.hasRootPrefix || p.onlyEqualizedPath {
// absolute pattern or only equalized path mode
targetPath = path
} else {
// relative pattern
targetPath = p.equalizeDepth(path)
}
return p.matcher.match(targetPath)
}
func (p pattern) equalizeDepth(path string) string {
equalizedPath, _ := cutLastN(path, p.pathDepth+1)
return equalizedPath
}

View File

@@ -0,0 +1,22 @@
package gitignore
type patterns struct {
patterns []pattern
}
func (ps *patterns) add(pattern pattern) {
ps.patterns = append(ps.patterns, pattern)
}
func (ps *patterns) size() int {
return len(ps.patterns)
}
func (ps patterns) match(path string, isDir bool) bool {
for _, p := range ps.patterns {
if match := p.match(path, isDir); match {
return true
}
}
return false
}

45
vendor/github.com/monochromegane/go-gitignore/util.go generated vendored Normal file
View File

@@ -0,0 +1,45 @@
package gitignore
import (
"os"
"strings"
)
func cutN(path string, n int) (string, bool) {
isLast := true
var i, count int
for i < len(path)-1 {
if os.IsPathSeparator(path[i]) {
count++
if count >= n {
isLast = false
break
}
}
i++
}
return path[:i+1], isLast
}
func cutLastN(path string, n int) (string, bool) {
isLast := true
i := len(path) - 1
var count int
for i >= 0 {
if os.IsPathSeparator(path[i]) {
count++
if count >= n {
isLast = false
break
}
}
i--
}
return path[i+1:], isLast
}
func hasMeta(path string) bool {
return strings.IndexAny(path, "*?[") >= 0
}