don't hardcode jobs in fm_driver

This lets us pass a job on the command line,

    go run infra/bots/task_drivers/fm_driver/fm_driver.go out/fm tests b=cpu

or use -script to pass a file or stdin,

    cat << EOF | go run infra/bots/task_drivers/fm_driver/fm_driver.go -script - out/fm
    b=cpu tests
    gms skvm=false b=cpu w=$out/vanilla
    gms skvm=true  b=cpu w=$out/skvm
    #gms skvm=true  b=cpu w=$out/dp3      gamut=p3      tf=srgb
    #gms skvm=true  b=cpu w=$out/linear   gamut=srgb    tf=linear
    #gms skvm=true  b=cpu w=$out/rec2020  gamut=rec2020 tf=rec2020
    EOF

(This CL will make the one FM bot temporarily do nothing,
but the next CL should fix it.)

Change-Id: I1f3badac78a0f61698179c1afec37b3020539fff
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/362216
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
diff --git a/infra/bots/gen_tasks_logic/gen_tasks_logic.go b/infra/bots/gen_tasks_logic/gen_tasks_logic.go
index 4c1d0fc..7c570e6 100644
--- a/infra/bots/gen_tasks_logic/gen_tasks_logic.go
+++ b/infra/bots/gen_tasks_logic/gen_tasks_logic.go
@@ -1393,7 +1393,8 @@
 			"--project_id", "skia-swarming-bots",
 			"--task_id", specs.PLACEHOLDER_TASK_ID,
 			"--task_name", b.Name,
-			"build/fm")
+			"build/fm",
+			"b=cpu gms tests") // TODO(mtklein): a file/stdin instead to use with -script?
 		b.serviceAccount(b.cfg.ServiceAccountCompile)
 		b.swarmDimensions()
 		b.expiration(15 * time.Minute)
diff --git a/infra/bots/task_drivers/fm_driver/fm_driver.go b/infra/bots/task_drivers/fm_driver/fm_driver.go
index 5409ac6..6ef3466 100644
--- a/infra/bots/task_drivers/fm_driver/fm_driver.go
+++ b/infra/bots/task_drivers/fm_driver/fm_driver.go
@@ -35,6 +35,7 @@
 		local     = flag.Bool("local", true, "Running locally (else on the bots)?")
 
 		resources = flag.String("resources", "resources", "Passed to fm -i.")
+		script    = flag.String("script", "", "File (or - for stdin) with one job per line.")
 	)
 	ctx := td.StartRun(projectId, taskId, taskName, output, local)
 	defer td.EndRun(ctx)
@@ -119,23 +120,26 @@
 		return w
 	}
 
-	// TODO: this doesn't have to be hard coded, of course.
-	// TODO: add some .skps or images to demo that.
-	script := `
-	b=cpu tests
-	b=cpu gms
-	b=cpu gms skvm=true
+	// One job can go on the command line, handy for ad hoc local runs.
+	jobs := [][]string{flag.Args()[1:]}
 
-	#b=cpu gms skvm=true gamut=p3
-	#b=cpu gms skvm=true ct=565
-	`
-	jobs := [][]string{}
-	scanner := bufio.NewScanner(strings.NewReader(script))
-	for scanner.Scan() {
-		jobs = append(jobs, strings.Fields(scanner.Text()))
-	}
-	if err := scanner.Err(); err != nil {
-		td.Fatal(ctx, err)
+	// Any number of jobs can come from -script.
+	if *script != "" {
+		file := os.Stdin
+		if *script != "-" {
+			file, err := os.Open(*script)
+			if err != nil {
+				td.Fatal(ctx, err)
+			}
+			defer file.Close()
+		}
+		scanner := bufio.NewScanner(file)
+		for scanner.Scan() {
+			jobs = append(jobs, strings.Fields(scanner.Text()))
+		}
+		if err := scanner.Err(); err != nil {
+			td.Fatal(ctx, err)
+		}
 	}
 
 	// We'll kick off workers to run FM with `-s <Sources...> <Flags...>` from parsed jobs.
diff --git a/infra/bots/tasks.json b/infra/bots/tasks.json
index 6777955..ece587c 100755
--- a/infra/bots/tasks.json
+++ b/infra/bots/tasks.json
@@ -14513,7 +14513,8 @@
         "<(TASK_ID)",
         "--task_name",
         "FM-Debian10-Clang-GCE-CPU-AVX2-x86_64-Debug-All",
-        "build/fm"
+        "build/fm",
+        "b=cpu gms tests"
       ],
       "dependencies": [
         "Build-Debian10-Clang-x86_64-Debug",