A vibe coded tangled fork which supports pijul.
1package xrpc
2
3import (
4 "context"
5 "fmt"
6 "math"
7 "net/http"
8 "time"
9
10 "github.com/bluesky-social/indigo/atproto/atclient"
11 "github.com/bluesky-social/indigo/atproto/syntax"
12 "tangled.org/core/api/tangled"
13 "tangled.org/core/knotserver/git"
14)
15
16func (x *Xrpc) ListLanguages(w http.ResponseWriter, r *http.Request) {
17 var (
18 repoQuery = r.URL.Query().Get("repo")
19 ref = r.URL.Query().Get("ref")
20 )
21 l := x.logger.With("repo", repoQuery, "ref", ref)
22
23 repo, err := syntax.ParseATURI(repoQuery)
24 if err != nil || repo.RecordKey() == "" {
25 l.Error("invalid repo at-uri", "err", err)
26 writeJson(w, http.StatusBadRequest, atclient.ErrorBody{Name: "BadRequest", Message: fmt.Sprintf("repo parameter invalid: %s", repoQuery)})
27 return
28 }
29
30 out, err := x.listLanguages(r.Context(), repo, ref)
31 if err != nil {
32 // TODO: better error return
33 l.Error("failed to list languages", "err", err)
34 writeJson(w, http.StatusInternalServerError, atclient.ErrorBody{Name: "InternalServerError", Message: "failed to list languages"})
35 return
36 }
37
38 writeJson(w, http.StatusOK, out)
39}
40
41func (x *Xrpc) listLanguages(ctx context.Context, repo syntax.ATURI, ref string) (*tangled.GitTempListLanguages_Output, error) {
42 repoPath, err := x.makeRepoPath(ctx, repo)
43 if err != nil {
44 return nil, fmt.Errorf("resolving repo at-uri: %w", err)
45 }
46
47 gr, err := git.Open(repoPath, ref)
48 if err != nil {
49 return nil, fmt.Errorf("opening git repo: %w", err)
50 }
51
52 ctx, cancel := context.WithTimeout(ctx, 1*time.Second)
53 defer cancel()
54
55 sizes, err := gr.AnalyzeLanguages(ctx)
56 if err != nil {
57 return nil, fmt.Errorf("analyzing languages: %w", err)
58 }
59
60 return &tangled.GitTempListLanguages_Output{
61 Ref: ref,
62 Languages: sizesToLanguages(sizes),
63 }, nil
64}
65
66func sizesToLanguages(sizes git.LangBreakdown) []*tangled.GitTempListLanguages_Language {
67 var apiLanguages []*tangled.GitTempListLanguages_Language
68 var totalSize int64
69 for _, size := range sizes {
70 totalSize += size
71 }
72
73 for name, size := range sizes {
74 percentagef64 := float64(size) / float64(totalSize) * 100
75 percentage := math.Round(percentagef64)
76
77 lang := &tangled.GitTempListLanguages_Language{
78 Name: name,
79 Size: size,
80 Percentage: int64(percentage),
81 }
82
83 apiLanguages = append(apiLanguages, lang)
84 }
85
86 return apiLanguages
87}