diff --git a/main_test.go b/main_test.go index ad52667..e0baa72 100644 --- a/main_test.go +++ b/main_test.go @@ -132,6 +132,7 @@ func TestScript(t *testing.T) { "generate-literals": generateLiterals, "setenvfile": setenvfile, "grepfiles": grepfiles, + "find-remove": findRemove, }, UpdateScripts: *update, RequireExplicitExec: true, @@ -354,7 +355,7 @@ func grepfiles(ts *testscript.TestScript, neg bool, args []string) { ts.Fatalf("usage: grepfiles path pattern") } anyFound := false - path, pattern := args[0], args[1] + path, pattern := ts.MkAbs(args[0]), args[1] rx := regexp.MustCompile(pattern) if err := filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error { if err != nil { @@ -377,6 +378,36 @@ func grepfiles(ts *testscript.TestScript, neg bool, args []string) { } } +func findRemove(ts *testscript.TestScript, neg bool, args []string) { + if neg { + ts.Fatalf("unsupported: ! find-remove") + } + if len(args) != 2 { + ts.Fatalf("usage: find-remove path pattern") + } + removed := 0 + path, pattern := ts.MkAbs(args[0]), args[1] + rx := regexp.MustCompile(pattern) + if err := filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + if rx.MatchString(path) { + if err := os.Remove(path); err != nil { + return err + } + removed++ + } + return nil + }); err != nil { + ts.Fatalf("%s", err) + } + if removed == 0 { + ts.Fatalf("no matching files to remove") + } + ts.Logf("removed %d matching files", removed) +} + func TestSplitFlagsFromArgs(t *testing.T) { t.Parallel() tests := []struct { diff --git a/testdata/script/cache.txtar b/testdata/script/cache.txtar new file mode 100644 index 0000000..7b64313 --- /dev/null +++ b/testdata/script/cache.txtar @@ -0,0 +1,102 @@ +# Ensure that garble knows how to handle all kinds of initial state scenarios +# when it comes to caching. If any cache file is missing, garble should redo +# the work and write the cache file again. See the docs below. + +[short] stop # This step is slow by design, since it starts with an empty cache. + +env GOCACHE=${WORK}/gocache + +# level1a has the regular Go build cached. +exec go build ./level1a + +# level1b has the garble build cached, but our own cache files are gone. +exec garble build ./level1b +find-remove gocache '-garble-' + +# level1c has the garble build cached with all files available. +exec garble build ./level1c + +# TODO: this test now fails due to our fragile caching. +! exec garble build +stderr 'cannot load garble export file' +# exec garble build +# exec ./main +# cmp stderr main.stderr + +# verify with regular Go. +go build +exec ./main +cmp stderr main.stderr +-- go.mod -- +module test/main + +go 1.20 +-- main.go -- +package main + +import ( + "test/main/level1a" + "test/main/level1b" + "test/main/level1c" +) + +func main() { + level1a.Print() + level1b.Print() + level1c.Print() +} +-- level1a/pkg.go -- +package level1a + +import ( + "test/main/level1a/level2x" + "test/main/level1a/level2y" +) + +func Print() { println(level2x.Value, level2y.Value) } +-- level1a/level2x/pkg.go -- +package level2x + +var Value = "1a/2x" +-- level1a/level2y/pkg.go -- +package level2y + +var Value = "1a/2y" +-- level1b/pkg.go -- +package level1b + +import ( + "test/main/level1b/level2x" + "test/main/level1b/level2y" +) + +func Print() { println(level2x.Value, level2y.Value) } +-- level1b/level2x/pkg.go -- +package level2x + +var Value = "1b/2x" +-- level1b/level2y/pkg.go -- +package level2y + +var Value = "1b/2y" +-- level1c/pkg.go -- +package level1c + +import ( + "test/main/level1c/level2x" + "test/main/level1c/level2y" +) + +func Print() { println(level2x.Value, level2y.Value) } +-- level1c/level2x/pkg.go -- +package level2x + +var Value = "1c/2x" +-- level1c/level2y/pkg.go -- +package level2y + +var Value = "1c/2y" +-- main.stderr -- +1a/2x 1a/2y +1b/2x 1b/2y +1c/2x 1c/2y