This repository has no description
1.6 kB
54 lines
1package xrpc
2
3import (
4 "bytes"
5 "fmt"
6 "net/http"
7 "os/exec"
8 "strings"
9
10 "github.com/bluesky-social/indigo/atproto/atclient"
11 "github.com/bluesky-social/indigo/atproto/syntax"
12)
13
14func (x *Xrpc) FormatPatch(w http.ResponseWriter, r *http.Request) {
15 var (
16 repoQuery = r.URL.Query().Get("repo")
17 from = r.URL.Query().Get("from")
18 to = r.URL.Query().Get("to")
19 )
20
21 repo, err := syntax.ParseDID(repoQuery)
22 if err != nil {
23 writeJson(w, http.StatusBadRequest, atclient.ErrorBody{Name: "BadRequest", Message: fmt.Sprintf("repo parameter invalid: %s", repoQuery)})
24 return
25 }
26
27 // reject leading dashes so user input can't be parsed as git flags
28 if from == "" || to == "" || strings.HasPrefix(from, "-") || strings.HasPrefix(to, "-") {
29 writeJson(w, http.StatusBadRequest, atclient.ErrorBody{Name: "BadRequest", Message: "missing or invalid from/to parameter"})
30 return
31 }
32
33 l := x.logger.With("method", "git.formatPatch", "repo", repo, "from", from, "to", to)
34 l.Debug("request")
35
36 ctx := r.Context()
37
38 repoPath, err := x.makeRepoPath(ctx, repo)
39 if err != nil {
40 writeJson(w, http.StatusNotFound, atclient.ErrorBody{Name: "RepoNotFound", Message: fmt.Sprintf("unknown repository: %q", repo)})
41 return
42 }
43
44 cmd := exec.CommandContext(ctx, "git", "-C", repoPath, "format-patch", "--stdout", fmt.Sprintf("%s..%s", from, to))
45 stderr := new(bytes.Buffer)
46 cmd.Stderr = stderr
47
48 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
49 cmd.Stdout = w
50 if err := cmd.Run(); err != nil {
51 l.Error("running format-patch", "err", err, "stderr", stderr.String())
52 w.WriteHeader(http.StatusInternalServerError)
53 }
54}