appview: implement a basic breadcrumb for files
This needs another pass to fix the intermediate directory links etc.
Anirudh Oppiliappan 2 weeks ago 8 files (+48, -12)
MODIFIED
.gitignore
MODIFIED
.gitignore
@@ -1,6 +1,7 @@.direnv/tmp*.db+*.db-*.bin/appview/pages/static/*result
ADDED
appview.db-journal
ADDED
appview.db-journal
MODIFIED
appview/pages/pages.go
MODIFIED
appview/pages/pages.go
@@ -8,7 +8,9 @@ "io""io/fs""log""net/http"+ "os""path"+ "path/filepath""strings""github.com/dustin/go-humanize"@@ -259,10 +261,18 @@ type RepoBlobParams struct {LoggedInUser *auth.UserRepoInfo RepoInfoActive string+ File string+ PathElems []stringtypes.RepoBlobResponse}func (p *Pages) RepoBlob(w io.Writer, params RepoBlobParams) error {+ path := filepath.Dir(params.Path)+ file := filepath.Base(params.Path)++ params.PathElems = strings.Split(path, string(os.PathSeparator))+ params.Path = path+ params.File = fileparams.Active = "overview"return p.executeRepo("repo/blob", w, params)}
@@ -3,7 +3,15 @@ {{ $lines := split .Contents }}{{ $tot_lines := len $lines }}{{ $tot_chars := len (printf "%d" $tot_lines) }}{{ $code_number_style := "text-gray-400 left-0 bg-white text-right mr-2 select-none" }}+<div class="pb-2 text-lg">+{{ range .PathElems }}+ <a href="/{{ $.RepoInfo.FullName }}/tree/{{ $.Ref }}/{{ . }}" class="text-bold text-gray-500">{{ . }}</a> /+{{ end }}<span class="">{{ .File }}</span>+</div>+++{{ if .IsBinary }}<p class="text-center text-gray-400">This is a binary file and will not be displayed.</p>{{ else }}<pre class="font-mono text-sm overflow-auto relative text-ellipsis"><code>{{ range $idx, $line := $lines }}<span class="flex"><span class="{{ $code_number_style }}" style="min-width: {{$tot_chars}}ch;">{{ add $idx 1 }}</span>- <span class="whitespace-pre">{{ $line }}</span></span>{{ else }}<em class="text-gray-400">this file is empty</em>{{ end }}</code></pre>+ <span class="whitespace-pre">{{ $line }}</span></span>{{ else }}<em class="text-gray-400">this file is empty</em>{{ end }}</code></pre>{{ end}}{{ end }}
MODIFIED
knotserver/git/git.go
MODIFIED
knotserver/git/git.go
@@ -14,6 +14,10 @@ "github.com/go-git/go-git/v5/plumbing""github.com/go-git/go-git/v5/plumbing/object")+var (+ ErrBinaryFile = fmt.Errorf("binary file")+)+type GitRepo struct {r *git.Repositoryh plumbing.Hash@@ -148,7 +152,7 @@if !isbin {return file.Contents()} else {- return "Not displaying binary file", nil+ return "", ErrBinaryFile}}
MODIFIED
knotserver/handler.go
MODIFIED
knotserver/handler.go
@@ -76,6 +76,7 @@ r.Get("/info/refs", h.InfoRefs)r.Post("/git-upload-pack", h.UploadPack)r.Route("/tree/{ref}", func(r chi.Router) {+ r.Get("/", h.RepoIndex)r.Get("/*", h.RepoTree)})
MODIFIED
knotserver/routes.go
MODIFIED
knotserver/routes.go
@@ -32,8 +32,9 @@func (h *Handle) RepoIndex(w http.ResponseWriter, r *http.Request) {path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r))l := h.l.With("path", path, "handler", "RepoIndex")+ ref := chi.URLParam(r, "ref")- gr, err := git.Open(path, "")+ gr, err := git.Open(path, ref)if err != nil {if errors.Is(err, plumbing.ErrReferenceNotFound) {resp := types.RepoIndexResponse{@@ -84,23 +85,26 @@ if readmeContent == "" {l.Warn("no readme found")}- mainBranch, err := gr.FindMainBranch(h.c.Repo.MainBranch)+ files, err := gr.FileTree("")if err != nil {writeError(w, err.Error(), http.StatusInternalServerError)- l.Error("finding main branch", "error", err.Error())+ l.Error("file tree", "error", err.Error())return}- files, err := gr.FileTree("")- if err != nil {- writeError(w, err.Error(), http.StatusInternalServerError)- l.Error("file tree", "error", err.Error())- return+ if ref == "" {+ mainBranch, err := gr.FindMainBranch(h.c.Repo.MainBranch)+ if err != nil {+ writeError(w, err.Error(), http.StatusInternalServerError)+ l.Error("finding main branch", "error", err.Error())+ return+ }+ ref = mainBranch}resp := types.RepoIndexResponse{IsEmpty: false,- Ref: mainBranch,+ Ref: ref,Commits: commits,Description: getDescription(path),Readme: readmeContent,@@ -156,8 +160,14 @@ notFound(w)return}+ var isBinaryFile bool = falsecontents, err := gr.FileContent(treePath)- if err != nil {+ if errors.Is(err, git.ErrBinaryFile) {+ isBinaryFile = true+ } else if errors.Is(err, object.ErrFileNotFound) {+ notFound(w)+ return+ } else if err != nil {writeError(w, err.Error(), http.StatusInternalServerError)return}@@ -168,6 +178,7 @@ resp := types.RepoBlobResponse{Ref: ref,Contents: string(safe),Path: treePath,+ IsBinary: isBinaryFile,}h.showFile(resp, w, l)
MODIFIED
types/repo.go
MODIFIED
types/repo.go
@@ -65,6 +65,7 @@ type RepoBlobResponse struct {Contents string `json:"contents,omitempty"`Ref string `json:"ref,omitempty"`Path string `json:"path,omitempty"`+ IsBinary bool `json:"is_binary,omitempty"`Lines int `json:"lines,omitempty"`}