github.com/unclejack/drone@v0.2.1-0.20140918182345-831b034aa33b/pkg/handler/commits.go (about) 1 package handler 2 3 import ( 4 "fmt" 5 "net/http" 6 "time" 7 8 "github.com/drone/drone/pkg/channel" 9 "github.com/drone/drone/pkg/database" 10 . "github.com/drone/drone/pkg/model" 11 "github.com/drone/drone/pkg/queue" 12 ) 13 14 // Display a specific Commit. 15 func CommitShow(w http.ResponseWriter, r *http.Request, u *User, repo *Repo) error { 16 branch := r.FormValue("branch") 17 if branch == "" { 18 branch = "master" 19 } 20 21 hash := r.FormValue(":commit") 22 labl := r.FormValue(":label") 23 24 // get the commit from the database 25 commit, err := database.GetCommitBranchHash(branch, hash, repo.ID) 26 if err != nil { 27 return err 28 } 29 30 // get the builds from the database. a commit can have 31 // multiple sub-builds (or matrix builds) 32 builds, err := database.ListBuilds(commit.ID) 33 if err != nil { 34 return err 35 } 36 37 admin, err := database.IsRepoAdmin(u, repo) 38 if err != nil { 39 return err 40 } 41 42 data := struct { 43 User *User 44 Repo *Repo 45 Commit *Commit 46 Build *Build 47 Builds []*Build 48 Token string 49 IsAdmin bool 50 }{u, repo, commit, builds[0], builds, "", admin} 51 52 // get the specific build requested by the user. instead 53 // of a database round trip, we can just loop through the 54 // list and extract the requested build. 55 for _, b := range builds { 56 if b.Slug == labl { 57 data.Build = b 58 break 59 } 60 } 61 62 // generate a token to connect with the websocket 63 // handler and stream output, if the build is running. 64 data.Token = channel.Token(fmt.Sprintf( 65 "%s/%s/%s/commit/%s/%s/builds/%s", repo.Host, repo.Owner, repo.Name, commit.Branch, commit.Hash, builds[0].Slug)) 66 67 // render the repository template. 68 return RenderTemplate(w, "repo_commit.html", &data) 69 } 70 71 // Helper method for saving a failed build or commit in the case where it never starts to build. 72 // This can happen if the yaml is bad or doesn't exist. 73 func saveFailedBuild(commit *Commit, msg string) error { 74 75 // Set the commit to failed 76 commit.Status = "Failure" 77 commit.Created = time.Now().UTC() 78 commit.Finished = commit.Created 79 commit.Duration = 0 80 if err := database.SaveCommit(commit); err != nil { 81 return err 82 } 83 84 // save the build to the database 85 build := &Build{} 86 build.Slug = "1" // TODO: This should not be hardcoded 87 build.CommitID = commit.ID 88 build.Created = time.Now().UTC() 89 build.Finished = build.Created 90 commit.Duration = 0 91 build.Status = "Failure" 92 build.Stdout = msg 93 if err := database.SaveBuild(build); err != nil { 94 return err 95 } 96 97 // TODO: Should the status be Error instead of Failure? 98 99 // TODO: Do we need to update the branch table too? 100 101 return nil 102 103 } 104 105 type CommitRebuildHandler struct { 106 queue *queue.Queue 107 } 108 109 func NewCommitRebuildHandler(queue *queue.Queue) *CommitRebuildHandler { 110 return &CommitRebuildHandler{ 111 queue: queue, 112 } 113 } 114 115 // CommitRebuild re-queues a previously built commit. It finds the existing 116 // commit and build and injects them back into the queue. If the commit 117 // doesn't exist or has no builds, or if a build label has been passed but 118 // can't be located, it prints an error. Otherwise, it adds the build/commit 119 // to the queue and redirects back to the commit page. 120 func (h *CommitRebuildHandler) CommitRebuild(w http.ResponseWriter, r *http.Request, u *User, repo *Repo) error { 121 hash := r.FormValue(":commit") 122 labl := r.FormValue(":label") 123 host := r.FormValue(":host") 124 branch := r.FormValue("branch") 125 if branch == "" { 126 branch = "master" 127 } 128 129 // get the commit from the database 130 commit, err := database.GetCommitBranchHash(branch, hash, repo.ID) 131 if err != nil { 132 return err 133 } 134 135 // get the builds from the database. a commit can have 136 // multiple sub-builds (or matrix builds) 137 builds, err := database.ListBuilds(commit.ID) 138 if err != nil { 139 return err 140 } 141 142 build := builds[0] 143 144 if labl != "" { 145 // get the specific build requested by the user. instead 146 // of a database round trip, we can just loop through the 147 // list and extract the requested build. 148 build = nil 149 for _, b := range builds { 150 if b.Slug == labl { 151 build = b 152 break 153 } 154 } 155 } 156 157 if build == nil { 158 return fmt.Errorf("Could not find build: %s", labl) 159 } 160 161 h.queue.Add(&queue.BuildTask{Repo: repo, Commit: commit, Build: build}) 162 163 if labl != "" { 164 http.Redirect(w, r, fmt.Sprintf("/%s/%s/%s/commit/%s/build/%s?branch=%s", host, repo.Owner, repo.Name, hash, labl, branch), http.StatusSeeOther) 165 } else { 166 http.Redirect(w, r, fmt.Sprintf("/%s/%s/%s/commit/%s?branch=%s", host, repo.Owner, repo.Name, hash, branch), http.StatusSeeOther) 167 } 168 169 return nil 170 }