woodpecker/server/handler/hook.go
Brad Rydzewski 83577a7d5d removed css files. designers will be providing
removed amber files. replacing with angular
removed queue package in favor or worker package
removed channel package in favor of pubsub package
2014-06-21 14:22:38 -07:00

108 lines
2.6 KiB
Go

package handler
import (
"net/http"
"github.com/drone/drone/server/database"
"github.com/drone/drone/server/worker"
"github.com/drone/drone/shared/model"
"github.com/gorilla/pat"
)
type HookHandler struct {
users database.UserManager
repos database.RepoManager
commits database.CommitManager
conf database.ConfigManager
queue chan *worker.Request
}
func NewHookHandler(users database.UserManager, repos database.RepoManager, commits database.CommitManager, conf database.ConfigManager, queue chan *worker.Request) *HookHandler {
return &HookHandler{users, repos, commits, conf, queue}
}
// PostHook receives a post-commit hook from GitHub, Bitbucket, etc
// GET /hook/:host
func (h *HookHandler) PostHook(w http.ResponseWriter, r *http.Request) error {
host := r.FormValue(":host")
// get the remote system's client.
remote := h.conf.Find().GetRemote(host)
if remote == nil {
return notFound{}
}
// parse the hook payload
hook, err := remote.GetHook(r)
if err != nil {
return badRequest{err}
}
// in some cases we have neither a hook nor error. An example
// would be GitHub sending a ping request to the URL, in which
// case we'll just exit quiely with an 'OK'
if hook == nil {
w.WriteHeader(http.StatusOK)
return nil
}
//fmt.Printf("%#v", hook)
// fetch the repository from the database
repo, err := h.repos.FindName(remote.GetHost(), hook.Owner, hook.Repo)
if err != nil {
return notFound{}
}
if repo.Active == false ||
(repo.PostCommit == false && len(hook.PullRequest) == 0) ||
(repo.PullRequest == false && len(hook.PullRequest) != 0) {
w.WriteHeader(http.StatusOK)
return nil
}
// fetch the user from the database that owns this repo
user, err := h.users.Find(repo.UserID)
if err != nil {
return notFound{}
}
// featch the .drone.yml file from the database
client := remote.GetClient(user.Access, user.Secret)
yml, err := client.GetScript(hook)
if err != nil {
return badRequest{err}
}
c := model.Commit{
RepoID: repo.ID,
Status: model.StatusEnqueue,
Sha: hook.Sha,
Branch: hook.Branch,
PullRequest: hook.PullRequest,
Timestamp: hook.Timestamp,
Message: hook.Message,
Config: yml}
c.SetAuthor(hook.Author)
// inser the commit into the database
if err := h.commits.Insert(&c); err != nil {
return badRequest{err}
}
//fmt.Printf("%s", yml)
// drop the items on the queue
go func() {
h.queue <- &worker.Request{
Repo: repo,
Commit: &c,
}
}()
return nil
}
func (h *HookHandler) Register(r *pat.Router) {
r.Post("/v1/hook/{host}", errorHandler(h.PostHook))
r.Put("/v1/hook/{host}", errorHandler(h.PostHook))
}