Refactor into middleware and server packages

Toby Padilla created

Change summary

main.go                              | 14 +++++++++--
server/middleware/bubbletea/tea.go   | 22 ++++++++++++++++++
server/middleware/git/git.go         | 11 +++-----
server/middleware/logging/logging.go | 19 +++++++++++++++
server/middleware/middleware.go      |  5 ++++
server/server.go                     | 36 ++---------------------------
6 files changed, 64 insertions(+), 43 deletions(-)

Detailed changes

main.go 🔗

@@ -2,6 +2,10 @@ package main
 
 import (
 	"log"
+	"smoothie/server"
+	bm "smoothie/server/middleware/bubbletea"
+	gm "smoothie/server/middleware/git"
+	lm "smoothie/server/middleware/logging"
 	"smoothie/tui"
 
 	tea "github.com/charmbracelet/bubbletea"
@@ -20,9 +24,13 @@ func main() {
 	if err != nil {
 		log.Fatalln(err)
 	}
-	btm := BubbleTeaMiddleware(tui.SessionHandler, tea.WithAltScreen())
-	gm := GitMiddleware(cfg.RepoPath)
-	s, err := NewServer(cfg.Port, cfg.KeyPath, btm, gm, LoggingMiddleware())
+	s, err := server.NewServer(
+		cfg.Port,
+		cfg.KeyPath,
+		bm.Middleware(tui.SessionHandler, tea.WithAltScreen()),
+		gm.Middleware(cfg.RepoPath),
+		lm.Middleware(),
+	)
 	if err != nil {
 		log.Fatalln(err)
 	}

server/middleware/bubbletea/tea.go 🔗

@@ -0,0 +1,22 @@
+package bubbletea
+
+import (
+	"smoothie/server/middleware"
+
+	tea "github.com/charmbracelet/bubbletea"
+	"github.com/gliderlabs/ssh"
+)
+
+func Middleware(bth func(ssh.Session) tea.Model, opts ...tea.ProgramOption) middleware.Middleware {
+	return func(sh ssh.Handler) ssh.Handler {
+		return func(s ssh.Session) {
+			m := bth(s)
+			if m != nil {
+				opts = append(opts, tea.WithInput(s), tea.WithOutput(s))
+				p := tea.NewProgram(m, opts...)
+				_ = p.Start()
+			}
+			sh(s)
+		}
+	}
+}

git.go → server/middleware/git/git.go 🔗

@@ -1,15 +1,16 @@
-package main
+package git
 
 import (
 	"context"
 	"fmt"
 	"os"
 	"os/exec"
+	"smoothie/server/middleware"
 
 	"github.com/gliderlabs/ssh"
 )
 
-func GitMiddleware(repoDir string) Middleware {
+func Middleware(repoDir string) middleware.Middleware {
 	return func(sh ssh.Handler) ssh.Handler {
 		return func(s ssh.Session) {
 			cmd := s.Command()
@@ -53,13 +54,9 @@ func fileExists(path string) (bool, error) {
 
 func fatalGit(s ssh.Session, err error) {
 	// hex length includes 4 byte length prefix and ending newline
-	logError(s, err)
 	msg := err.Error()
 	pktLine := fmt.Sprintf("%04x%s\n", len(msg)+5, msg)
-	_, err = s.Write([]byte(pktLine))
-	if err != nil {
-		logError(s, err)
-	}
+	_, _ = s.Write([]byte(pktLine))
 	s.Exit(1)
 }
 

server/middleware/logging/logging.go 🔗

@@ -0,0 +1,19 @@
+package logging
+
+import (
+	"log"
+	"smoothie/server/middleware"
+
+	"github.com/gliderlabs/ssh"
+)
+
+func Middleware() middleware.Middleware {
+	return func(sh ssh.Handler) ssh.Handler {
+		return func(s ssh.Session) {
+			hpk := s.PublicKey() != nil
+			log.Printf("%s connect %v %v\n", s.RemoteAddr().String(), hpk, s.Command())
+			sh(s)
+			log.Printf("%s disconnect %v %v\n", s.RemoteAddr().String(), hpk, s.Command())
+		}
+	}
+}

server.go → server/server.go 🔗

@@ -1,57 +1,27 @@
-package main
+package server
 
 import (
 	"fmt"
 	"log"
 	"path/filepath"
+	"smoothie/server/middleware"
 	"strings"
 
-	tea "github.com/charmbracelet/bubbletea"
 	"github.com/charmbracelet/charm/keygen"
 	"github.com/gliderlabs/ssh"
 	gossh "golang.org/x/crypto/ssh"
 )
 
-type Middleware func(ssh.Handler) ssh.Handler
-
-func LoggingMiddleware() Middleware {
-	return func(sh ssh.Handler) ssh.Handler {
-		return func(s ssh.Session) {
-			hpk := s.PublicKey() != nil
-			log.Printf("%s connect %v %v\n", s.RemoteAddr().String(), hpk, s.Command())
-			sh(s)
-			log.Printf("%s disconnect %v %v\n", s.RemoteAddr().String(), hpk, s.Command())
-		}
-	}
-}
-
 func logError(s ssh.Session, err error) {
 	log.Printf("%s error %v: %s\n", s.RemoteAddr().String(), s.Command(), err)
 }
 
-func BubbleTeaMiddleware(bth func(ssh.Session) tea.Model, opts ...tea.ProgramOption) Middleware {
-	return func(sh ssh.Handler) ssh.Handler {
-		return func(s ssh.Session) {
-			m := bth(s)
-			if m != nil {
-				opts = append(opts, tea.WithInput(s), tea.WithOutput(s))
-				p := tea.NewProgram(m, opts...)
-				err := p.Start()
-				if err != nil {
-					logError(s, err)
-				}
-			}
-			sh(s)
-		}
-	}
-}
-
 type Server struct {
 	server *ssh.Server
 	key    gossh.PublicKey
 }
 
-func NewServer(port int, keyPath string, mw ...Middleware) (*Server, error) {
+func NewServer(port int, keyPath string, mw ...middleware.Middleware) (*Server, error) {
 	s := &Server{server: &ssh.Server{}}
 	s.server.Version = "OpenSSH_7.6p1"
 	s.server.Addr = fmt.Sprintf(":%d", port)