This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / knotmirror / xrpc / git_format_patch.go
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}