@@ -4,19 +4,44 @@ package main
44
55import (
66 "bufio"
7+ "encoding/json"
78 "fmt"
9+ "io"
10+ "net/http"
811 "os"
912 "regexp"
10- "strings"
1113 "sort"
14+ "strings"
15+ )
16+
17+ const (
18+ headerKey = "Authorization"
19+ headerVal = "Bearer %s"
20+ projUrl = "https://ci.appveyor.com/api/projects/mpictor/stepcode"
21+ //"https://ci.appveyor.com/api/buildjobs/2rjxdv1rnb8jcg8y/log"
22+ logUrl = "https://ci.appveyor.com/api/buildjobs/%s/log"
1223)
1324
1425//uses stdin and stdout
1526func main () {
16- log := unwrap ()
27+ rawlog , build , err := getLog ()
28+ if err != nil {
29+ fmt .Fprintf (os .Stderr , "ERROR: %s\n " , err )
30+ return
31+ }
32+ defer rawlog .Close ()
33+ log := unwrap (rawlog )
1734 warns , errs := countMessages (log )
18- printMessages ("error" , errs )
19- printMessages ("warning" , warns )
35+ fi , err := os .Create (fmt .Sprintf ("appveyor-%d.smy" , build ))
36+ if err != nil {
37+ fmt .Fprintf (os .Stderr , "ERROR: %s\n " , err )
38+ return
39+ }
40+ printMessages ("error" , errs , fi )
41+ printMessages ("warning" , warns , fi )
42+
43+ fmt .Printf ("done\n " )
44+
2045}
2146
2247/* categorizes warnings and errors based upon the MSVC message number (i.e. C4244)
@@ -28,17 +53,14 @@ func countMessages(log []string) (warns, errs map[string][]string) {
2853 warns = make (map [string ][]string )
2954 errs = make (map [string ][]string )
3055 tstamp := `\[\d\d:\d\d:\d\d\] `
31- fname := " *(.*)" // $1
32- fline := `(?:\((\d+)\)| ): ` // $2 - either line number in parenthesis or a space, followed by a colon
33- msgNr := `([A-Z]+\d+): ` // $3 - C4251, LNK2005, etc
34- msgTxt := `([^\[]*) ` // $4
56+ fname := " *(.*)" // $1
57+ fline := `(?:\((\d+)\)| ): ` // $2 - either line number in parenthesis or a space, followed by a colon
58+ msgNr := `([A-Z]+\d+): ` // $3 - C4251, LNK2005, etc
59+ msgTxt := `([^\[]*) ` // $4
3560 tail := `\[[^\[\]]*\]`
3661 warnRe := regexp .MustCompile (tstamp + fname + fline + `warning ` + msgNr + msgTxt + tail )
3762 errRe := regexp .MustCompile (tstamp + fname + fline + `(?:fatal )?error ` + msgNr + msgTxt + tail )
38- //reScanner := bufio.NewScanner(strings.NewReader(...log))
39- //for reScanner.Scan() {
40- //line := reScanner.Text()
41- for _ ,line := range log {
63+ for _ , line := range log {
4264 if warnRe .MatchString (line ) {
4365 key := warnRe .ReplaceAllString (line , "$3" )
4466 path := strings .ToLower (warnRe .ReplaceAllString (line , "$1:$2" ))
@@ -84,53 +106,116 @@ func countMessages(log []string) (warns, errs map[string][]string) {
84106 return
85107}
86108
87- func printMessages (typ string , m map [string ][]string ) {
109+ func printMessages (typ string , m map [string ][]string , w io. Writer ) {
88110 //sort keys
89111 keys := make ([]string , 0 , len (m ))
90112 for key := range m {
91113 keys = append (keys , key )
92114 }
93115 sort .Strings (keys )
94- //fmt.Println(keys)
95116 for _ , k := range keys {
96117 for i , l := range m [k ] {
97118 //first string is an example, not a location
98119 if i == 0 {
99- fmt .Printf ( "%s %s (i.e. \" %s\" )\n " , typ , k , l )
120+ fmt .Fprintf ( w , "%s %s (i.e. \" %s\" )\n " , typ , k , l )
100121 } else if len (l ) > 1 { //not sure where blank lines are coming from...
101- fmt .Printf ( " >> %s\n " , l )
122+ fmt .Fprintf ( w , " >> %s\n " , l )
102123 }
103124 }
104125 }
105126}
106127
107128//
108- func unwrap () (log []string ) {
129+ func unwrap (r io. Reader ) (log []string ) {
109130 startNewLine := true
110- unwrapScanner := bufio .NewScanner (os . Stdin )
131+ unwrapScanner := bufio .NewScanner (r )
111132 var lineOut string
112133 for unwrapScanner .Scan () {
113134 lastNewline := startNewLine
114135 lineIn := unwrapScanner .Text ()
115- startNewLine = (len (lineIn ) < 240 ) || strings .HasSuffix (lineIn ,"vcxproj]" )
136+ startNewLine = (len (lineIn ) < 240 ) || strings .HasSuffix (lineIn , "vcxproj]" )
116137 if ! lastNewline {
117138 lineOut += lineIn [11 :]
118139 } else {
119140 lineOut = lineIn
120141 }
121142 if startNewLine {
122- log = append (log ,lineOut )
143+ log = append (log , lineOut )
123144 lineOut = ""
124- //log += fmt.Sprintf("\n")
125145 }
126146 }
127147 if len (lineOut ) > 0 {
128- log = append (log ,lineOut )
148+ log = append (log , lineOut )
129149 }
130150 if err := unwrapScanner .Err (); err != nil {
131151 fmt .Fprintln (os .Stderr , "Error reading appveyor log:" , err )
132152 }
133153 return
134154}
135155
156+ //http://json2struct.mervine.net/
157+ type AppVeyorBuild struct {
158+ Build struct {
159+ BuildNumber int `json:"buildNumber"`
160+ Jobs []struct {
161+ JobID string `json:"jobId"`
162+ } `json:"jobs"`
163+ } `json:"build"`
164+ }
165+
166+ func getLog () (log io.ReadCloser , build int , err error ) {
167+ client := & http.Client {}
168+ req , err := http .NewRequest ("GET" , projUrl , nil )
169+ if err != nil {
170+ return
171+ }
172+ apikey := os .Getenv ("APPVEYOR_API_KEY" )
173+ //api key isn't necessary for read-only queries on public projects
174+ //if len(apikey) < 1 {
175+ // fmt.Printf("Env var APPVEYOR_API_KEY is not set.")
176+ //}
177+ req .Header .Add (headerKey , fmt .Sprintf (headerVal ,apikey ))
178+ resp , err := client .Do (req )
179+ if err != nil {
180+ return
181+ }
182+
183+ build , job := decode (resp .Body )
184+ fmt .Printf ("build #%d, jobId %s\n " , build , job )
185+ resp , err = http .Get (fmt .Sprintf (logUrl , job ))
186+ if err != nil {
187+ return
188+ }
189+ logName := fmt .Sprintf ("appveyor-%d.log" , build )
190+ fi , err := os .Create (logName )
191+ if err != nil {
192+ return
193+ }
194+ _ , err = io .Copy (fi , resp .Body )
195+ if err != nil {
196+ return
197+ }
198+ log , err = os .Open (logName )
199+ if err != nil {
200+ log = nil
201+ }
202+ return
203+ }
204+
205+ func decode (r io.Reader ) (num int , job string ) {
206+ dec := json .NewDecoder (r )
207+ var av AppVeyorBuild
208+ err := dec .Decode (& av )
209+ if err != io .EOF && err != nil {
210+ fmt .Printf ("err %s\n " , err )
211+ return
212+ }
213+ if len (av .Build .Jobs ) != 1 {
214+ return
215+ }
216+ num = av .Build .BuildNumber
217+ job = av .Build .Jobs [0 ].JobID
218+ return
219+ }
220+
136221// kate: indent-width 8; space-indent off; replace-tabs off; replace-tabs-save off; replace-trailing-space-save on; remove-trailing-space on; tab-intent on; tab-width 8; show-tabs off;
0 commit comments