tools cts/roll: Generate cache file list

Will be used by GN to know the outputs of the generate cache step.

Change-Id: Iae09477fb355eac41ff9b2204605f46ed78e08ec
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/110620
Reviewed-by: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/tools/src/cmd/cts/roll/roll.go b/tools/src/cmd/cts/roll/roll.go
index 83ea904..98be378 100644
--- a/tools/src/cmd/cts/roll/roll.go
+++ b/tools/src/cmd/cts/roll/roll.go
@@ -55,6 +55,7 @@
 	depsRelPath          = "DEPS"
 	tsSourcesRelPath     = "third_party/gn/webgpu-cts/ts_sources.txt"
 	testListRelPath      = "third_party/gn/webgpu-cts/test_list.txt"
+	cacheListRelPath     = "third_party/gn/webgpu-cts/cache_list.txt"
 	resourceFilesRelPath = "third_party/gn/webgpu-cts/resource_files.txt"
 	webTestsPath         = "webgpu-cts/webtests"
 	refMain              = "refs/heads/main"
@@ -296,7 +297,7 @@
 
 	// Create a new gerrit change, if needed
 	changeID := ""
-	if len(existingRolls) == 0 {
+	if r.flags.preserve || len(existingRolls) == 0 {
 		msg := r.rollCommitMessage(oldCTSHash, newCTSHash, ctsLog, "")
 		change, err := r.gerrit.CreateChange(r.cfg.Gerrit.Project, "main", msg, true)
 		if err != nil {
@@ -447,9 +448,11 @@
 		msg.WriteString(" commits)")
 	}
 	msg.WriteString("\n\n")
-	msg.WriteString("Update:\n")
+	msg.WriteString("Regenerated:\n")
 	msg.WriteString(" - expectations.txt\n")
 	msg.WriteString(" - ts_sources.txt\n")
+	msg.WriteString(" - test_list.txt\n")
+	msg.WriteString(" - cache_list.txt\n")
 	msg.WriteString(" - resource_files.txt\n")
 	msg.WriteString(" - webtest .html files\n")
 	msg.WriteString("\n\n")
@@ -606,6 +609,7 @@
 // file path to file content for the CTS roll's change. This includes:
 // * type-script source files
 // * CTS test list
+// * CTS cache list
 // * resource file list
 // * webtest file sources
 func (r *roller) generateFiles(ctx context.Context) (map[string]string, error) {
@@ -648,6 +652,7 @@
 	for relPath, generator := range map[string]func(context.Context) (string, error){
 		tsSourcesRelPath:     r.genTSDepList,
 		testListRelPath:      r.genTestList,
+		cacheListRelPath:     r.genCacheList,
 		resourceFilesRelPath: r.genResourceFilesList,
 	} {
 		relPath, generator := relPath, generator // Capture values, not iterators
@@ -762,6 +767,40 @@
 	return strings.Join(tests, "\n"), nil
 }
 
+// genCacheList returns the file list of cached data
+func (r *roller) genCacheList(ctx context.Context) (string, error) {
+	// Run 'src/common/runtime/cmdline.ts' to obtain the full test list
+	cmd := exec.CommandContext(ctx, r.flags.nodePath,
+		"-e", "require('./src/common/tools/setup-ts-in-node.js');require('./src/common/tools/gen_cache.ts');",
+		"--", // Start of arguments
+		// src/common/runtime/helper/sys.ts expects 'node file.js <args>'
+		// and slices away the first two arguments. When running with '-e', args
+		// start at 1, so just inject a placeholder argument.
+		"placeholder-arg",
+		".",
+		"src/webgpu",
+		"--list",
+	)
+	cmd.Dir = r.ctsDir
+
+	stderr := bytes.Buffer{}
+	cmd.Stderr = &stderr
+
+	out, err := cmd.Output()
+	if err != nil {
+		return "", fmt.Errorf("failed to generate cache list: %w\n%v", err, stderr.String())
+	}
+
+	files := []string{}
+	for _, file := range strings.Split(string(out), "\n") {
+		if file != "" {
+			files = append(files, strings.TrimPrefix(file, "./"))
+		}
+	}
+
+	return strings.Join(files, "\n") + "\n", nil
+}
+
 // genResourceFilesList returns a list of resource files, for the CTS checkout at r.ctsDir
 // This list can be used to populate the resource_files.txt file.
 func (r *roller) genResourceFilesList(ctx context.Context) (string, error) {
diff --git a/tools/src/cmd/cts/roll/roll_test.go b/tools/src/cmd/cts/roll/roll_test.go
index 08fc082..a776afc3 100644
--- a/tools/src/cmd/cts/roll/roll_test.go
+++ b/tools/src/cmd/cts/roll/roll_test.go
@@ -58,9 +58,11 @@
 	)
 	expect := `Roll third_party/webgpu-cts/ d5e605a55..29275672e (2 commits)
 
-Update:
+Regenerated:
  - expectations.txt
  - ts_sources.txt
+ - test_list.txt
+ - cache_list.txt
  - resource_files.txt
  - webtest .html files