Beispiel #1
0
// IntersectInclude is not documented yet, please see TestIntersectInclude for
// temporary usage details.
//
// TODO(rjeczalik): document
func (c Control) IntersectInclude(src, dir string) map[string][]string {
	var (
		old = c.FS
		spy = memfs.New()
		tee = Tee(old, spy)
	)
	c.FS = tee
	dirs := c.Intersect(src, dir)
	c.FS = old
	switch len(dirs) {
	case 0:
		return nil
	case 1:
		return map[string][]string{dirs[0]: nil}
	}
	sort.StringSlice(dirs).Sort()
	m := make(map[string][]string, len(dirs))
	for i := 1; i < len(dirs); i++ {
		m[dirs[i]] = nil
		j, n := strings.Index(dirs[i], dirs[i-1]), len(dirs[i-1])
		if j == -1 || dirs[i][j+n] != os.PathSeparator {
			continue
		}
		for _, name := range (Control{FS: spy, Hidden: c.Hidden}).Readdirnames(
			filepath.Join(dir, dirs[i-1])) {
			if notindirs(dirs, name) {
				m[dirs[i-1]] = append(m[dirs[i-1]], filepath.Join(dirs[i-1], name))
			}
		}
	}
	return m
}
Beispiel #2
0
func TestRel(t *testing.T) {
	// To randomize.
	cases := map[string]struct{}{
		"/":                      {},
		"C:/":                    {},
		"/a":                     {},
		"X:/a":                   {},
		"/tmp":                   {},
		"C:/Windows/Temp":        {},
		"/private/var/tmp":       {},
		"C:/Program Files (x86)": {},
	}
	for cas := range cases {
		cas = filepath.FromSlash(cas)
		for i, tree := range trees {
			// This is a hack, which emulates:
			//
			//   func EqualFilesystem(lhs memfs.FS, rhs fs.FS) bool
			//
			// Which should probably hit memfs/util.go file eventually.
			exp, spy := move(tree, cas), memfs.New()
			if n := Copy(tree, Rel(spy, cas)); n == 0 {
				t.Errorf("want n!=0 (cas=%s, i=%d)", cas, i)
				continue
			}
			if !memfs.Equal(spy, exp) {
				t.Errorf("want spy=exp (cas=%s, i=%d)", cas, i)
			}
			return
		}
	}
}
Beispiel #3
0
// TODO(rjeczalik): Split into TestTeeOpen and TestTeeReaddir
func TestTeeOpen(t *testing.T) {
	cases := [...]struct {
		open []string
		read []string
		fs   []byte
	}{
		0: {
			open: []string{"/w/x/y/z"},
			fs:   []byte(".\nw\n\tx\n\t\ty\n\t\t\tz/"),
		},
		1: {
			open: []string{"/a.txt", "/w/w.txt", "/a"},
			fs:   []byte(".\na/\na.txt\nw\n\tw.txt"),
		},
		2: {
			read: []string{"/a/b2/c1"},
			fs:   []byte(".\na\n\tb2\n\t\tc1\n\t\t\td1.txt\n\t\t\td2/\n\t\t\td3.txt"),
		},
		3: {
			read: []string{"/a/b1/c1", "/a/b1/c2", "/a/b1/c3"},
			fs: []byte(".\na\n\tb1\n\t\tc1\n\t\t\tc1.txt\n\t\tc2\n\t\t\tc2.txt\n\t\t" +
				"c3\n\t\t\tc3.txt\n\t\t\td1/"),
		},
		4: {
			read: []string{"/w", "/w/x/y", "/w/x/y/z", "/w/x"},
			fs:   []byte(".\nw\n\tw.txt\n\tx\n\t\ty\n\t\t\tz\n\t\t\t\t1.txt\n\t\ty.txt"),
		}}
Test:
	for i, cas := range cases {
		spy := memfs.New()
		tee := Tee(tree, spy)
		for j, path := range cas.open {
			if _, err := tee.Open(filepath.FromSlash(path)); err != nil {
				t.Errorf("want err=nil; got %q (i=%d, j=%d)", err, i, j)
				continue Test
			}
		}
		for j, path := range cas.read {
			f, err := tee.Open(filepath.FromSlash(path))
			if err != nil {
				t.Errorf("want err=nil; got %q (i=%d, j=%d)", err, i, j)
				continue Test
			}
			if _, err = f.Readdir(0); err != nil {
				t.Errorf("want err=nil; got %q (i=%d, j=%d)", err, i, j)
				continue Test
			}
		}
		if !memfs.Equal(spy, memfs.Must(memfs.UnmarshalTab(cas.fs))) {
			t.Errorf("want Compare(...)=true; got false (i=%d)", i)
		}
	}
}
Beispiel #4
0
func move(fs memfs.FS, off string) memfs.FS {
	mv := memfs.New()
	if err := mv.MkdirAll(off, 0xD); err != nil {
		panic(err)
	}
	if dirlen(mv.Tree) == 0 {
		return fs
	}
	dir, base := filepath.Split(off)
	tmp := memfs.Must(mv.Cd(dir))
	tmp.Tree[base] = fs.Tree
	return mv
}
Beispiel #5
0
func main() {
	if len(os.Args) == 2 && ishelp(os.Args[1]) {
		fmt.Println(usage)
		return
	}
	if len(flag.Args()) > 1 {
		die(usage)
	}
	var (
		root      = "."
		spy       = memfs.New()
		printroot = true
	)
	if len(flags.Args()) == 1 {
		root = flags.Args()[0]
	}
	if root == "." {
		root, _ = os.Getwd()
		printroot = false
	}
	root = filepath.Clean(root)
	(fsutil.Control{FS: fsutil.Tee(fs.FS{}, spy), Hidden: all}).Find(root, lvl)
	spy, err := spy.Cd(root)
	if err != nil {
		die(err) // TODO(rjeczalik): improve error message
	}
	if gowidth > 0 || varname != "" {
		if err = EncodeLiteral(spy, gowidth, varname, os.Stdout); err != nil {
			die(err)
		}
	} else {
		if err = gotree(root, printroot, spy, os.Stdout); err != nil {
			die(err)
		}
	}
}
Beispiel #6
0
func TestCatchSpy(t *testing.T) {
	cases := [...]struct {
		depth int
		c     Control
		dirs  map[string][]string
	}{
		0: {
			1, Control{FS: trees[3]},
			map[string][]string{
				filepath.FromSlash("/"): {
					"/1",
					"/1.txt",
					"/a.txt",
					"/abc",
					"/abc.txt",
				},
				filepath.FromSlash("/1"): {
					"/1/2",
					"/1/2.txt",
				},
				filepath.FromSlash("/abc"): {
					"/abc/1",
					"/abc/efg",
					"/abc/efg.txt",
				},
			},
		},
		1: {
			1, Control{FS: trees[3], Hidden: true},
			map[string][]string{
				filepath.FromSlash("/"): {
					"/.1",
					"/.1.txt",
					"/.abc",
					"/.abc.txt",
					"/1",
					"/1.txt",
					"/a.txt",
					"/abc",
					"/abc.txt",
				},
				filepath.FromSlash("/1"): {
					"/1/.2",
					"/1/.2.txt",
					"/1/2",
					"/1/2.txt",
				},
				filepath.FromSlash("/abc"): {
					"/abc/.1",
					"/abc/.efg",
					"/abc/.efg.txt",
					"/abc/1",
					"/abc/efg",
					"/abc/efg.txt",
				},
			},
		},
		2: {
			3, Control{FS: trees[3]},
			map[string][]string{
				filepath.FromSlash("/abc/1"): {
					"/abc/1/2",
					"/abc/1/2/3",
					"/abc/1/2/3/txt",
					"/abc/1/2/3.txt",
					"/abc/1/2.txt",
				},
				filepath.FromSlash("/1"): {
					"/1/2",
					"/1/2/3",
					"/1/2/3/txt",
					"/1/2/3.txt",
					"/1/2.txt",
				},
				filepath.FromSlash("/abc"): {
					"/abc/1",
					"/abc/1/2",
					"/abc/1/2/3",
					"/abc/1/2/3.txt",
					"/abc/1/2.txt",
					"/abc/efg",
					"/abc/efg/hij",
					"/abc/efg/hij/txt",
					"/abc/efg/hij.txt",
					"/abc/efg.txt",
				},
			},
		},
	}
	for i, cas := range cases {
		for dir, v := range cas.dirs {
			spy := memfs.New()
			for j, fs := range []fs.Filesystem{
				0: cas.c.FS,
				1: Tee(cas.c.FS, spy),
				2: spy,
			} {
				c := cas.c
				c.FS = fs
				found := c.Find(dir, cas.depth)
				if found == nil {
					t.Errorf("want found!=nil (i=%d, dir=%s, j=%d)", i, dir, j)
					continue
				}
				if !equal(found, v) {
					t.Errorf("want found=%v; got %v (i=%d, dir=%s, j=%d)", v,
						found, i, dir, j)
				}
			}
			found := (Control{FS: spy, Hidden: true}).Find(dir, cas.depth)
			if found == nil {
				t.Errorf("want found!=nil (i=%d, dir=%s)", i, dir)
				continue
			}
			if !equal(found, v) {
				t.Errorf("want found=%v; got %v (i=%d, dir=%s)", v, found, i, dir)
			}
		}
	}
}