snapshot of https://github.com/ThreeDotsLabs/watermill.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
master / ci (push) Failing after 0s

This commit is contained in:
upstream-mirror
2026-09-15 21:27:46 +05:00
commit ce933d1277
538 changed files with 46504 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
module github.com/ThreeDotsLabs/watermill/dev/validate-examples
go 1.25.0
require (
github.com/fatih/color v1.19.0
gopkg.in/yaml.v2 v2.4.0
)
require (
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.22 // indirect
golang.org/x/sys v0.44.0 // indirect
)

View File

@@ -0,0 +1,12 @@
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4=
github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

View File

@@ -0,0 +1,177 @@
package main
import (
"bufio"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"time"
"github.com/fatih/color"
yaml "gopkg.in/yaml.v2"
)
type Config struct {
ValidationCmd string `yaml:"validation_cmd"`
TeardownCmd string `yaml:"teardown_cmd"`
Timeout int `yaml:"timeout"`
ExpectedOutput string `yaml:"expected_output"`
ExpectedOutputs []string `yaml:"expected_outputs"`
}
func (c *Config) LoadFrom(path string) error {
file, err := os.ReadFile(path)
if err != nil {
return err
}
err = yaml.Unmarshal(file, c)
if err != nil {
return err
}
return nil
}
func main() {
path := "../../_examples/"
if len(os.Args) > 1 {
path = filepath.Join(path, os.Args[1])
}
walkErr := filepath.Walk(path, func(exampleConfig string, f os.FileInfo, _ error) error {
if f == nil {
return nil
}
matches, err := filepath.Match(".validate_example*.yml", f.Name())
if err != nil {
return fmt.Errorf("could not match file, err: %w", err)
}
if !matches {
return nil
}
exampleDirectory := filepath.Dir(exampleConfig)
fmt.Printf("validating %s\n", exampleDirectory)
err = validate(exampleConfig)
if err != nil {
return fmt.Errorf("validation for %s failed, err: %v", exampleDirectory, err)
}
return nil
})
if walkErr != nil {
panic(walkErr)
}
}
func validate(path string) error {
config := &Config{}
err := config.LoadFrom(path)
if err != nil {
return fmt.Errorf("could not load config, err: %v", err)
}
dirName := filepath.Base(filepath.Dir(path))
expectedOutputs := config.ExpectedOutputs
if config.ExpectedOutput != "" {
expectedOutputs = append(expectedOutputs, config.ExpectedOutput)
}
fmt.Print("\n\n")
fmt.Println("Validating example:", dirName)
fmt.Println("Waiting for output: ", color.GreenString(fmt.Sprintf("%+q", expectedOutputs)))
cmdAndArgs := strings.Fields(config.ValidationCmd)
validationCmd := exec.Command(cmdAndArgs[0], cmdAndArgs[1:]...)
validationCmd.Dir = filepath.Dir(path)
defer func() {
if config.TeardownCmd == "" {
return
}
cmdAndArgs := strings.Fields(config.TeardownCmd)
teardownCmd := exec.Command(cmdAndArgs[0], cmdAndArgs[1:]...)
teardownCmd.Dir = filepath.Dir(path)
_ = teardownCmd.Run()
}()
stdout, err := validationCmd.StdoutPipe()
if err != nil {
return fmt.Errorf("could not attach to stdout, err: %v", err)
}
stderr, err := validationCmd.StderrPipe()
if err != nil {
return fmt.Errorf("could not attach to stderr, err: %v", err)
}
fmt.Printf("running: %v\n", validationCmd.Args)
err = validationCmd.Start()
if err != nil {
return fmt.Errorf("could not start validation, err: %v", err)
}
defer func() {
err := validationCmd.Process.Kill()
if err != nil {
fmt.Printf("could not kill process in %s, err: %v\n", dirName, err)
}
}()
success := make(chan bool)
lines := make(chan string)
go readLines(stdout, lines)
go readLines(stderr, lines)
outputsFound := map[int]struct{}{}
go func() {
for line := range lines {
fmt.Printf("[%s] > %s\n", color.CyanString(dirName), line)
for num, output := range expectedOutputs {
ok, _ := regexp.MatchString(output, line)
if ok {
outputsFound[num] = struct{}{}
}
}
if len(outputsFound) == len(expectedOutputs) {
success <- true
return
}
}
}()
select {
case <-success:
return nil
case <-time.After(time.Duration(config.Timeout) * time.Second):
return fmt.Errorf("validation command timed out")
}
}
func readLines(reader io.Reader, output chan<- string) {
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
if scanner.Err() != nil {
if scanner.Err() == io.EOF {
return
}
continue
}
line := scanner.Text()
output <- line
}
}