github.com/mhlo/force@v0.22.28-0.20150915022417-6d05ecfb0b47/partner.go (about) 1 package main 2 3 import ( 4 "encoding/xml" 5 "errors" 6 "fmt" 7 "strings" 8 ) 9 10 type ForcePartner struct { 11 Force *Force 12 } 13 14 type TestCoverage struct { 15 Log string `xml:"Header>DebuggingInfo>debugLog"` 16 NumberRun int `xml:"Body>runTestsResponse>result>numTestsRun"` 17 NumberLocations []int `xml:"Body>runTestsResponse>result>codeCoverage>numLocations"` 18 NumberLocationsNotCovered []int `xml:"Body>runTestsResponse>result>codeCoverage>numLocationsNotCovered"` 19 Name []string `xml:"Body>runTestsResponse>result>codeCoverage>name"` 20 SMethodNames []string `xml:"Body>runTestsResponse>result>successes>methodName"` 21 SClassNames []string `xml:"Body>runTestsResponse>result>successes>name"` 22 FMethodNames []string `xml:"Body>runTestsResponse>result>failures>methodName"` 23 FClassNames []string `xml:"Body>runTestsResponse>result>failures>name"` 24 FMessage []string `xml:"Body>runTestsResponse>result>failures>message"` 25 FStackTrace []string `xml:"Body>runTestsResponse>result>failures>stackTrace"` 26 } 27 28 func NewForcePartner(force *Force) (partner *ForcePartner) { 29 partner = &ForcePartner{Force: force} 30 return 31 } 32 33 func (partner *ForcePartner) CheckStatus(id string) (err error) { 34 body, err := partner.soapExecute("checkStatus", fmt.Sprintf("<id>%s</id>", id)) 35 if err != nil { 36 return 37 } 38 var status struct { 39 Done bool `xml:"Body>checkStatusResponse>result>done"` 40 State string `xml:"Body>checkStatusResponse>result>state"` 41 Message string `xml:"Body>checkStatusResponse>result>message"` 42 } 43 if err = xml.Unmarshal(body, &status); err != nil { 44 return 45 } 46 switch { 47 case !status.Done: 48 return partner.CheckStatus(id) 49 case status.State == "Error": 50 return errors.New(status.Message) 51 } 52 return 53 } 54 55 func (partner *ForcePartner) ExecuteAnonymous(apex string) (output string, err error) { 56 soap := "<apexcode><![CDATA[%s]]></apexcode>" 57 body, err := partner.soapExecute("executeAnonymous", fmt.Sprintf(soap, apex)) 58 if err != nil { 59 return 60 } 61 var result struct { 62 Compiled bool `xml:"Body>executeAnonymousResponse>result>compiled"` 63 CompileProblem string `xml:"Body>executeAnonymousResponse>result>compileProblem"` 64 ExceptionMessage string `xml:"Body>executeAnonymousResponse>result>exceptionMessage"` 65 ExceptionTrace string `xml:"Body>executeAnonymousResponse>result>exceptionStackTrace"` 66 Log string `xml:"Header>DebuggingInfo>debugLog"` 67 Success bool `xml:"Body>executeAnonymousResponse>result>success"` 68 } 69 if err = xml.Unmarshal(body, &result); err != nil { 70 return 71 } 72 if !result.Compiled { 73 message := strings.Replace(result.CompileProblem, "%", "%%", -1) 74 err = errors.New(message) 75 return 76 } 77 output = result.Log 78 return 79 } 80 81 func (partner *ForcePartner) soapExecuteCore(action, query string) (response []byte, err error) { 82 login, err := partner.Force.Get(partner.Force.Credentials.Id) 83 if err != nil { 84 return 85 } 86 version := strings.Replace(apiVersion, "v", "", 1) 87 url := strings.Replace(login["urls"].(map[string]interface{})["partner"].(string), "{version}", version, 1) 88 //url = strings.Replace(url, "/u/", "/s/", 1) // seems dirty 89 soap := NewSoap(url, "urn:partner.soap.sforce.com", partner.Force.Credentials.AccessToken) 90 soap.Header = "<apex:DebuggingHeader><apex:debugLevel>DEBUGONLY</apex:debugLevel></apex:DebuggingHeader>" 91 response, err = soap.Execute(action, query) 92 return 93 } 94 95 func (partner *ForcePartner) RunTests(tests []string, namespace string) (output TestCoverage, err error) { 96 soap := "<RunTestsRequest>\n" 97 if strings.EqualFold(tests[0], "all") { 98 soap += "<allTests>True</allTests>\n" 99 } else { 100 for _, element := range tests { 101 soap += "<classes>" + element + "</classes>\n" 102 } 103 } 104 if namespace != "" { 105 soap += "<namespace>" + namespace + "</namespace>\n" 106 } 107 soap += "</RunTestsRequest>" 108 body, err := partner.soapExecute("runTests", soap) 109 if err != nil { 110 return 111 } 112 var result TestCoverage 113 if err = xml.Unmarshal(body, &result); err != nil { 114 return 115 } 116 output = result 117 return 118 } 119 120 func (partner *ForcePartner) soapExecute(action, query string) (response []byte, err error) { 121 login, err := partner.Force.Get(partner.Force.Credentials.Id) 122 if err != nil { 123 return 124 } 125 version := strings.Replace(apiVersion, "v", "", 1) 126 url := strings.Replace(login["urls"].(map[string]interface{})["partner"].(string), "{version}", version, 1) 127 url = strings.Replace(url, "/u/", "/s/", 1) // seems dirty 128 soap := NewSoap(url, "http://soap.sforce.com/2006/08/apex", partner.Force.Credentials.AccessToken) 129 soap.Header = "<apex:DebuggingHeader><apex:debugLevel>DEBUGONLY</apex:debugLevel></apex:DebuggingHeader>" 130 response, err = soap.Execute(action, query) 131 return 132 }