this repo has no description

add repo-tree template

Akshay 56dc2ac0 c768a04c

Changed files
+116 -54
appview
pages
templates
state
knotserver
types
+10
appview/pages/pages.go
··· 175 func (p *Pages) RepoCommit(w io.Writer, params RepoCommitParams) error { 176 return p.execute("repo/commit", w, params) 177 }
··· 175 func (p *Pages) RepoCommit(w io.Writer, params RepoCommitParams) error { 176 return p.execute("repo/commit", w, params) 177 } 178 + 179 + type RepoTreeParams struct { 180 + LoggedInUser *auth.User 181 + RepoInfo RepoInfo 182 + types.RepoTreeResponse 183 + } 184 + 185 + func (p *Pages) RepoTree(w io.Writer, params RepoTreeParams) error { 186 + return p.execute("repo/tree", w, params) 187 + }
+2 -2
appview/pages/templates/repo/index.html
··· 1 - {{define "title"}} {{ .RepoInfo.OwnerWithAt }} / {{ .RepoInfo.Name }} {{end}} 2 3 {{define "content"}} 4 5 <h1> 6 - {{ .RepoInfo.OwnerWithAt }} / {{ .RepoInfo.Name }} 7 </h1> 8 <main> 9 {{- if .IsEmpty }}
··· 1 + {{define "title"}} {{ .RepoInfo.FullName }} {{end}} 2 3 {{define "content"}} 4 5 <h1> 6 + {{ .RepoInfo.FullName }} 7 </h1> 8 <main> 9 {{- if .IsEmpty }}
+21 -26
appview/pages/templates/repo/tree.html
··· 1 - <html> 2 3 - {{ template "layouts/head" . }} 4 5 - {{ template "layouts/repo-header" . }} 6 - <body> 7 - {{ template "layouts/nav" . }} 8 <main> 9 - {{ $repo := .name }} 10 - {{ $ref := .ref }} 11 - {{ $parent := .parent }} 12 - 13 <div class="tree"> 14 - {{ if $parent }} 15 <div></div> 16 <div></div> 17 - <div><a href="/{{ $repo }}/tree/{{ $ref }}/{{ .dotdot }}">..</a></div> 18 {{ end }} 19 - {{ range .files }} 20 {{ if not .IsFile }} 21 <div class="mode">{{ .Mode }}</div> 22 <div class="size">{{ .Size }}</div> 23 <div> 24 - {{ if $parent }} 25 - <a href="/{{ $repo }}/tree/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}/</a> 26 {{ else }} 27 - <a href="/{{ $repo }}/tree/{{ $ref }}/{{ .Name }}">{{ .Name }}/</a> 28 {{ end }} 29 </div> 30 {{ end }} 31 {{ end }} 32 - {{ range .files }} 33 {{ if .IsFile }} 34 <div class="mode">{{ .Mode }}</div> 35 <div class="size">{{ .Size }}</div> 36 <div> 37 - {{ if $parent }} 38 - <a href="/{{ $repo }}/blob/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}</a> 39 {{ else }} 40 - <a href="/{{ $repo }}/blob/{{ $ref }}/{{ .Name }}">{{ .Name }}</a> 41 {{ end }} 42 </div> 43 {{ end }} 44 {{ end }} 45 </div> 46 - <article> 47 - <pre> 48 - {{- if .readme }}{{ .readme }}{{- end -}} 49 - </pre> 50 - </article> 51 </main> 52 - </body> 53 - </html>
··· 1 + {{define "title"}} {{ .RepoInfo.FullName }} {{end}} 2 3 + {{define "content"}} 4 5 + <h1> 6 + {{ .RepoInfo.FullName }} 7 + </h1> 8 <main> 9 <div class="tree"> 10 + 11 + {{ if .Parent }} 12 <div></div> 13 <div></div> 14 + <div><a href="/{{ .RepoInfo.FullName }}/tree/{{ .Ref }}/{{ .DotDot }}">..</a></div> 15 {{ end }} 16 + 17 + {{ range .Files }} 18 {{ if not .IsFile }} 19 <div class="mode">{{ .Mode }}</div> 20 <div class="size">{{ .Size }}</div> 21 <div> 22 + {{ if $.Parent }} 23 + <a href="/{{ .RepoInfo.FullName }}/tree/{{ $.Ref }}/{{ $.Parent }}/{{ .Name }}">{{ .Name }}/</a> 24 {{ else }} 25 + <a href="/{{ .RepoInfo.FullName }}/tree/{{ $.Ref }}/{{ .Name }}">{{ .Name }}/</a> 26 {{ end }} 27 </div> 28 + <hr /> 29 {{ end }} 30 {{ end }} 31 + 32 + {{ range .Files }} 33 {{ if .IsFile }} 34 <div class="mode">{{ .Mode }}</div> 35 <div class="size">{{ .Size }}</div> 36 <div> 37 + {{ if $.Parent }} 38 + <a href="/{{ $.RepoInfo.FullName }}/blob/{{ $.Ref }}/{{ $.Parent }}/{{ .Name }}">{{ .Name }}</a> 39 {{ else }} 40 + <a href="/{{ $.RepoInfo.FullName }}/blob/{{ $.Ref }}/{{ .Name }}">{{ .Name }}</a> 41 {{ end }} 42 </div> 43 + <hr /> 44 {{ end }} 45 {{ end }} 46 </div> 47 </main> 48 + {{end}}
+42
appview/state/repo.go
··· 133 return 134 } 135 136 func repoKnotAndId(r *http.Request) (string, string, identity.Identity, error) { 137 repoName := chi.URLParam(r, "repo") 138 knot, ok := r.Context().Value("knot").(string)
··· 133 return 134 } 135 136 + func (s *State) RepoTree(w http.ResponseWriter, r *http.Request) { 137 + repoName, knot, id, err := repoKnotAndId(r) 138 + if err != nil { 139 + log.Println("failed to get repo and knot", err) 140 + return 141 + } 142 + 143 + ref := chi.URLParam(r, "ref") 144 + treePath := chi.URLParam(r, "*") 145 + resp, err := http.Get(fmt.Sprintf("http://%s/%s/%s/tree/%s/%s", knot, id.DID.String(), repoName, ref, treePath)) 146 + if err != nil { 147 + log.Println("failed to reach knotserver", err) 148 + return 149 + } 150 + 151 + body, err := io.ReadAll(resp.Body) 152 + if err != nil { 153 + log.Fatalf("Error reading response body: %v", err) 154 + return 155 + } 156 + 157 + var result types.RepoTreeResponse 158 + err = json.Unmarshal(body, &result) 159 + if err != nil { 160 + log.Println("failed to parse response:", err) 161 + return 162 + } 163 + 164 + log.Println(result) 165 + 166 + s.pages.RepoTree(w, pages.RepoTreeParams{ 167 + LoggedInUser: s.auth.GetUser(r), 168 + RepoInfo: pages.RepoInfo{ 169 + OwnerDid: id.DID.String(), 170 + OwnerHandle: id.Handle.String(), 171 + Name: repoName, 172 + }, 173 + RepoTreeResponse: result, 174 + }) 175 + return 176 + } 177 + 178 func repoKnotAndId(r *http.Request) (string, string, identity.Identity, error) { 179 repoName := chi.URLParam(r, "repo") 180 knot, ok := r.Context().Value("knot").(string)
+3
appview/state/state.go
··· 602 r.With(ResolveRepoKnot(s)).Route("/{repo}", func(r chi.Router) { 603 r.Get("/", s.RepoIndex) 604 r.Get("/log/{ref}", s.RepoLog) 605 r.Get("/commit/{ref}", s.RepoCommit) 606 607 // These routes get proxied to the knot
··· 602 r.With(ResolveRepoKnot(s)).Route("/{repo}", func(r chi.Router) { 603 r.Get("/", s.RepoIndex) 604 r.Get("/log/{ref}", s.RepoLog) 605 + r.Route("/tree/{ref}", func(r chi.Router) { 606 + r.Get("/*", s.RepoTree) 607 + }) 608 r.Get("/commit/{ref}", s.RepoCommit) 609 610 // These routes get proxied to the knot
+6 -14
knotserver/git/tree.go
··· 4 "fmt" 5 6 "github.com/go-git/go-git/v5/plumbing/object" 7 ) 8 9 - func (g *GitRepo) FileTree(path string) ([]NiceTree, error) { 10 c, err := g.r.CommitObject(g.h) 11 if err != nil { 12 return nil, fmt.Errorf("commit object: %w", err) 13 } 14 15 - files := []NiceTree{} 16 tree, err := c.Tree() 17 if err != nil { 18 return nil, fmt.Errorf("file tree: %w", err) ··· 39 return files, nil 40 } 41 42 - // A nicer git tree representation. 43 - type NiceTree struct { 44 - Name string 45 - Mode string 46 - Size int64 47 - IsFile bool 48 - IsSubtree bool 49 - } 50 - 51 - func makeNiceTree(t *object.Tree) []NiceTree { 52 - nts := []NiceTree{} 53 54 for _, e := range t.Entries { 55 mode, _ := e.Mode.ToOSFileMode() 56 sz, _ := t.Size(e.Name) 57 - nts = append(nts, NiceTree{ 58 Name: e.Name, 59 Mode: mode.String(), 60 IsFile: e.Mode.IsFile(),
··· 4 "fmt" 5 6 "github.com/go-git/go-git/v5/plumbing/object" 7 + "github.com/sotangled/tangled/types" 8 ) 9 10 + func (g *GitRepo) FileTree(path string) ([]types.NiceTree, error) { 11 c, err := g.r.CommitObject(g.h) 12 if err != nil { 13 return nil, fmt.Errorf("commit object: %w", err) 14 } 15 16 + files := []types.NiceTree{} 17 tree, err := c.Tree() 18 if err != nil { 19 return nil, fmt.Errorf("file tree: %w", err) ··· 40 return files, nil 41 } 42 43 + func makeNiceTree(t *object.Tree) []types.NiceTree { 44 + nts := []types.NiceTree{} 45 46 for _, e := range t.Entries { 47 mode, _ := e.Mode.ToOSFileMode() 48 sz, _ := t.Size(e.Name) 49 + nts = append(nts, types.NiceTree{ 50 Name: e.Name, 51 Mode: mode.String(), 52 IsFile: e.Mode.IsFile(),
+14 -6
knotserver/routes.go
··· 122 return 123 } 124 125 - data := make(map[string]any) 126 - data["ref"] = ref 127 - data["parent"] = treePath 128 - data["desc"] = getDescription(path) 129 - data["dotdot"] = filepath.Dir(treePath) 130 131 - h.listFiles(files, data, w) 132 return 133 } 134
··· 122 return 123 } 124 125 + resp := types.RepoTreeResponse{ 126 + Ref: ref, 127 + Parent: treePath, 128 + Description: getDescription(path), 129 + DotDot: filepath.Dir(treePath), 130 + Files: files, 131 + } 132 + // data := make(map[string]any) 133 + // data["ref"] = ref 134 + // data["parent"] = treePath 135 + // data["desc"] = getDescription(path) 136 + // data["dotdot"] = filepath.Dir(treePath) 137 138 + writeJSON(w, resp) 139 + // h.listFiles(files, data, w) 140 return 141 } 142
+8 -6
types/repo.go
··· 24 PerPage int `json:"per_page,omitempty"` 25 } 26 27 - // data["commit"] = diff.Commit 28 - // 29 - // data["stat"] = diff.Stat 30 - // data["diff"] = diff.Diff 31 - // data["ref"] = ref 32 - // data["desc"] = getDescription(path) 33 type RepoCommitResponse struct { 34 Ref string `json:"ref,omitempty"` 35 Diff *NiceDiff `json:"diff,omitempty"` 36 }
··· 24 PerPage int `json:"per_page,omitempty"` 25 } 26 27 type RepoCommitResponse struct { 28 Ref string `json:"ref,omitempty"` 29 Diff *NiceDiff `json:"diff,omitempty"` 30 } 31 + 32 + type RepoTreeResponse struct { 33 + Ref string `json:"ref,omitempty"` 34 + Parent string `json:"parent,omitempty"` 35 + Description string `json:"description,omitempty"` 36 + DotDot string `json:"dotdot,omitempty"` 37 + Files []NiceTree `json:"files,omitempty"` 38 + }
+10
types/tree.go
···
··· 1 + package types 2 + 3 + // A nicer git tree representation. 4 + type NiceTree struct { 5 + Name string 6 + Mode string 7 + Size int64 8 + IsFile bool 9 + IsSubtree bool 10 + }