func (h *Handler) serveRepoTag(w http.ResponseWriter, r *http.Request) error { v := mux.Vars(r) repo, repoPath, done, err := h.getRepo(r) if err != nil { return err } defer done() type resolveTag interface { ResolveTag(string) (vcs.CommitID, error) } if repo, ok := repo.(resolveTag); ok { commitID, err := repo.ResolveTag(v["Tag"]) if err != nil { return err } setShortCache(w) http.Redirect(w, r, h.router.URLToRepoCommit(repoPath, commitID).String(), http.StatusFound) return nil } return &httpError{http.StatusNotImplemented, fmt.Errorf("ResolveTag not yet implemented for %T", repo)} }
func (h *Handler) serveRepoRevision(w http.ResponseWriter, r *http.Request) error { v := mux.Vars(r) repo, repoPath, done, err := h.getRepo(r) if err != nil { return err } defer done() type resolveRevision interface { ResolveRevision(string) (vcs.CommitID, error) } if repo, ok := repo.(resolveRevision); ok { commitID, err := repo.ResolveRevision(v["RevSpec"]) if err != nil { return err } var statusCode int if commitIDIsCanon(v["RevSpec"]) { setLongCache(w) statusCode = http.StatusMovedPermanently } else { setShortCache(w) statusCode = http.StatusFound } http.Redirect(w, r, h.router.URLToRepoCommit(repoPath, commitID).String(), statusCode) return nil } return &httpError{http.StatusNotImplemented, fmt.Errorf("ResolveRevision not yet implemented for %T", repo)} }
func (h *Handler) serveRepoMergeBase(w http.ResponseWriter, r *http.Request) error { v := mux.Vars(r) repo, repoPath, done, err := h.getRepo(r) if err != nil { return err } defer done() if repo, ok := repo.(vcs.Merger); ok { a, b := vcs.CommitID(v["CommitIDA"]), vcs.CommitID(v["CommitIDB"]) mb, err := repo.MergeBase(a, b) if err != nil { return err } var statusCode int if commitIDIsCanon(string(a)) && commitIDIsCanon(string(b)) { setLongCache(w) statusCode = http.StatusMovedPermanently } else { setShortCache(w) statusCode = http.StatusFound } http.Redirect(w, r, h.router.URLToRepoCommit(repoPath, mb).String(), statusCode) return nil } return &httpError{http.StatusNotImplemented, fmt.Errorf("Merger not yet implemented by %T", repo)} }
func (h *Handler) getRepoPath(r *http.Request, label string) (repoPath string, err error) { v := mux.Vars(r) repoPath = v[label+"RepoPath"] if repoPath == "" { return "", &httpError{http.StatusBadRequest, errors.New("repoPath not found")} } return repoPath, err }
func (h *Handler) serveRepoCrossRepoDiff(w http.ResponseWriter, r *http.Request) error { v := mux.Vars(r) baseRepo, _, doneBase, err := h.getRepo(r) if err != nil { return err } defer doneBase() headRepo, _, doneHead, err := h.getRepoLabeled(r, "Head") if err != nil { return err } defer doneHead() var opt vcs.DiffOptions if err := schemaDecoder.Decode(&opt, r.URL.Query()); err != nil { return err } if baseRepo, ok := baseRepo.(vcs.CrossRepoDiffer); ok { diff, err := baseRepo.CrossRepoDiff(vcs.CommitID(v["Base"]), headRepo.(vcs.Repository), vcs.CommitID(v["Head"]), &opt) if err != nil { return err } _, baseCanon, err := checkCommitID(v["Base"]) if err != nil { return err } _, headCanon, err := checkCommitID(v["Head"]) if err != nil { return err } if baseCanon && headCanon { setLongCache(w) } else { setShortCache(w) } return writeJSON(w, diff) } return &httpError{http.StatusNotImplemented, fmt.Errorf("CrossRepoDiff not yet implemented for %T", baseRepo)} }
func (h *Handler) serveRepoBlameFile(w http.ResponseWriter, r *http.Request) error { v := mux.Vars(r) repo, _, done, err := h.getRepo(r) if err != nil { return err } defer done() var opt vcs.BlameOptions if err := schemaDecoder.Decode(&opt, r.URL.Query()); err != nil { return err } type blameFile interface { BlameFile(path string, opt *vcs.BlameOptions) ([]*vcs.Hunk, error) } if repo, ok := repo.(blameFile); ok { hunks, err := repo.BlameFile(v["Path"], &opt) if err != nil { return err } if opt.NewestCommit != "" { _, canon, err := checkCommitID(string(opt.NewestCommit)) if err != nil { return err } if canon { setLongCache(w) } else { setShortCache(w) } } return writeJSON(w, hunks) } return &httpError{http.StatusNotImplemented, fmt.Errorf("BlameFile not yet implemented for %T", repo)} }
// getCommitID retrieves the CommitID from the route variables and // runs checkCommitID on it. func getCommitID(r *http.Request) (vcs.CommitID, bool, error) { return checkCommitID(mux.Vars(r)["CommitID"]) }