github.com/beauknowssoftware/makehcl@v0.0.0-20200322000747-1b9bb1e1c008/internal/run/bash.go (about)

     1  package run
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"os"
     7  	"os/exec"
     8  )
     9  
    10  type bashOpts struct {
    11  	verbose    bool
    12  	env        map[string]string
    13  	globalEnv  map[string]string
    14  	shell      string
    15  	shellFlags *string
    16  	teeTarget  *string
    17  }
    18  
    19  const (
    20  	defaultShell      = "bash"
    21  	defaultShellFlags = "-c"
    22  )
    23  
    24  func bash(cmd string, opts bashOpts) error {
    25  	if opts.verbose {
    26  		fmt.Println(cmd)
    27  	}
    28  
    29  	shell := opts.shell
    30  	if shell == "" {
    31  		shell = defaultShell
    32  	}
    33  
    34  	shellFlags := opts.shellFlags
    35  	if shellFlags == nil {
    36  		c := defaultShellFlags
    37  		shellFlags = &c
    38  	}
    39  
    40  	var c *exec.Cmd
    41  	if *shellFlags == "" {
    42  		c = exec.Command(shell, cmd)
    43  	} else {
    44  		c = exec.Command(shell, *shellFlags, cmd)
    45  	}
    46  
    47  	c.Env = os.Environ()
    48  
    49  	hd, err := os.UserHomeDir()
    50  	if err != nil {
    51  		return err
    52  	}
    53  
    54  	e := fmt.Sprintf("HOME=%v", hd)
    55  	c.Env = append(c.Env, e)
    56  
    57  	for k, v := range opts.env {
    58  		e := fmt.Sprintf("%v=%v", k, v)
    59  		c.Env = append(c.Env, e)
    60  	}
    61  
    62  	for k, v := range opts.globalEnv {
    63  		e := fmt.Sprintf("%v=%v", k, v)
    64  		c.Env = append(c.Env, e)
    65  	}
    66  
    67  	if opts.teeTarget != nil {
    68  		f, err := os.Create(*opts.teeTarget)
    69  		if err != nil {
    70  			return err
    71  		}
    72  		defer f.Close()
    73  		c.Stdout = io.MultiWriter(f, os.Stdout)
    74  	} else {
    75  		c.Stdout = os.Stdout
    76  	}
    77  
    78  	c.Stderr = os.Stderr
    79  
    80  	return c.Run()
    81  }