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 }