9ea2a7ecef2d1cabf9f5b90da7e88e38b4a2c1b6

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

Message

feat: display files middleware

sshing with a filepath in a non-interactive terminal spits out the file
content with the option of syntax highlighting and line numbers

Diff

This diff is truncated to protect this page.

  1diff --git a/server/middleware.go b/server/middleware.go
  2new file mode 100644
  3index 0000000000000000000000000000000000000000..d94fe6b3b49d85947f82c30d8aee8d6bbaa6b906
  4--- /dev/null
  5+++ b/server/middleware.go
  6@@ -0,0 +1,144 @@
  7+package server
  8+
  9+import (
 10+	"fmt"
 11+	"path/filepath"
 12+	"strings"
 13+
 14+	"github.com/alecthomas/chroma/lexers"
 15+	gansi "github.com/charmbracelet/glamour/ansi"
 16+	"github.com/charmbracelet/lipgloss"
 17+	appCfg "github.com/charmbracelet/soft-serve/internal/config"
 18+	"github.com/charmbracelet/soft-serve/internal/tui/bubbles/git/types"
 19+	"github.com/charmbracelet/wish"
 20+	"github.com/charmbracelet/wish/git"
 21+	"github.com/gliderlabs/ssh"
 22+	gg "github.com/go-git/go-git/v5"
 23+	"github.com/muesli/termenv"
 24+)
 25+
 26+// softServeMiddleware is a middleware that handles displaying files with the
 27+// option of syntax highlighting and line numbers.
 28+func softServeMiddleware(ac *appCfg.Config) wish.Middleware {
 29+	return func(sh ssh.Handler) ssh.Handler {
 30+		return func(s ssh.Session) {
 31+			_, _, active := s.Pty()
 32+			cmds := s.Command()
 33+			if !active && len(cmds) > 0 {
 34+				func() {
 35+					formatting := false
 36+					lineno := false
 37+					fp := filepath.Clean(cmds[0])
 38+					ps := strings.Split(fp, "/")
 39+					repo := ps[0]
 40+					repoExists := false
 41+					for _, rp := range ac.Source.AllRepos() {
 42+						if rp.Name == repo {
 43+							repoExists = true
 44+						}
 45+					}
 46+					if !repoExists {
 47+						return
 48+					}
 49+					auth := ac.AuthRepo(repo, s.PublicKey())
 50+					if auth < git.ReadOnlyAccess {
 51+						s.Write([]byte("unauthorized"))
 52+						s.Exit(1)
 53+						return
 54+					}
 55+					for _, op := range cmds[1:] {
 56+						if op == "formatting" {
 57+							formatting = true
 58+						} else if op == "lineno" || op == "linenumber" {
 59+							lineno = true
 60+						}
 61+					}
 62+					rs, err := ac.Source.GetRepo(repo)
 63+					if err != nil {
 64+						_, _ = s.Write([]byte(err.Error()))
 65+						_ = s.Exit(1)
 66+						return
 67+					}
 68+					fc, err := readFile(rs.Repository, strings.Join(ps[1:], "/"))
 69+					if err != nil {
 70+						_, _ = s.Write([]byte(err.Error()))
 71+						_ = s.Exit(1)
 72+						return
 73+					}
 74+					if formatting {
 75+						ffc, err := withFormatting(fp, fc)
 76+						if err != nil {
 77+							s.Write([]byte(err.Error()))
 78+							s.Exit(1)
 79+							return
 80+						}
 81+						fc = ffc
 82+					}
 83+					if lineno {
 84+						fc = withLineNumber(fc, formatting)
 85+					}
 86+					s.Write([]byte(fc))
 87+				}()
 88+			}
 89+			sh(s)
 90+		}
 91+	}
 92+}
 93+
 94+func readFile(r *gg.Repository, fp string) (string, error) {
 95+	l, err := r.Log(&gg.LogOptions{})
 96+	if err != nil {
 97+		return "", err
 98+	}
 99+	c, err := l.Next()
100+	if err != nil {
101+		return "", err
102+	}
103+	f, err := c.File(fp)
104+	if err != nil {
105+		return "", err
106diff --git a/server/server.go b/server/server.go
107index 863e6b807daf7cdc05800774ab2c36ce323ab2e3..7b72f6ca3705571f3c31248994dbde0e91a636b8 100644
108--- a/server/server.go
109+++ b/server/server.go
110@@ -37,6 +37,7 @@ func NewServer(cfg *config.Config) *Server {
111 	mw := []wish.Middleware{
112 		rm.MiddlewareWithLogger(
113 			cfg.ErrorLog,
114+			softServeMiddleware(ac),
115 			bm.Middleware(tui.SessionHandler(ac)),
116 			gm.Middleware(cfg.RepoPath, ac),
117 			lm.Middleware(),