Skip to content

Shell-script-like experience in Go. A fork of https://github.com/go-pipe/pipe with a few enhancements

License

Notifications You must be signed in to change notification settings

variantdev/pipe

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pipe

Actions Status

pipe is a fork of the awesome go-pipe with a few enhancements:

  • Support for Go modules
  • Support for Go context.Context for timeout, cancellation and deadline
  • Tested compatibility with macOS(ore more concretely unit tests to ensure it's working on macOS)
  • Exec logger for recording executed commands and context propagation for e.g. tracing and metering (See the OpenTelemetry example)

Usage

// `p` is basically the following shell script rewritten in Go:
//
// #!/usr/bin/env sh
// PIPE_NEW_VAR=new
// echo $PIPE_OLD_VAR $PIPE_NEW_VAR
// PIPE_NEW_VAR=after
// go run a-go-app-prints-PIPE_NEW_VAR
// echo hello | sed s/l/k/g
//
p := pipe.Script(
    pipe.SetEnvVar("PIPE_NEW_VAR", "new"),
    pipe.System("echo $PIPE_OLD_VAR $PIPE_NEW_VAR"),
    pipe.SetEnvVar("PIPE_NEW_VAR", "after"),
    func(s *pipe.State) error {
        count := 0
        prefix := "PIPE_NEW_VAR="
        for _, kv := range s.Env {
            if strings.HasPrefix(kv, prefix) {
                count++
            }
        }
        if count != 1 {
            return fmt.Errorf("found %d environment variables", count)
        }
        return nil
    },
     pipe.Line(
        pipe.Print("hello"),
        pipe.Exec("sed", "s/l/k/g")
    )
)

// output contains everything written to stdout by running the script
output, err := pipe.Output(p)

// combimed contains everything written to stdout and stderr by running the script
combined, err := pipe.CombinedOutput(p)

// errs contains everything written to stderr by running the script
output, errs, err := pipe.DividedOutput(p))

// Cancellation with low-level API
started := time.Now()
s := pipe.NewState(nil, nil)

if err := s(p); err != nil {
  // when the script failed to initialize
}

ch := make(chan error)
go func() {
    ch <- s.RunTasks()
}()
time.Sleep(100 * time.Millisecond)
s.Kill()

err := <-ch

if err.Error() == "explicitly killed" {
  // When the script 
} else {
  // When the script succeeded
}

// context.Context support
started := time.Now()
// ctx, cancel := context.WithDeadline(context.Background(), ...)
// ctx, cancel := context.WithCancel(context.Background())
ctx, cancel := context.WithTimeout(context.Background(), 100 * time.Millisecond)
s := pipe.NewState(nil, nil)

if err := s(p); err != nil {
  // when the script failed to initialize
}

ch := make(chan error)
go func() {
    ch <- s.Run(ctx)
}()

// `cancel()` to cancel

// If not `cancel()`ed, this may be an `explicitly killed` error due to the timeout
err := <-ch

if err.Error() == "context canceled" {
  // The script is cancelled
} else if err.Error() == "context deadline exceeded" 
  // The script is timed out
} else {
  // The script succeeded
}

See gopkg.in/pipe.v2 for the upstream documentation and usage details.

Why you'd want to choose this over go-pipe?

go-pipe seemed the best option above all the options existed at the time of writing this, but it lacked the following things I wanted:

  • Support for Go modules
  • Support for Go context.Context for timeout, cancellation and deadline
  • Tested compatibility with macOS(ore more concretely unit tests to ensure it's working on macOS)
  • Exec logger for recording executed commands and context propagation for e.g. tracing and metering (See the OpenTelemetry example)

This project just adds them without (mostly) keeping the same API as go-pipe. I'm very eager to submit pull requests to go-pipe/pipe if it makes sense but until then I'll use this as a better alternative to go-pipe for my specific use-cases.

Alternatives

For shell scripting in Go, and more concretely "replacing bash scripts with Go apps", I've considered following alternatives.

About

Shell-script-like experience in Go. A fork of https://github.com/go-pipe/pipe with a few enhancements

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

 

Packages

No packages published