Merge pull request #589 from AudriusButkevicius/include
Add #include directive to .stignore (fixes #424)
This commit is contained in:
2
build.go
2
build.go
@@ -163,7 +163,7 @@ func setup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func test(pkg string) {
|
func test(pkg string) {
|
||||||
runPrint("godep", "go", "test", pkg)
|
runPrint("godep", "go", "test", "-short", "-timeout", "10s", pkg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func install(pkg string) {
|
func install(pkg string) {
|
||||||
|
|||||||
0
scanner/testdata/.foo/bar
vendored
0
scanner/testdata/.foo/bar
vendored
8
scanner/testdata/.stignore
vendored
8
scanner/testdata/.stignore
vendored
@@ -1,2 +1,6 @@
|
|||||||
.*
|
#include excludes
|
||||||
quux
|
#include nonexistent-file
|
||||||
|
|
||||||
|
bfile
|
||||||
|
dir1/cfile
|
||||||
|
|
||||||
|
|||||||
1
scanner/testdata/afile
vendored
Normal file
1
scanner/testdata/afile
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
foo
|
||||||
1
scanner/testdata/bar
vendored
1
scanner/testdata/bar
vendored
@@ -1 +0,0 @@
|
|||||||
foobarbaz
|
|
||||||
1
scanner/testdata/baz/quux
vendored
1
scanner/testdata/baz/quux
vendored
@@ -1 +0,0 @@
|
|||||||
baazquux
|
|
||||||
1
scanner/testdata/bfile
vendored
Normal file
1
scanner/testdata/bfile
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
bar
|
||||||
1
scanner/testdata/dir1/cfile
vendored
Normal file
1
scanner/testdata/dir1/cfile
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
baz
|
||||||
1
scanner/testdata/dir1/dfile
vendored
Normal file
1
scanner/testdata/dir1/dfile
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
quux
|
||||||
1
scanner/testdata/dir2/cfile
vendored
Normal file
1
scanner/testdata/dir2/cfile
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
baz
|
||||||
1
scanner/testdata/dir2/dfile
vendored
Normal file
1
scanner/testdata/dir2/dfile
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
quux
|
||||||
1
scanner/testdata/dir3/cfile
vendored
Normal file
1
scanner/testdata/dir3/cfile
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
baz
|
||||||
1
scanner/testdata/dir3/dfile
vendored
Normal file
1
scanner/testdata/dir3/dfile
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
quux
|
||||||
0
scanner/testdata/empty
vendored
0
scanner/testdata/empty
vendored
4
scanner/testdata/excludes
vendored
Normal file
4
scanner/testdata/excludes
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
dir2/dfile
|
||||||
|
#include excludes
|
||||||
|
#include further-excludes
|
||||||
|
#include loop-excludes
|
||||||
1
scanner/testdata/foo
vendored
1
scanner/testdata/foo
vendored
@@ -1 +0,0 @@
|
|||||||
foobar
|
|
||||||
1
scanner/testdata/further-excludes
vendored
Normal file
1
scanner/testdata/further-excludes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
dir3
|
||||||
1
scanner/testdata/loop-excludes
vendored
Normal file
1
scanner/testdata/loop-excludes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
#include excludes
|
||||||
@@ -99,7 +99,8 @@ func (w *Walker) loadIgnoreFiles(dir string, ignores *[]*regexp.Regexp) filepath
|
|||||||
|
|
||||||
if pn, sn := filepath.Split(rn); sn == w.IgnoreFile {
|
if pn, sn := filepath.Split(rn); sn == w.IgnoreFile {
|
||||||
pn := filepath.Clean(pn)
|
pn := filepath.Clean(pn)
|
||||||
dirIgnores := loadIgnoreFile(p, pn)
|
filesSeen := make(map[string]map[string]bool)
|
||||||
|
dirIgnores := loadIgnoreFile(p, pn, filesSeen)
|
||||||
*ignores = append(*ignores, dirIgnores...)
|
*ignores = append(*ignores, dirIgnores...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,16 +108,16 @@ func (w *Walker) loadIgnoreFiles(dir string, ignores *[]*regexp.Regexp) filepath
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadIgnoreFile(ignFile, base string) []*regexp.Regexp {
|
func loadIgnoreFile(ignFile, base string, filesSeen map[string]map[string]bool) []*regexp.Regexp {
|
||||||
fd, err := os.Open(ignFile)
|
fd, err := os.Open(ignFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
defer fd.Close()
|
defer fd.Close()
|
||||||
return parseIgnoreFile(fd, base)
|
return parseIgnoreFile(fd, base, ignFile, filesSeen)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseIgnoreFile(fd io.Reader, base string) []*regexp.Regexp {
|
func parseIgnoreFile(fd io.Reader, base, currentFile string, filesSeen map[string]map[string]bool) []*regexp.Regexp {
|
||||||
var exps []*regexp.Regexp
|
var exps []*regexp.Regexp
|
||||||
scanner := bufio.NewScanner(fd)
|
scanner := bufio.NewScanner(fd)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
@@ -148,6 +149,27 @@ func parseIgnoreFile(fd io.Reader, base string) []*regexp.Regexp {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
exps = append(exps, exp)
|
exps = append(exps, exp)
|
||||||
|
} else if strings.HasPrefix(line, "#include ") {
|
||||||
|
includeFile := filepath.Join(filepath.Dir(currentFile), strings.Replace(line, "#include ", "", 1))
|
||||||
|
if _, err := os.Stat(includeFile); os.IsNotExist(err) {
|
||||||
|
l.Infoln("Could not open ignore include file", includeFile)
|
||||||
|
} else {
|
||||||
|
seen := false
|
||||||
|
if seenByCurrent, ok := filesSeen[currentFile]; ok {
|
||||||
|
_, seen = seenByCurrent[includeFile]
|
||||||
|
}
|
||||||
|
|
||||||
|
if seen {
|
||||||
|
l.Warnf("Recursion detected while including %s from %s", includeFile, currentFile)
|
||||||
|
} else {
|
||||||
|
if filesSeen[currentFile] == nil {
|
||||||
|
filesSeen[currentFile] = make(map[string]bool)
|
||||||
|
}
|
||||||
|
filesSeen[currentFile][includeFile] = true
|
||||||
|
includes := loadIgnoreFile(includeFile, base, filesSeen)
|
||||||
|
exps = append(exps, includes...)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Path name or pattern, add it so it matches files both in
|
// Path name or pattern, add it so it matches files both in
|
||||||
// current directory and subdirs.
|
// current directory and subdirs.
|
||||||
|
|||||||
@@ -8,32 +8,48 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
rdebug "runtime/debug"
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/syncthing/syncthing/protocol"
|
"github.com/syncthing/syncthing/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
var testdata = []struct {
|
type testfile struct {
|
||||||
name string
|
name string
|
||||||
size int
|
size int
|
||||||
hash string
|
hash string
|
||||||
}{
|
}
|
||||||
{"bar", 10, "2f72cc11a6fcd0271ecef8c61056ee1eb1243be3805bf9a9df98f92f7636b05c"},
|
|
||||||
{"baz", 0, ""},
|
type testfileList []testfile
|
||||||
{"empty", 0, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"},
|
|
||||||
{"foo", 7, "aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f"},
|
var testdata = testfileList{
|
||||||
|
{"afile", 4, "b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c"},
|
||||||
|
{"dir1", 128, ""},
|
||||||
|
{filepath.Join("dir1", "dfile"), 5, "49ae93732fcf8d63fe1cce759664982dbd5b23161f007dba8561862adc96d063"},
|
||||||
|
{"dir2", 128, ""},
|
||||||
|
{filepath.Join("dir2", "cfile"), 4, "bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c"},
|
||||||
|
{"excludes", 78, "1f5ac95d9e6fb2516629a029d788d27953c7bb2f4dc09184b660fdda0c8f2f04"},
|
||||||
|
{"further-excludes", 5, "7eb0a548094fa6295f7fd9200d69973e5f5ec5c04f2a86d998080ac43ecf89f1"},
|
||||||
|
{"loop-excludes", 18, "2db057aa82a8b8fe4b1367ccc875259ed4b8020255820d4e3d4bfe78f0dd3f2a"},
|
||||||
}
|
}
|
||||||
|
|
||||||
var correctIgnores = map[string][]string{
|
var correctIgnores = map[string][]string{
|
||||||
".": {".*", "quux"},
|
".": {".*", "quux"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// This test runs the risk of entering infinite recursion if it fails.
|
||||||
|
// Limit the stack size to 10 megs to creash early in that case instead of
|
||||||
|
// potentially taking down the box...
|
||||||
|
rdebug.SetMaxStack(10 * 1 << 20)
|
||||||
|
}
|
||||||
|
|
||||||
func TestWalkSub(t *testing.T) {
|
func TestWalkSub(t *testing.T) {
|
||||||
w := Walker{
|
w := Walker{
|
||||||
Dir: "testdata",
|
Dir: "testdata",
|
||||||
Sub: "foo",
|
Sub: "dir2",
|
||||||
BlockSize: 128 * 1024,
|
BlockSize: 128 * 1024,
|
||||||
IgnoreFile: ".stignore",
|
IgnoreFile: ".stignore",
|
||||||
}
|
}
|
||||||
@@ -46,11 +62,17 @@ func TestWalkSub(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(files) != 1 {
|
// The directory contains two files, where one is ignored from a higher
|
||||||
t.Fatalf("Incorrect length %d != 1", len(files))
|
// level. We should see only the directory and one of the files.
|
||||||
|
|
||||||
|
if len(files) != 2 {
|
||||||
|
t.Fatalf("Incorrect length %d != 2", len(files))
|
||||||
}
|
}
|
||||||
if files[0].Name != "foo" {
|
if files[0].Name != "dir2" {
|
||||||
t.Errorf("Incorrect file %v != foo", files[0])
|
t.Errorf("Incorrect file %v != dir2", files[0])
|
||||||
|
}
|
||||||
|
if files[1].Name != filepath.Join("dir2", "cfile") {
|
||||||
|
t.Errorf("Incorrect file %v != dir2/cfile", files[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,39 +82,21 @@ func TestWalk(t *testing.T) {
|
|||||||
BlockSize: 128 * 1024,
|
BlockSize: 128 * 1024,
|
||||||
IgnoreFile: ".stignore",
|
IgnoreFile: ".stignore",
|
||||||
}
|
}
|
||||||
fchan, err := w.Walk()
|
|
||||||
var files []protocol.FileInfo
|
|
||||||
for f := range fchan {
|
|
||||||
files = append(files, f)
|
|
||||||
}
|
|
||||||
sort.Sort(fileList(files))
|
|
||||||
|
|
||||||
|
fchan, err := w.Walk()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if l1, l2 := len(files), len(testdata); l1 != l2 {
|
var tmp []protocol.FileInfo
|
||||||
t.Log(files)
|
for f := range fchan {
|
||||||
t.Log(testdata)
|
tmp = append(tmp, f)
|
||||||
t.Fatalf("Incorrect number of walked files %d != %d", l1, l2)
|
|
||||||
}
|
}
|
||||||
|
sort.Sort(fileList(tmp))
|
||||||
|
files := fileList(tmp).testfiles()
|
||||||
|
|
||||||
for i := range testdata {
|
if !reflect.DeepEqual(files, testdata) {
|
||||||
if n1, n2 := testdata[i].name, files[i].Name; n1 != n2 {
|
t.Errorf("Walk returned unexpected data\nExpected: %v\nActual: %v", testdata, files)
|
||||||
t.Errorf("Incorrect file name %q != %q for case #%d", n1, n2, i)
|
|
||||||
}
|
|
||||||
|
|
||||||
if testdata[i].hash != "" {
|
|
||||||
if h1, h2 := fmt.Sprintf("%x", files[i].Blocks[0].Hash), testdata[i].hash; h1 != h2 {
|
|
||||||
t.Errorf("Incorrect hash %q != %q for case #%d", h1, h2, i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t0 := time.Date(2010, 1, 1, 0, 0, 0, 0, time.UTC).Unix()
|
|
||||||
t1 := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC).Unix()
|
|
||||||
if mt := files[i].Modified; mt < t0 || mt > t1 {
|
|
||||||
t.Errorf("Unrealistic modtime %d for test %d", mt, i)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,20 +132,20 @@ func TestIgnore(t *testing.T) {
|
|||||||
*/other/test
|
*/other/test
|
||||||
**/deep
|
**/deep
|
||||||
`)
|
`)
|
||||||
patterns := parseIgnoreFile(patStr, "")
|
patterns := parseIgnoreFile(patStr, "", "", make(map[string]map[string]bool))
|
||||||
|
|
||||||
patStr = bytes.NewBufferString(`
|
patStr = bytes.NewBufferString(`
|
||||||
bar
|
bar
|
||||||
z*
|
z*
|
||||||
q[abc]x
|
q[abc]x
|
||||||
`)
|
`)
|
||||||
patterns = append(patterns, parseIgnoreFile(patStr, "foo")...)
|
patterns = append(patterns, parseIgnoreFile(patStr, "foo", "", make(map[string]map[string]bool))...)
|
||||||
|
|
||||||
patStr = bytes.NewBufferString(`
|
patStr = bytes.NewBufferString(`
|
||||||
quux
|
quux
|
||||||
.*
|
.*
|
||||||
`)
|
`)
|
||||||
patterns = append(patterns, parseIgnoreFile(patStr, "foo/baz")...)
|
patterns = append(patterns, parseIgnoreFile(patStr, "foo/baz", "", make(map[string]map[string]bool))...)
|
||||||
|
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
f string
|
f string
|
||||||
@@ -194,3 +198,27 @@ func (f fileList) Less(a, b int) bool {
|
|||||||
func (f fileList) Swap(a, b int) {
|
func (f fileList) Swap(a, b int) {
|
||||||
f[a], f[b] = f[b], f[a]
|
f[a], f[b] = f[b], f[a]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l fileList) testfiles() testfileList {
|
||||||
|
testfiles := make(testfileList, len(l))
|
||||||
|
for i, f := range l {
|
||||||
|
if len(f.Blocks) > 1 {
|
||||||
|
panic("simple test case stuff only supports a single block per file")
|
||||||
|
}
|
||||||
|
testfiles[i] = testfile{name: f.Name, size: int(f.Size())}
|
||||||
|
if len(f.Blocks) == 1 {
|
||||||
|
testfiles[i].hash = fmt.Sprintf("%x", f.Blocks[0].Hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return testfiles
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l testfileList) String() string {
|
||||||
|
var b bytes.Buffer
|
||||||
|
b.WriteString("{\n")
|
||||||
|
for _, f := range l {
|
||||||
|
fmt.Fprintf(&b, " %s (%d bytes): %s\n", f.name, f.size, f.hash)
|
||||||
|
}
|
||||||
|
b.WriteString("}")
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user