@@ -9,55 +9,43 @@ import (
99	"io" 
1010	"io/ioutil" 
1111	"net/http" 
12- 	"path/filepath" 
13- 
14- 	"strings" 
15- 
16- 	"errors" 
1712
1813	"github.com/bivas/rivi/config/client" 
1914	"github.com/bivas/rivi/types" 
2015	"github.com/bivas/rivi/types/builder" 
21- 	"github.com/bivas/rivi/util" 
2216	"github.com/bivas/rivi/util/log" 
2317)
2418
25- var  (
26- 	supportedEventTypes  =  []string {
27- 		"issue_comment" ,
28- 		"pull_request" ,
29- 		"pull_request_review" ,
30- 		"pull_request_review_comment" }
31- )
32- 
3319type  builderContext  struct  {
3420	secret  []byte 
3521	client  * ghClient 
3622	data    * data 
3723}
3824
3925type  dataBuilder  struct  {
40- 	logger  log.Logger 
26+ 	handlers        map [string ]eventHandler 
27+ 	defaultHandler  eventHandler 
28+ 	logger          log.Logger 
4129}
4230
43- func  ( builder   * dataBuilder )  validate (context   * builderContext , payload  []byte , request  * http.Request ) bool  {
44- 	if  len (context . secret ) ==  0  {
31+ func  validate (secret , payload  []byte , request  * http.Request ) bool  {
32+ 	if  len (secret ) ==  0  {
4533		return  true 
4634	}
47- 	h  :=  hmac .New (sha1 .New , context . secret )
35+ 	h  :=  hmac .New (sha1 .New , secret )
4836	h .Write (payload )
4937	result  :=  fmt .Sprintf ("sha1=%s" , hex .EncodeToString (h .Sum (nil )))
5038	return  request .Header .Get ("X-Hub-Signature" ) ==  result 
5139}
5240
53- func  ( builder   * dataBuilder )  readPayload ( context   * builderContext , r  * http.Request ) (* payload , []byte , error ) {
41+ func  ReadPayload ( secret  [] byte , r  * http.Request ) (* payload , []byte , error ) {
5442	body  :=  r .Body 
5543	defer  body .Close ()
5644	raw , err  :=  ioutil .ReadAll (io .LimitReader (body , r .ContentLength ))
5745	if  err  !=  nil  {
5846		return  nil , raw , err 
5947	}
60- 	if  ! builder . validate (context , raw , r ) {
48+ 	if  ! validate (secret , raw , r ) {
6149		return  nil , raw , fmt .Errorf ("Payload could not be validated" )
6250	}
6351	var  pr  payload 
@@ -67,120 +55,41 @@ func (builder *dataBuilder) readPayload(context *builderContext, r *http.Request
6755	return  & pr , raw , nil 
6856}
6957
70- func  (builder  * dataBuilder ) readFromJson (context  * builderContext , payload  * payload ) {
71- 	pr  :=  payload .PullRequest 
72- 	if  pr .Number  >  0  {
73- 		context .data .number  =  pr .Number 
74- 	} else  {
75- 		context .data .number  =  payload .Number 
76- 	}
77- 	context .data .title  =  pr .Title 
78- 	context .data .description  =  pr .Body 
79- 	context .data .changedFiles  =  pr .ChangedFiles 
80- 	context .data .additions  =  pr .Additions 
81- 	context .data .deletions  =  pr .Deletions 
82- 	context .data .ref  =  pr .Base .Ref 
83- 	head  :=  pr .Head 
84- 	context .data .origin  =  types.Origin {
85- 		User :   strings .ToLower (head .User .Login ),
86- 		Repo :   head .Repo .Name ,
87- 		Ref :    head .Ref ,
88- 		Head :   head .Sha [0 :6 ],
89- 		GitURL : head .Repo .GitURL ,
90- 	}
91- 	context .data .state  =  pr .State 
92- }
93- 
94- func  (builder  * dataBuilder ) readFromClient (context  * builderContext ) {
95- 	id  :=  context .data .number 
96- 	context .data .assignees  =  context .client .GetAssignees (id )
97- 	context .data .state  =  context .client .GetState (id )
98- 	context .data .labels  =  context .client .GetLabels (id )
99- 	context .data .comments  =  context .client .GetComments (id )
100- 	fileNames  :=  context .client .GetFileNames (id )
101- 	context .data .fileNames  =  fileNames 
102- 	stringSet  :=  util.StringSet {Transformer : filepath .Ext }
103- 	context .data .fileExt  =  stringSet .AddAll (fileNames ).Values ()
104- 	context .data .reviewers  =  context .client .GetReviewers (id )
105- 	context .data .locked  =  context .client .Locked (id )
106- }
107- 
108- func  (builder  * dataBuilder ) checkProcessState (context  * builderContext ) bool  {
109- 	builder .logger .DebugWith (log.MetaFields {log .F ("issue" , context .data .GetShortName ())},
110- 		"Current state is '%s'" , context .data .state )
111- 	return  context .data .state  !=  "closed" 
58+ func  (builder  * dataBuilder ) findEventHandler (githubEvent  string ) eventHandler  {
59+ 	handler , ok  :=  builder .handlers [githubEvent ]
60+ 	if  ! ok  {
61+ 		builder .logger .DebugWith (log.MetaFields {
62+ 			log .F ("eventType" , githubEvent ),
63+ 		}, "Using default event handler" )
64+ 		handler  =  builder .defaultHandler 
65+ 	}
66+ 	return  handler 
11267}
11368
11469func  (builder  * dataBuilder ) BuildFromHook (config  client.ClientConfig , r  * http.Request ) (types.HookData , bool , error ) {
11570	githubEvent  :=  r .Header .Get ("X-Github-Event" )
116- 	if  githubEvent  ==  "ping"  {
117- 		builder .logger .Info ("Got GitHub 'ping' event" )
118- 		return  nil , false , nil 
119- 	}
120- 	supportedEvent  :=  false 
121- 	for  _ , event  :=  range  supportedEventTypes  {
122- 		if  event  ==  githubEvent  {
123- 			supportedEvent  =  true 
124- 		}
125- 	}
126- 	if  ! supportedEvent  {
127- 		builder .logger .Debug ("Got GitHub '%s' event" , githubEvent )
128- 		return  nil , false , nil 
129- 	}
130- 	context  :=  & builderContext {secret : []byte (config .GetSecret ())}
131- 	pl , raw , err  :=  builder .readPayload (context , r )
132- 	if  err  !=  nil  {
133- 		return  nil , false , err 
134- 	}
135- 	if  pl .Number  ==  0  &&  pl .PullRequest .Number  ==  0  {
136- 		builder .logger .Warning ("Payload appear to have issue id 0" )
137- 		builder .logger .Debug ("Faulty payload %+v" , pl )
138- 		return  nil , false , fmt .Errorf ("Payload appear to have issue id 0" )
139- 	}
140- 	repo  :=  pl .Repository .Name 
141- 	owner  :=  pl .Repository .Owner .Login 
142- 	installation  :=  pl .Installation .ID 
143- 	if  installation  >  0  {
144- 		context .client  =  newAppClient (config , owner , repo , installation )
145- 	} else  {
146- 		context .client  =  newClient (config , owner , repo )
147- 	}
148- 	if  context .client  ==  nil  {
149- 		return  nil , false , errors .New ("Unable to initialize github client" )
150- 	}
151- 	context .data  =  & data {owner : owner , repo : repo , payload : raw , client : context .client }
152- 	builder .readFromJson (context , pl )
153- 	return  context .data , builder .checkProcessState (context ), nil 
71+ 	return  builder .findEventHandler (githubEvent ).FromRequest (config , r )
15472}
15573
156- func  (builder  * dataBuilder ) BuildFromPayload (config  client.ClientConfig , raw  []byte ) (types.Data , bool , error ) {
157- 	var  pl  payload 
158- 	if  e  :=  json .Unmarshal (raw , & pl ); e  !=  nil  {
159- 		return  nil , false , e 
160- 	}
161- 	repo  :=  pl .Repository .Name 
162- 	owner  :=  pl .Repository .Owner .Login 
163- 	installation  :=  pl .Installation .ID 
164- 	context  :=  & builderContext {}
165- 	if  installation  >  0  {
166- 		context .client  =  newAppClient (config , owner , repo , installation )
167- 	} else  {
168- 		context .client  =  newClient (config , owner , repo )
169- 	}
170- 	if  context .client  ==  nil  {
171- 		return  nil , false , errors .New ("Unable to initialize github client" )
172- 	}
173- 	context .data  =  & data {owner : owner , repo : repo , payload : raw , client : context .client }
174- 	builder .readFromJson (context , & pl )
175- 	if  context .data .GetNumber () ==  0  {
176- 		builder .logger .Warning ("Payload appear to have issue id 0" )
177- 		builder .logger .Debug ("Faulty payload %+v" , pl )
178- 		return  nil , false , fmt .Errorf ("Payload appear to have issue id 0" )
179- 	}
180- 	builder .readFromClient (context )
181- 	return  context .data , builder .checkProcessState (context ), nil 
74+ func  (builder  * dataBuilder ) BuildFromPayload (config  client.ClientConfig , ofType  string , raw  []byte ) (types.Data , bool , error ) {
75+ 	return  builder .findEventHandler (ofType ).FromPayload (config , raw )
18276}
18377
78+ var  DataBuilder  dataBuilder 
79+ 
18480func  init () {
185- 	builder .RegisterNewDataBuilder ("github" , & dataBuilder {logger : log .Get ("GitHub.DataBuilder" )})
81+ 	logger  :=  log .Get ("GitHub.DataBuilder" )
82+ 	prHandler  :=  & pullRequestEventHandler {
83+ 		logger : logger .Get ("PullRequestHandler" ),
84+ 	}
85+ 	DataBuilder  =  dataBuilder {
86+ 		logger : logger ,
87+ 		handlers : map [string ]eventHandler {
88+ 			"pull_request" :                prHandler ,
89+ 			"pull_request_review" :         prHandler ,
90+ 			"pull_request_review_comment" : prHandler ,
91+ 		},
92+ 		defaultHandler : defaultHandler ,
93+ 	}
94+ 	builder .RegisterNewDataBuilder ("github" , & DataBuilder )
18695}
0 commit comments