diff --git a/internal/runner/go.go b/internal/runner/go.go new file mode 100644 index 00000000..fbacb1af --- /dev/null +++ b/internal/runner/go.go @@ -0,0 +1,17 @@ +package runner + +import "github.com/buildkite/test-splitter/internal/api" + +type GoTests struct{} + +func (GoTests) FindFiles() ([]string, error) { + return nil, nil +} + +func (GoTests) Run(testCases []string) error { + return nil +} + +func (GoTests) Report([]api.TestCase) { + +} diff --git a/internal/runner/rspec.go b/internal/runner/rspec.go index afb12a1a..68b577cb 100644 --- a/internal/runner/rspec.go +++ b/internal/runner/rspec.go @@ -1,22 +1,22 @@ package runner import ( + "errors" "fmt" - "log" "math" "os" "os/exec" "path/filepath" "strings" + "syscall" "time" "github.com/buildkite/test-splitter/internal/api" ) -type Rspec struct { -} +type Rspec struct{} -func (Rspec) GetFiles() []string { +func (Rspec) FindFiles() ([]string, error) { var files []string // Use filepath.Walk to traverse the directory recursively @@ -34,24 +34,39 @@ func (Rspec) GetFiles() []string { // Handle potential error from filepath.Walk if err != nil { - log.Fatal("Error when getting files: ", err) + return nil, fmt.Errorf("walking to find files: %w", err) } - return files + return files, nil } -func (Rspec) Run(testCases []string) error { +func (r Rspec) Run(testCases []string) error { args := []string{"--options", ".rspec.ci"} args = append(args, testCases...) + // TODO: Figure out in advance whether we'll hit ARG_MAX and make args + // an appropriate size + fmt.Println("+++ :test-analytics: Executing tests 🏃") fmt.Println("bin/rspec", strings.Join(args, " ")) cmd := exec.Command("bin/rspec", args...) cmd.Stderr = os.Stderr cmd.Stdout = os.Stdout - return cmd.Run() + + err := cmd.Run() + if errors.Is(err, syscall.E2BIG) { // Will this work on e.g. Windows? + n := len(testCases) / 2 + if err := r.Run(testCases[:n]); err != nil { + return err + } + if err := r.Run(testCases[n:]); err != nil { + return err + } + return nil + } + return err } type RspecExample struct { diff --git a/main.go b/main.go index 0800bd1c..b5061721 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ package main import ( "encoding/json" + "flag" "fmt" "log" @@ -22,12 +23,32 @@ type RspecData struct { } func main() { - // TODO: detect test runner and use appropriate runner - testRunner := runner.Rspec{} + testType := flag.String("type", "rspec", "Test `framework` to be run [rspec, go]") + flag.Parse() + + var testRunner interface { + FindFiles() ([]string, error) + Run([]string) error + Report([]api.TestCase) + } + + switch *testType { + case "rspec": + testRunner = runner.Rspec{} + + case "go": + testRunner = runner.GoTests{} + + default: + log.Fatalf("Unsupported test type %q", *testType) + } // get files fmt.Println("--- :test-analytics: Gathering test plan context and creating test plan request 🐿️") - files := testRunner.GetFiles() + files, err := testRunner.FindFiles() + if err != nil { + log.Fatalf("Couldn't find test files: %v", err) + } fmt.Printf("Found %d files\n", len(files)) // fetch env vars