c5fc8b2d8926db3bd8ed9fd928e3cb7a21d56ce3

Author
Ayman Bagabas <ayman.bagabas@gmail.com>
Committer
Ayman Bagabas <ayman.bagabas@gmail.com>
Date

Message

feat: cat middleware: list directory entries

Diff

This diff is truncated to protect this page.

  1diff --git a/internal/git/git.go b/internal/git/git.go
  2index f7188c551ca3da69aafae773506b4a533dff345c..cf2b09d37bfdbb3bcea2ae0ec3daab12e26aa222 100644
  3--- a/internal/git/git.go
  4+++ b/internal/git/git.go
  5@@ -306,13 +306,7 @@ func (rs *RepoSource) loadRepo(name string, rg *git.Repository) (*Repo, error) {
  6 
  7 // LatestFile returns the latest file at the specified path in the repository.
  8 func (r *Repo) LatestFile(path string) (string, error) {
  9-	lg, err := r.repository.Log(&git.LogOptions{
 10-		From: r.GetHEAD().Hash(),
 11-	})
 12-	if err != nil {
 13-		return "", err
 14-	}
 15-	c, err := lg.Next()
 16+	c, err := r.commitForHash(r.head.Hash())
 17 	if err != nil {
 18 		return "", err
 19 	}
 20@@ -326,3 +320,8 @@ func (r *Repo) LatestFile(path string) (string, error) {
 21 	}
 22 	return content, nil
 23 }
 24+
 25+// LatestTree returns the latest tree at the specified path in the repository.
 26+func (r *Repo) LatestTree(path string) (*object.Tree, error) {
 27+	return r.Tree(r.head, path)
 28+}
 29diff --git a/server/middleware.go b/server/middleware.go
 30index e60fd53b57648ce20db5722a217ae6a0d857f067..cdfc70d73a4a13cc35d1bd997632d811a1f9df32 100644
 31--- a/server/middleware.go
 32+++ b/server/middleware.go
 33@@ -3,6 +3,7 @@ package server
 34 import (
 35 	"fmt"
 36 	"path/filepath"
 37+	"sort"
 38 	"strings"
 39 
 40 	"github.com/alecthomas/chroma/lexers"
 41@@ -11,16 +12,36 @@ import (
 42 	appCfg "github.com/charmbracelet/soft-serve/internal/config"
 43 	"github.com/charmbracelet/soft-serve/internal/tui/bubbles/git/types"
 44 	"github.com/charmbracelet/wish"
 45-	"github.com/charmbracelet/wish/git"
 46+	gitwish "github.com/charmbracelet/wish/git"
 47 	"github.com/gliderlabs/ssh"
 48-	gg "github.com/go-git/go-git/v5"
 49+	"github.com/go-git/go-git/v5/plumbing/filemode"
 50+	"github.com/go-git/go-git/v5/plumbing/object"
 51 	"github.com/muesli/termenv"
 52 )
 53 
 54 var (
 55-	linenoStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("8"))
 56+	linenoStyle   = lipgloss.NewStyle().Foreground(lipgloss.Color("8"))
 57+	dirnameStyle  = lipgloss.NewStyle().Foreground(lipgloss.Color("#00AAFF"))
 58+	filenameStyle = lipgloss.NewStyle()
 59+	filemodeStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#777777"))
 60 )
 61 
 62+type entries []object.TreeEntry
 63+
 64+func (cl entries) Len() int      { return len(cl) }
 65+func (cl entries) Swap(i, j int) { cl[i], cl[j] = cl[j], cl[i] }
 66+func (cl entries) Less(i, j int) bool {
 67+	if cl[i].Mode == filemode.Dir && cl[j].Mode == filemode.Dir {
 68+		return cl[i].Name < cl[j].Name
 69+	} else if cl[i].Mode == filemode.Dir {
 70+		return true
 71+	} else if cl[j].Mode == filemode.Dir {
 72+		return false
 73+	} else {
 74+		return cl[i].Name < cl[j].Name
 75+	}
 76+}
 77+
 78 // softServeMiddleware is a middleware that handles displaying files with the
 79 // option of syntax highlighting and line numbers.
 80 func softServeMiddleware(ac *appCfg.Config) wish.Middleware {
 81@@ -48,7 +69,7 @@ func softServeMiddleware(ac *appCfg.Config) wish.Middleware {
 82 						return
 83 					}
 84 					auth := ac.AuthRepo(repo, s.PublicKey())
 85-					if auth < git.ReadOnlyAccess {
 86+					if auth < gitwish.ReadOnlyAccess {
 87 						s.Write([]byte("unauthorized"))
 88 						s.Exit(1)
 89 						return
 90@@ -66,25 +87,52 @@ func softServeMiddleware(ac *appCfg.Config) wish.Middleware {
 91 						_ = s.Exit(1)
 92 						return
 93 					}
 94-					fc, err := readFile(rs.Repository(), strings.Join(ps[1:], "/"))
 95-					if err != nil {
 96+					p := strings.Join(ps[1:], "/")
 97+					t, err := rs.LatestTree(p)
 98+					if err != nil && err != object.ErrDirectoryNotFound {
 99 						_, _ = s.Write([]byte(err.Error()))
100 						_ = s.Exit(1)
101 						return
102 					}
103-					if color {
104-						ffc, err := withFormatting(fp, fc)
105+					if err == object.ErrDirectoryNotFound {
106+						fc, err := rs.LatestFile(p)
107 						if err != nil {
108-							s.Write([]byte(err.Error()))
109-							s.Exit(1)
110+							_, _ = s.Write([]byte(err.Error()))
111+							_ = s.Exit(1)
112 							return
113 						}
114-						fc = ffc
115-					}
116-					if lineno {
117-						fc = withLineNumber(fc, color)
118+						if color {
119+							ffc, err := withFormatting(fp, fc)
120+							if err != nil {
121+								s.Write([]byte(err.Error()))
122+								s.Exit(1)
123+								return
124+							}
125+							fc = ffc
126+						}
127+						if lineno {
128+							fc = withLineNumber(fc, color)
129+						}
130+						s.Write([]byte(fc))
131+					} else {
132+						ents := entries(t.Entries)