github.com/joselitofilho/goreleaser@v0.155.1-0.20210123221854-e4891856c593/internal/exec/exec_mock.go (about)

     1  package exec
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"os"
     7  	"reflect"
     8  	"strings"
     9  )
    10  
    11  // nolint: gochecknoglobals
    12  var (
    13  	MockEnvVar = "GORELEASER_MOCK_DATA"
    14  	MockCmd    = os.Args[0]
    15  )
    16  
    17  type MockData struct {
    18  	AnyOf []MockCall `json:"any_of,omitempty"`
    19  }
    20  
    21  type MockCall struct {
    22  	Stdout       string   `json:"stdout,omitempty"`
    23  	Stderr       string   `json:"stderr,omitempty"`
    24  	ExpectedArgs []string `json:"args"`
    25  	ExpectedEnv  []string `json:"env"`
    26  	ExitCode     int      `json:"exit_code"`
    27  }
    28  
    29  func (m *MockData) MarshalJSON() ([]byte, error) {
    30  	type t MockData
    31  	return json.Marshal((*t)(m))
    32  }
    33  
    34  func (m *MockData) UnmarshalJSON(b []byte) error {
    35  	type t MockData
    36  	return json.Unmarshal(b, (*t)(m))
    37  }
    38  
    39  // nolint: interfacer
    40  func MarshalMockEnv(data *MockData) string {
    41  	b, err := data.MarshalJSON()
    42  	if err != nil {
    43  		errData := &MockData{
    44  			AnyOf: []MockCall{
    45  				{
    46  					Stderr:   fmt.Sprintf("unable to marshal mock data: %s", err),
    47  					ExitCode: 1,
    48  				},
    49  			},
    50  		}
    51  		b, _ = errData.MarshalJSON()
    52  	}
    53  
    54  	return MockEnvVar + "=" + string(b)
    55  }
    56  
    57  func ExecuteMockData(jsonData string) int {
    58  	md := &MockData{}
    59  	err := md.UnmarshalJSON([]byte(jsonData))
    60  	if err != nil {
    61  		fmt.Fprintf(os.Stderr, "unable to unmarshal mock data: %s", err)
    62  		return 1
    63  	}
    64  
    65  	givenArgs := os.Args[1:]
    66  	givenEnv := filterEnv(os.Environ())
    67  
    68  	if len(md.AnyOf) == 0 {
    69  		fmt.Fprintf(os.Stderr, "no mock calls expected. args: %q, env: %q",
    70  			givenArgs, givenEnv)
    71  		return 1
    72  	}
    73  
    74  	for _, item := range md.AnyOf {
    75  		if item.ExpectedArgs == nil {
    76  			item.ExpectedArgs = []string{}
    77  		}
    78  		if item.ExpectedEnv == nil {
    79  			item.ExpectedEnv = []string{}
    80  		}
    81  
    82  		if reflect.DeepEqual(item.ExpectedArgs, givenArgs) &&
    83  			reflect.DeepEqual(item.ExpectedEnv, givenEnv) {
    84  			fmt.Fprint(os.Stdout, item.Stdout)
    85  			fmt.Fprint(os.Stderr, item.Stderr)
    86  
    87  			return item.ExitCode
    88  		}
    89  	}
    90  
    91  	fmt.Fprintf(os.Stderr, "no mock calls matched. args: %q, env: %q",
    92  		givenArgs, givenEnv)
    93  	return 1
    94  }
    95  
    96  func filterEnv(vars []string) []string {
    97  	for i, env := range vars {
    98  		if strings.HasPrefix(env, MockEnvVar+"=") {
    99  			return append(vars[:i], vars[i+1:]...)
   100  		}
   101  	}
   102  
   103  	return vars
   104  }