-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Have ParseWebHook
return a event-related "marker" interface
#2462
Comments
Thank you, @hashtagchris . I think I would have to see this to give my opinion. |
Thanks @gmlewis, I'll try to put something together. However I think one of the biggest benefits is the stricter type checking during the build. I'm not sure I can capture that in a test case. Short examplepackage main
import (
"fmt"
"log"
)
func main() {
// no build error - have to use runtime checks to catch this bad arg 👎
LogEvent("Oops, I'm passing a string instead of an event")
// build error 🎉
LogEventUsingProposedType("Oops, I'm passing a string instead of an event")
}
type GitHubEvent interface {
Event()
}
type BranchProtectionRuleEvent struct {
RuleName string
// imagine several more fields relevant to BranchProtectionRuleEvent here
}
func (e *BranchProtectionRuleEvent) Event() {}
func LogEvent(event interface{}) {
switch evt := event.(type) {
case *BranchProtectionRuleEvent:
fmt.Printf("BranchProtectionRule: %s\n", evt.RuleName)
default:
log.Fatalf("Type %T is not a known event type\n", event)
}
}
func LogEventUsingProposedType(event GitHubEvent) {
switch evt := event.(type) {
case *BranchProtectionRuleEvent:
fmt.Printf("BranchProtectionRule: %s\n", evt.RuleName)
default:
log.Fatalf("Type %T is not a known event type\n", event)
}
} |
Ah, I gotcha, @hashtagchris - thank you for the example! So the down-side to this is that we "simply" need to make sure that every event has the magic line If the answer is "yes" (and I think the answer is indeed "yes"), then we could put all these magic lines in a separate auto-generated file with the standard "DO NOT EDIT - See Contributing.md for details", and never have to think about this again, right? If so, then this makes sense to me to do. Obviously, others are welcome to comment with other opinions. If there are no objections, then do you want to put together a PR that implements this, @hashtagchris , or would you like to open this up for one of our other contributors to implement? |
Yup and Yup! I may have time this week to contribute changes. Would you have the generator identify the event structs by iterating over the |
Fantastic! It's yours.
Great question! I'm all for the solution that is easiest to maintain (which usually means "simplest") and the one which seems to be most future-resistant as possible in the hopes that no matter what we do to the code, it will reliably find the events. So I'm leaning toward the former, but am leaving it up to you. We can further comment during the code review. 😁 |
I second this proposal. As a step further, we could group events and provide an higher level API. For example, some of them always have a Sender field. So we have dummy code like: func getSender(eventPayload interface{}) (string, error) {
switch payload := eventPayload.(type) {
case *github.IssueCommentEvent:
return *payload.Sender.Login, nil
case *github.PullRequestEvent:
return *payload.Sender.Login, nil
case *github.PullRequestReviewEvent:
return *payload.Sender.Login, nil
case *github.PullRequestReviewCommentEvent:
return *payload.Sender.Login, nil
case *github.PushEvent:
return *payload.Sender.Login, nil
case *github.ReleaseEvent:
return *payload.Sender.Login, nil
case *github.CheckRunEvent:
return *payload.Sender.Login, nil
case *github.CheckSuiteEvent:
return *payload.Sender.Login, nil
case *github.IssuesEvent:
return *payload.Sender.Login, nil
case *github.ProjectCardEvent:
return *payload.Sender.Login, nil
case *github.ProjectColumnEvent:
return *payload.Sender.Login, nil
case *github.ProjectEvent:
return *payload.Sender.Login, nil
case *github.WatchEvent:
return *payload.Sender.Login, nil
case *github.ForkEvent:
return *payload.Sender.Login, nil
case *github.CreateEvent:
return *payload.Sender.Login, nil
case *github.DeleteEvent:
return *payload.Sender.Login, nil
case *github.PublicEvent:
return *payload.Sender.Login, nil
case *github.GollumEvent:
return *payload.Sender.Login, nil
case *github.TeamEvent:
return *payload.Sender.Login, nil
case *github.TeamAddEvent:
return *payload.Sender.Login, nil
case *github.StatusEvent:
return *payload.Sender.Login, nil
case *github.MembershipEvent:
return *payload.Sender.Login, nil
case *github.LabelEvent:
return *payload.Sender.Login, nil
case *github.MilestoneEvent:
return *payload.Sender.Login, nil
case *github.PageBuildEvent:
return *payload.Sender.Login, nil
}
return "", fmt.Errorf("unknown event type")
} @hashtagchris: I'll try to help out on the draft PR. |
ParseWebHook
currently returns aninterface{}
. I know there's no one method that all webhook events share. But what if we added a "marker" interface and hadParseWebHook
return that type? This would make the return type ofParseWebHook
a little clearer, and allow consumers to use the same interface in their codebase as they pass events throughout.Example:
Exporting the method (
Event()
in the example above) would be useful for tests. Tests could define struct types that implement the same interface, independent of specific webhook types.Related
#1154
The text was updated successfully, but these errors were encountered: