...

Source file src/github.com/monochromegane/go-gitignore/gitignore.go

Documentation: github.com/monochromegane/go-gitignore

     1  package gitignore
     2  
     3  import (
     4  	"bufio"
     5  	"io"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  )
    10  
    11  type IgnoreMatcher interface {
    12  	Match(path string, isDir bool) bool
    13  }
    14  
    15  type DummyIgnoreMatcher bool
    16  
    17  func (d DummyIgnoreMatcher) Match(path string, isDir bool) bool {
    18  	return bool(d)
    19  }
    20  
    21  type gitIgnore struct {
    22  	ignorePatterns scanStrategy
    23  	acceptPatterns scanStrategy
    24  	path           string
    25  }
    26  
    27  func NewGitIgnore(gitignore string, base ...string) (IgnoreMatcher, error) {
    28  	var path string
    29  	if len(base) > 0 {
    30  		path = base[0]
    31  	} else {
    32  		path = filepath.Dir(gitignore)
    33  	}
    34  
    35  	file, err := os.Open(gitignore)
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  	defer file.Close()
    40  
    41  	return NewGitIgnoreFromReader(path, file), nil
    42  }
    43  
    44  func NewGitIgnoreFromReader(path string, r io.Reader) IgnoreMatcher {
    45  	g := gitIgnore{
    46  		ignorePatterns: newIndexScanPatterns(),
    47  		acceptPatterns: newIndexScanPatterns(),
    48  		path:           path,
    49  	}
    50  	scanner := bufio.NewScanner(r)
    51  	for scanner.Scan() {
    52  		line := strings.Trim(scanner.Text(), " ")
    53  		if len(line) == 0 || strings.HasPrefix(line, "#") {
    54  			continue
    55  		}
    56  		if strings.HasPrefix(line, `\#`) {
    57  			line = strings.TrimPrefix(line, `\`)
    58  		}
    59  
    60  		if strings.HasPrefix(line, "!") {
    61  			g.acceptPatterns.add(strings.TrimPrefix(line, "!"))
    62  		} else {
    63  			g.ignorePatterns.add(line)
    64  		}
    65  	}
    66  	return g
    67  }
    68  
    69  func (g gitIgnore) Match(path string, isDir bool) bool {
    70  	relativePath, err := filepath.Rel(g.path, path)
    71  	if err != nil {
    72  		return false
    73  	}
    74  	relativePath = filepath.ToSlash(relativePath)
    75  
    76  	if g.acceptPatterns.match(relativePath, isDir) {
    77  		return false
    78  	}
    79  	return g.ignorePatterns.match(relativePath, isDir)
    80  }
    81  

View as plain text