corvus-ch/rabbitmq-cli-consumer

View on GitHub
command/builder_pipe.go

Summary

Maintainability
A
0 mins
Test Coverage
A
92%
package command

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "os"
    "os/exec"
    "strings"

    "github.com/bketelsen/logr"
    "github.com/corvus-ch/rabbitmq-cli-consumer/delivery"
)

type PipeBuilder struct {
    Builder
    log          logr.Logger
    outputWriter io.Writer
    errorWriter  io.Writer
    cmd          string
    args         []string
    capture      bool
}

// SetLogger is part of Builder.
func (b *PipeBuilder) SetLogger(l logr.Logger) {
    b.log = l
}

func (b *PipeBuilder) SetOutputWriter(w io.Writer) {
    b.outputWriter = w
}

func (b *PipeBuilder) SetErrorWriter(w io.Writer) {
    b.errorWriter = w
}

func (b *PipeBuilder) SetCommand(cmd string) {
    var args []string

    if split := strings.Split(cmd, " "); len(split) > 1 {
        cmd, args = split[0], split[1:]
    }

    b.cmd = cmd
    b.args = args
}

func (b *PipeBuilder) SetCaptureOutput(capture bool) {
    b.capture = capture
}

func (b *PipeBuilder) GetCommand(p delivery.Properties, d delivery.Info, body []byte) (*exec.Cmd, error) {

    meta, err := json.Marshal(&struct {
        Properties   delivery.Properties `json:"properties"`
        DeliveryInfo delivery.Info       `json:"delivery_info"`
    }{

        Properties:   p,
        DeliveryInfo: d,
    })
    if err != nil {
        return nil, fmt.Errorf("failed to marshall matadata: %v", err)
    }

    r, w, err := os.Pipe()
    if err != nil {
        return nil, fmt.Errorf("failed to create pipe: %v", err)
    }

    cmd := exec.Command(b.cmd, b.args...)

    cmd.Env = os.Environ()
    cmd.Stdin = bytes.NewBuffer(body)
    cmd.ExtraFiles = []*os.File{r}

    if b.capture {
        cmd.Stdout = b.outputWriter
        cmd.Stderr = b.errorWriter
    }

    w.Write(meta)
    w.Close()

    return cmd, nil
}