Port the removed walk test to Go
This commit is contained in:
parent
a2aadd4756
commit
3f9579d61d
@ -227,9 +227,9 @@ func (self *Collection) Apply(f func(path, typ, changed_path string) error) erro
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func allowed(path string) bool {
|
func allowed(path string, patterns ...string) bool {
|
||||||
name := filepath.Base(path)
|
name := filepath.Base(path)
|
||||||
for _, pat := range conf.Ignore_name {
|
for _, pat := range patterns {
|
||||||
if matched, err := filepath.Match(pat, name); err == nil && matched {
|
if matched, err := filepath.Match(pat, name); err == nil && matched {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -257,9 +257,9 @@ func resolve_remote_name(path, defval string) string {
|
|||||||
return defval
|
return defval
|
||||||
}
|
}
|
||||||
|
|
||||||
func walk(base string, names *utils.Set[string], pmap map[string]string) error {
|
func walk(base string, patterns []string, names *utils.Set[string], pmap, path_name_map map[string]string) error {
|
||||||
return filepath.WalkDir(base, func(path string, d fs.DirEntry, err error) error {
|
return filepath.WalkDir(base, func(path string, d fs.DirEntry, err error) error {
|
||||||
is_allowed := allowed(path)
|
is_allowed := allowed(path, patterns...)
|
||||||
if !is_allowed {
|
if !is_allowed {
|
||||||
if d.IsDir() {
|
if d.IsDir() {
|
||||||
return fs.SkipDir
|
return fs.SkipDir
|
||||||
@ -289,11 +289,11 @@ func walk(base string, names *utils.Set[string], pmap map[string]string) error {
|
|||||||
func (self *Collection) collect_files(left, right string) error {
|
func (self *Collection) collect_files(left, right string) error {
|
||||||
left_names, right_names := utils.NewSet[string](16), utils.NewSet[string](16)
|
left_names, right_names := utils.NewSet[string](16), utils.NewSet[string](16)
|
||||||
left_path_map, right_path_map := make(map[string]string, 16), make(map[string]string, 16)
|
left_path_map, right_path_map := make(map[string]string, 16), make(map[string]string, 16)
|
||||||
err := walk(left, left_names, left_path_map)
|
err := walk(left, conf.Ignore_name, left_names, left_path_map, path_name_map)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = walk(right, right_names, right_path_map)
|
err = walk(right, conf.Ignore_name, right_names, right_path_map, path_name_map)
|
||||||
common_names := left_names.Intersect(right_names)
|
common_names := left_names.Intersect(right_names)
|
||||||
changed_names := utils.NewSet[string](common_names.Len())
|
changed_names := utils.NewSet[string](common_names.Len())
|
||||||
for n := range common_names.Iterable() {
|
for n := range common_names.Iterable() {
|
||||||
|
|||||||
53
tools/cmd/diff/collect_test.go
Normal file
53
tools/cmd/diff/collect_test.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
package diff
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"kitty/tools/utils"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = fmt.Print
|
||||||
|
|
||||||
|
func TestDiffCollectWalk(t *testing.T) {
|
||||||
|
tdir := t.TempDir()
|
||||||
|
j := func(x ...string) string { return filepath.Join(append([]string{tdir}, x...)...) }
|
||||||
|
os.MkdirAll(j("a", "b"), 0o700)
|
||||||
|
os.WriteFile(j("a/b/c"), nil, 0o600)
|
||||||
|
os.WriteFile(j("b"), nil, 0o600)
|
||||||
|
os.WriteFile(j("d"), nil, 0o600)
|
||||||
|
os.WriteFile(j("e"), nil, 0o600)
|
||||||
|
os.WriteFile(j("#d#"), nil, 0o600)
|
||||||
|
os.WriteFile(j("e~"), nil, 0o600)
|
||||||
|
os.MkdirAll(j("f"), 0o700)
|
||||||
|
os.WriteFile(j("f/g"), nil, 0o600)
|
||||||
|
os.WriteFile(j("h space"), nil, 0o600)
|
||||||
|
|
||||||
|
expected_names := utils.NewSetWithItems("d", "e", "f/g", "h space")
|
||||||
|
expected_pmap := map[string]string{
|
||||||
|
"d": j("d"),
|
||||||
|
"e": j("e"),
|
||||||
|
"f/g": j("f/g"),
|
||||||
|
"h space": j("h space"),
|
||||||
|
}
|
||||||
|
names := utils.NewSet[string](16)
|
||||||
|
pmap := make(map[string]string, 16)
|
||||||
|
if err := walk(tdir, []string{"*~", "#*#", "b"}, names, pmap, map[string]string{}); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(
|
||||||
|
utils.Sort(expected_names.AsSlice(), func(a, b string) bool { return a < b }),
|
||||||
|
utils.Sort(names.AsSlice(), func(a, b string) bool { return a < b }),
|
||||||
|
); diff != "" {
|
||||||
|
t.Fatal(diff)
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(expected_pmap, pmap); diff != "" {
|
||||||
|
t.Fatal(diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,7 +4,6 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
|
||||||
|
|
||||||
"golang.org/x/exp/constraints"
|
"golang.org/x/exp/constraints"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
@ -74,26 +73,29 @@ func Repeat[T any](x T, n int) []T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Sort[T any](s []T, less func(a, b T) bool) []T {
|
func Sort[T any](s []T, less func(a, b T) bool) []T {
|
||||||
sort.Slice(s, func(i, j int) bool { return less(s[i], s[j]) })
|
slices.SortFunc(s, less)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func StableSort[T any](s []T, less func(a, b T) bool) []T {
|
func StableSort[T any](s []T, less func(a, b T) bool) []T {
|
||||||
sort.SliceStable(s, func(i, j int) bool { return less(s[i], s[j]) })
|
slices.SortStableFunc(s, less)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func sort_with_key[T any, C constraints.Ordered](impl func(any, func(int, int) bool), s []T, key func(a T) C) []T {
|
func sort_with_key[T any, C constraints.Ordered](stable bool, s []T, key func(a T) C) []T {
|
||||||
temp := make([]struct {
|
type t struct {
|
||||||
key C
|
key C
|
||||||
val T
|
val T
|
||||||
}, len(s))
|
}
|
||||||
|
temp := make([]t, len(s))
|
||||||
for i, x := range s {
|
for i, x := range s {
|
||||||
temp[i].val, temp[i].key = x, key(x)
|
temp[i].val, temp[i].key = x, key(x)
|
||||||
}
|
}
|
||||||
impl(temp, func(i, j int) bool {
|
if stable {
|
||||||
return temp[i].key < temp[j].key
|
slices.SortStableFunc(temp, func(a, b t) bool { return a.key < b.key })
|
||||||
})
|
} else {
|
||||||
|
slices.SortFunc(temp, func(a, b t) bool { return a.key < b.key })
|
||||||
|
}
|
||||||
for i, x := range temp {
|
for i, x := range temp {
|
||||||
s[i] = x.val
|
s[i] = x.val
|
||||||
}
|
}
|
||||||
@ -101,11 +103,11 @@ func sort_with_key[T any, C constraints.Ordered](impl func(any, func(int, int) b
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SortWithKey[T any, C constraints.Ordered](s []T, key func(a T) C) []T {
|
func SortWithKey[T any, C constraints.Ordered](s []T, key func(a T) C) []T {
|
||||||
return sort_with_key(sort.Slice, s, key)
|
return sort_with_key(false, s, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func StableSortWithKey[T any, C constraints.Ordered](s []T, key func(a T) C) []T {
|
func StableSortWithKey[T any, C constraints.Ordered](s []T, key func(a T) C) []T {
|
||||||
return sort_with_key(sort.SliceStable, s, key)
|
return sort_with_key(true, s, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Max[T constraints.Ordered](a T, items ...T) (ans T) {
|
func Max[T constraints.Ordered](a T, items ...T) (ans T) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user