1package web
2
3import (
4 "net/http"
5
6 "github.com/charmbracelet/log/v2"
7 "github.com/charmbracelet/soft-serve/git"
8 "github.com/charmbracelet/soft-serve/pkg/config"
9 "github.com/charmbracelet/soft-serve/pkg/proto"
10 "github.com/gorilla/mux"
11)
12
13// TreeData contains data for rendering directory tree view.
14type TreeData struct {
15 Repo proto.Repository
16 DefaultBranch string
17 Ref string
18 Path string
19 Entries git.Entries
20 ActiveTab string
21 ServerName string
22 IsCommitHash bool
23}
24
25func repoTree(w http.ResponseWriter, r *http.Request) {
26 ctx := r.Context()
27 logger := log.FromContext(ctx)
28 cfg := config.FromContext(ctx)
29 repo := proto.RepositoryFromContext(ctx)
30 if repo == nil {
31 renderNotFound(w, r)
32 return
33 }
34
35 gr, err := openRepository(repo)
36 if err != nil {
37 logger.Debug("failed to open repository", "repo", repo.Name(), "err", err)
38 renderInternalServerError(w, r)
39 return
40 }
41
42 vars := mux.Vars(r)
43 refAndPath := vars["refAndPath"]
44 ref, path := parseRefAndPath(gr, refAndPath)
45
46 if ref == "" {
47 head, err := gr.HEAD()
48 if err == nil && head != nil {
49 ref = head.Name().Short()
50 }
51 }
52
53 refObj, isCommitHash, err := resolveAndBuildRef(gr, ref)
54 if err != nil {
55 logger.Debug("failed to resolve ref or commit", "repo", repo.Name(), "ref", ref, "err", err)
56 renderNotFound(w, r)
57 return
58 }
59
60 tree, err := gr.TreePath(refObj, path)
61 if err != nil {
62 logger.Debug("failed to get tree path", "repo", repo.Name(), "ref", ref, "path", path, "err", err)
63 renderNotFound(w, r)
64 return
65 }
66
67 entries, err := tree.Entries()
68 if err != nil {
69 logger.Debug("failed to get tree entries", "err", err)
70 renderInternalServerError(w, r)
71 return
72 }
73
74 entries.Sort()
75
76 defaultBranch := getDefaultBranch(gr)
77
78 data := TreeData{
79 Repo: repo,
80 DefaultBranch: defaultBranch,
81 Ref: ref,
82 Path: path,
83 Entries: entries,
84 ActiveTab: "tree",
85 ServerName: cfg.Name,
86 IsCommitHash: isCommitHash,
87 }
88
89 renderHTML(w, "tree.html", data)
90}