A vibe coded tangled fork which supports pijul.
1package xrpc
2
3import (
4 "net/http"
5
6 "tangled.org/core/knotserver/vcs"
7 xrpcerr "tangled.org/core/xrpc/errors"
8
9 "tangled.org/core/api/tangled"
10)
11
12// RepoPijulTree is kept as an alias for backwards compatibility.
13// It delegates to the unified RepoTree handler.
14func (x *Xrpc) RepoPijulTree(w http.ResponseWriter, r *http.Request) {
15 // Map channel param to ref if present, then delegate
16 q := r.URL.Query()
17 if channel := q.Get("channel"); channel != "" && q.Get("ref") == "" {
18 q.Set("ref", channel)
19 r.URL.RawQuery = q.Encode()
20 }
21 x.RepoTree(w, r)
22}
23
24// RepoPijulBlob handles the sh.tangled.repo.pijulBlob endpoint
25// Returns file content from a Pijul repository
26func (x *Xrpc) RepoPijulBlob(w http.ResponseWriter, r *http.Request) {
27 repo := r.URL.Query().Get("repo")
28 repoPath, err := x.parseRepoParam(repo)
29 if err != nil {
30 writeError(w, err.(xrpcerr.XrpcError), http.StatusBadRequest)
31 return
32 }
33
34 channel := r.URL.Query().Get("channel")
35 path := r.URL.Query().Get("path")
36
37 if path == "" {
38 writeError(w, xrpcerr.NewXrpcError(
39 xrpcerr.WithTag("InvalidRequest"),
40 xrpcerr.WithMessage("missing path parameter"),
41 ), http.StatusBadRequest)
42 return
43 }
44
45 rv, err := vcs.Open(repoPath, channel)
46 if err != nil {
47 writeError(w, xrpcerr.NewXrpcError(
48 xrpcerr.WithTag("RepoNotFound"),
49 xrpcerr.WithMessage("failed to open pijul repository"),
50 ), http.StatusNotFound)
51 return
52 }
53
54 // Try to read as text first
55 const maxSize = 1024 * 1024 // 1MB
56 content, err := rv.FileContentN(path, maxSize)
57 if err != nil {
58 if vcs.IsBinaryFileError(err) {
59 // Return binary indicator
60 response := tangled.RepoPijulBlob_Output{
61 Is_binary: true,
62 Path: path,
63 Ref: &channel,
64 }
65 writeJson(w, response)
66 return
67 }
68
69 x.Logger.Error("failed to read file", "error", err, "path", path)
70 writeError(w, xrpcerr.NewXrpcError(
71 xrpcerr.WithTag("PathNotFound"),
72 xrpcerr.WithMessage("failed to read file"),
73 ), http.StatusNotFound)
74 return
75 }
76
77 contentStr := string(content)
78 response := tangled.RepoPijulBlob_Output{
79 Contents: &contentStr,
80 Path: path,
81 Ref: &channel,
82 }
83
84 writeJson(w, response)
85}