Monorepo for Tangled tangled.org

wip: knot2: xrpc.git.keepCommit

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

boltless.me a713d72a 537af051

verified
Changed files
+91 -3
knot2
+87
knot2/server/handler/xrpc_git_keep_commit.go
··· 1 + package handler 2 + 3 + import ( 4 + "encoding/json" 5 + "fmt" 6 + "net/http" 7 + "os/exec" 8 + "path" 9 + 10 + "github.com/bluesky-social/indigo/atproto/syntax" 11 + "github.com/go-git/go-git/v5" 12 + "github.com/go-git/go-git/v5/plumbing" 13 + "tangled.org/core/api/tangled" 14 + "tangled.org/core/knot2/config" 15 + "tangled.org/core/log" 16 + xrpcerr "tangled.org/core/xrpc/errors" 17 + ) 18 + 19 + func XrpcGitKeepCommit(cfg *config.Config) http.HandlerFunc { 20 + return func(w http.ResponseWriter, r *http.Request) { 21 + ctx := r.Context() 22 + l := log.FromContext(ctx).With("handler", "XrpcGitKeepCommit") 23 + 24 + // TODO: get session did 25 + actorDid := syntax.DID("") 26 + 27 + var input tangled.GitKeepCommit_Input 28 + if err := json.NewDecoder(r.Body).Decode(&input); err != nil { 29 + l.Error("failed to decode body", "err", err) 30 + panic("unimplemented") 31 + } 32 + 33 + repoAt, err := syntax.ParseATURI(input.Repo) 34 + if err != nil { 35 + l.Error("failed to decode body", "err", err) 36 + panic("unimplemented") 37 + } 38 + repoPath := repoPathFromAtUri(cfg, repoAt) 39 + 40 + // ensure repo exist (if not, clone it) 41 + repo, err := git.PlainOpen(repoPath) 42 + if err != nil { 43 + // TODO: clone the ref from source repo if repo doesn't exist in this knot yet 44 + l.Info("repo missing in knot", "err", err) 45 + panic("unimplemented") 46 + } 47 + 48 + commitId, err := repo.ResolveRevision(plumbing.Revision(input.Ref)) 49 + if err != nil { 50 + l.Error("failed to resolve revision", "ref", input.Ref, "err", err) 51 + panic("unimplemented") 52 + } 53 + 54 + // set keep-ref for given commit 55 + refspec := fmt.Sprintf("refs/knot/%s/keep/%s", actorDid, commitId) 56 + updateRefCmd := exec.Command("git", "-C", repoPath, "update-ref", refspec, commitId.String()) 57 + if err := updateRefCmd.Run(); err != nil { 58 + writeError(w, xrpcerr.GenericError(err), http.StatusBadRequest) 59 + return 60 + } 61 + 62 + output := tangled.GitKeepCommit_Output{ 63 + CommitId: commitId.String(), 64 + } 65 + 66 + w.WriteHeader(http.StatusOK) 67 + writeJson(w, output) 68 + } 69 + } 70 + 71 + func repoPathFromAtUri(cfg *config.Config, repoAt syntax.ATURI) string { 72 + return path.Join(cfg.RepoDir, repoAt.Authority().String(), repoAt.RecordKey().String()) 73 + } 74 + 75 + func writeError(w http.ResponseWriter, e xrpcerr.XrpcError, status int) { 76 + w.Header().Set("Content-Type", "application/json") 77 + w.WriteHeader(status) 78 + json.NewEncoder(w).Encode(e) 79 + } 80 + 81 + func writeJson(w http.ResponseWriter, response any) { 82 + w.Header().Set("Content-Type", "application/json") 83 + if err := json.NewEncoder(w).Encode(response); err != nil { 84 + writeError(w, xrpcerr.GenericError(err), http.StatusInternalServerError) 85 + return 86 + } 87 + }
+4 -3
knot2/server/routes.go
··· 7 7 "github.com/bluesky-social/indigo/atproto/auth/oauth" 8 8 "github.com/go-chi/chi/v5" 9 9 "github.com/gorilla/sessions" 10 + "tangled.org/core/api/tangled" 10 11 "tangled.org/core/knot2/config" 11 12 "tangled.org/core/knot2/server/handler" 12 13 "tangled.org/core/knot2/server/middleware" ··· 43 44 44 45 r.Get("/events", handler.Events()) 45 46 46 - // r.Route("/xrpc", func(r chi.Router) { 47 - // r.Post("/"+tangled.GitKeepRefNSID, handler.GitKeepRef()) 48 - // }) 47 + r.Route("/xrpc", func(r chi.Router) { 48 + r.Post("/"+tangled.GitKeepCommitNSID, handler.XrpcGitKeepCommit(cfg)) 49 + }) 49 50 50 51 return r 51 52 }