forked from
tangled.org/core
Monorepo for Tangled — https://tangled.org
1package xrpc
2
3import (
4 "context"
5 "math"
6 "net/http"
7 "time"
8
9 "tangled.org/core/api/tangled"
10 "tangled.org/core/knotserver/git"
11 xrpcerr "tangled.org/core/xrpc/errors"
12)
13
14func (x *Xrpc) RepoLanguages(w http.ResponseWriter, r *http.Request) {
15 repo := r.URL.Query().Get("repo")
16 repoPath, err := x.parseRepoParam(repo)
17 if err != nil {
18 writeError(w, err.(xrpcerr.XrpcError), http.StatusBadRequest)
19 return
20 }
21
22 ref := r.URL.Query().Get("ref")
23
24 gr, err := git.Open(repoPath, ref)
25 if err != nil {
26 x.Logger.Error("opening repo", "error", err.Error())
27 writeError(w, xrpcerr.RefNotFoundError, http.StatusNotFound)
28 return
29 }
30
31 ctx, cancel := context.WithTimeout(r.Context(), 1*time.Second)
32 defer cancel()
33
34 sizes, err := gr.AnalyzeLanguages(ctx)
35 if err != nil {
36 x.Logger.Error("failed to analyze languages", "error", err.Error())
37 writeError(w, xrpcerr.NewXrpcError(
38 xrpcerr.WithTag("InvalidRequest"),
39 xrpcerr.WithMessage("failed to analyze repository languages"),
40 ), http.StatusNoContent)
41 return
42 }
43
44 var apiLanguages []*tangled.RepoLanguages_Language
45 var totalSize int64
46
47 for _, size := range sizes {
48 totalSize += size
49 }
50
51 for name, size := range sizes {
52 percentagef64 := float64(size) / float64(totalSize) * 100
53 percentage := math.Round(percentagef64)
54
55 lang := &tangled.RepoLanguages_Language{
56 Name: name,
57 Size: size,
58 Percentage: int64(percentage),
59 }
60
61 apiLanguages = append(apiLanguages, lang)
62 }
63
64 response := tangled.RepoLanguages_Output{
65 Ref: ref,
66 Languages: apiLanguages,
67 }
68
69 if totalSize > 0 {
70 response.TotalSize = &totalSize
71 totalFiles := int64(len(sizes))
72 response.TotalFiles = &totalFiles
73 }
74
75 writeJson(w, response)
76}