github.com/beauknowssoftware/makehcl@v0.0.0-20200322000747-1b9bb1e1c008/internal/functions/shell.go (about) 1 package functions 2 3 import ( 4 "io/ioutil" 5 "os/exec" 6 "strings" 7 8 "github.com/pkg/errors" 9 "github.com/zclconf/go-cty/cty" 10 "github.com/zclconf/go-cty/cty/function" 11 ) 12 13 var ShellSpec = function.Spec{ 14 Params: []function.Parameter{ 15 {Type: cty.String}, 16 }, 17 Type: function.StaticReturnType(cty.DynamicPseudoType), 18 Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { 19 a := args[0].AsString() 20 c := exec.Command("sh", "-c", a) 21 22 outPipe, err := c.StdoutPipe() 23 if err != nil { 24 err = errors.Wrap(err, "failed to create stdout pipe") 25 return cty.UnknownVal(cty.DynamicPseudoType), err 26 } 27 28 errPipe, err := c.StderrPipe() 29 if err != nil { 30 err = errors.Wrap(err, "failed to create stderr pipe") 31 return cty.UnknownVal(cty.DynamicPseudoType), err 32 } 33 34 if err = c.Start(); err != nil { 35 err = errors.Wrap(err, "failed to start") 36 return cty.UnknownVal(cty.DynamicPseudoType), err 37 } 38 39 resBytes, err := ioutil.ReadAll(outPipe) 40 if err != nil { 41 err = errors.Wrap(err, "failed to read stdout") 42 return cty.UnknownVal(cty.DynamicPseudoType), err 43 } 44 45 errBytes, err := ioutil.ReadAll(errPipe) 46 if err != nil { 47 err = errors.Wrap(err, "failed to read stderr") 48 return cty.UnknownVal(cty.DynamicPseudoType), err 49 } 50 51 if err := c.Wait(); err != nil { 52 err = errors.Wrap(err, string(errBytes)) 53 return cty.UnknownVal(cty.DynamicPseudoType), err 54 } 55 56 res := strings.TrimSpace(string(resBytes)) 57 58 return cty.StringVal(res), nil 59 }, 60 }