package main import ( "fmt" "os/exec" "path/filepath" "sort" "strings" ) type goTestTarget struct { label string moduleRoot string args []string } type goTestFailure struct { target string stage string output string } func discoverOrchestratorTestTargets(repoRoot, backendDir string, includeCoreTargets bool) []goTestTarget { if !includeCoreTargets || !samePath(repoRoot, blockNinjaRepoRoot()) || !samePath(backendDir, filepath.Join(repoRoot, "backend")) { return nil } return discoverOrchestratorTestTargetsFromRoot(orchestratorRepoRoot()) } func discoverOrchestratorTestTargetsFromRoot(root string) []goTestTarget { backendDir := filepath.Join(root, "backend") if !fileExists(filepath.Join(backendDir, "go.mod")) { return nil } return []goTestTarget{{ label: "orchestrator/backend", moduleRoot: backendDir, args: []string{"test", "./..."}, }} } func runGoTestTargets(targets []goTestTarget) (completed []string, failures []goTestFailure, err error) { goBin, err := exec.LookPath("go") if err != nil { return nil, nil, fmt.Errorf("go not found in PATH") } return runGoTestTargetsWithBinary(targets, goBin) } func runGoTestTargetsWithBinary(targets []goTestTarget, goBin string) (completed []string, failures []goTestFailure, err error) { for _, target := range targets { args := append([]string{}, target.args...) if len(args) == 0 { args = []string{"test", "./..."} } stage := "go " + strings.Join(args, " ") output, runErr := runCommand(target.moduleRoot, goBin, args...) if runErr != nil { failures = append(failures, goTestFailure{ target: target.label, stage: stage, output: output, }) continue } completed = append(completed, target.label+" ["+stage+"]") } sort.Strings(completed) return completed, failures, nil }