github.com/bilus/oya@v0.0.3-0.20190301162104-da4acbd394c6/pkg/task/script.go (about)

     1  package task
     2  
     3  import (
     4  	"io"
     5  	"io/ioutil"
     6  	corelog "log"
     7  	"os"
     8  	"strings"
     9  
    10  	"github.com/bilus/oya/pkg/template"
    11  	"github.com/magefile/mage/sh"
    12  	"github.com/pkg/errors"
    13  )
    14  
    15  type Script struct {
    16  	Script string
    17  	Shell  string
    18  	Scope  *template.Scope
    19  }
    20  
    21  func (s Script) Exec(workDir string, values template.Scope, stdout, stderr io.Writer) error {
    22  	scope := values.Merge(*s.Scope)
    23  
    24  	scriptFile, err := ioutil.TempFile("", "oya-script-")
    25  	if err != nil {
    26  		return err
    27  	}
    28  	defer os.Remove(scriptFile.Name())
    29  	scriptTpl, err := template.Parse(s.Script)
    30  	if err != nil {
    31  		return errors.Wrapf(err, "error running script")
    32  	}
    33  	err = scriptTpl.Render(scriptFile, scope)
    34  	if err != nil {
    35  		_ = scriptFile.Close()
    36  		return err
    37  	}
    38  	err = scriptFile.Close()
    39  	if err != nil {
    40  		return err
    41  	}
    42  
    43  	oldCwd, err := os.Getwd()
    44  	if err != nil {
    45  		return err
    46  	}
    47  	defer os.Chdir(oldCwd)
    48  	err = os.Chdir(workDir)
    49  	if err != nil {
    50  		return err
    51  	}
    52  	corelog.SetOutput(ioutil.Discard) // BUG(bilus): Suppress logging from the library. This prevents using standard logger anywhere else.
    53  
    54  	_, err = sh.Exec(env(), stdout, stderr, s.Shell, scriptFile.Name())
    55  	return err
    56  }
    57  
    58  func env() map[string]string {
    59  	env := make(map[string]string)
    60  	for _, v := range os.Environ() {
    61  		parts := strings.SplitN(v, "=", 2)
    62  		switch len(parts) {
    63  		case 1:
    64  			env[parts[0]] = ""
    65  		case 2:
    66  			env[parts[0]] = parts[1]
    67  		}
    68  	}
    69  	return env
    70  }