package handler import ( "net/http" "time" "github.com/drone/drone/server/resource/build" "github.com/drone/drone/server/resource/commit" "github.com/drone/drone/server/resource/repo" "github.com/gorilla/pat" ) // badges that indicate the current build status for a repository // and branch combination. var ( badgeSuccess = []byte(`buildbuildsuccesssuccess`) badgeFailure = []byte(`buildbuildfailurefailure`) badgeStarted = []byte(`buildbuildstartedstarted`) badgeError = []byte(`buildbuilderrorerror`) badgeNone = []byte(`buildbuildnonenone`) ) type BadgeHandler struct { commits commit.CommitManager repos repo.RepoManager } func NewBadgeHandler(repos repo.RepoManager, commits commit.CommitManager) *BadgeHandler { return &BadgeHandler{commits, repos} } // GetStatus gets the build status badge. // GET /v1/badge/:host/:owner/:name/status.svg func (h *BadgeHandler) GetStatus(w http.ResponseWriter, r *http.Request) error { host, owner, name := parseRepo(r) branch := r.FormValue("branch") // github has insanely aggressive caching so we'll set almost // every parameter possible to try to prevent caching. w.Header().Set("Content-Type", "image/svg+xml") w.Header().Add("Cache-Control", "no-cache") w.Header().Add("Cache-Control", "no-store") w.Header().Add("Cache-Control", "max-age=0") w.Header().Add("Cache-Control", "must-revalidate") w.Header().Add("Cache-Control", "value") w.Header().Set("Last-Modified", time.Now().UTC().Format(http.TimeFormat)) w.Header().Set("Expires", "Thu, 01 Jan 1970 00:00:00 GMT") // get the repository from the database arepo, err := h.repos.FindName(host, owner, name) if err != nil { w.Write(badgeNone) return nil } // if no branch, use the default if len(branch) == 0 { branch = repo.DefaultBranch } // get the latest commit commit, _ := h.commits.FindLatest(arepo.ID, branch) // if no commit was found then display // the 'none' badge if commit == nil { w.Write(badgeNone) return nil } // determine which badge to load switch commit.Status { case build.StatusSuccess: w.Write(badgeSuccess) case build.StatusFailure: w.Write(badgeFailure) case build.StatusError: w.Write(badgeError) case build.StatusEnqueue, build.StatusStarted: w.Write(badgeStarted) default: w.Write(badgeNone) } return nil } // GetCoverage gets the build status badge. // GET /v1/badges/:host/:owner/:name/coverage.svg func (h *BadgeHandler) GetCoverage(w http.ResponseWriter, r *http.Request) error { return notImplemented{} } func (h *BadgeHandler) GetCC(w http.ResponseWriter, r *http.Request) error { return notImplemented{} } func (h *BadgeHandler) Register(r *pat.Router) { r.Get("/v1/badge/{host}/{owner}/{name}/coverage.svg", errorHandler(h.GetCoverage)) r.Get("/v1/badge/{host}/{owner}/{name}/status.svg", errorHandler(h.GetStatus)) r.Get("/v1/badge/{host}/{owner}/{name}/cc.xml", errorHandler(h.GetCC)) }