Monorepo for Tangled
0

Configure Feed

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

knotmirror/xrpc: `git.formatPatch`

Signed-off-by: Seongmin Lee <git@boltless.me>

Seongmin Lee (Jul 14, 2026, 4:05 AM +0900) 50f99c60 62859cf7

+55
+54
knotmirror/xrpc/git_format_patch.go
··· 1 + package xrpc 2 + 3 + import ( 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 + 14 + func (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 + }
+1
knotmirror/xrpc/xrpc.go
··· 66 66 // r.Get("/"+tangled.GitTempGetCommitNSID, x.GetCommit) // todo 67 67 // r.Get("/"+tangled.GitTempGetDiffNSID, x.GetDiff) // todo 68 68 r.Get("/"+tangled.GitTempGetEntryNSID, x.GetEntry) // todo 69 + r.Get("/"+tangled.GitTempFormatPatchNSID, x.FormatPatch) 69 70 // r.Get("/"+tangled.GitTempGetHeadNSID, x.GetHead) // todo 70 71 r.Get("/"+tangled.GitTempGetMergeBaseNSID, x.GetMergeBase) 71 72 r.Get("/"+tangled.GitTempGetTagNSID, x.GetTag) // using types.Response