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