Add stats interface

Ayman Bagabas created

Change summary

internal/config/config.go |  7 +++++++
internal/config/git.go    | 11 +++++++----
internal/tui/session.go   |  3 +++
server.go                 | 10 +++++-----
stats/stats.go            |  8 ++++++++
5 files changed, 30 insertions(+), 9 deletions(-)

Detailed changes

internal/config/config.go 🔗

@@ -8,6 +8,7 @@ import (
 	"path/filepath"
 
 	"github.com/charmbracelet/soft/internal/git"
+	"github.com/charmbracelet/soft/stats"
 	gg "github.com/go-git/go-git/v5"
 	"github.com/go-git/go-git/v5/plumbing/object"
 )
@@ -21,6 +22,7 @@ type Config struct {
 	Users        []User `yaml:"users"`
 	Repos        []Repo `yaml:"repos"`
 	Source       *git.RepoSource
+	Stats        stats.Stats
 }
 
 type User struct {
@@ -37,6 +39,11 @@ type Repo struct {
 	Private bool   `yaml:"private"`
 }
 
+func (cfg *Config) WithStats(s stats.Stats) *Config {
+	cfg.Stats = s
+	return cfg
+}
+
 func NewConfig(host string, port int, pk string, rs *git.RepoSource) (*Config, error) {
 	var anonAccess string
 	var yamlUsers string

internal/config/git.go 🔗

@@ -13,10 +13,16 @@ func (cfg *Config) Push(repo string, pk ssh.PublicKey) {
 	if err != nil {
 		log.Printf("error reloading after push: %s", err)
 	}
+	if cfg.Stats != nil {
+		cfg.Stats.Push()
+	}
 }
 
 func (cfg *Config) Fetch(repo string, pk ssh.PublicKey) {
 	log.Printf("git fetch: %s", repo)
+	if cfg.Stats != nil {
+		cfg.Stats.Fetch()
+	}
 }
 
 func (cfg *Config) AuthRepo(repo string, pk ssh.PublicKey) gm.AccessLevel {
@@ -28,10 +34,7 @@ func (cfg *Config) PasswordHandler(ctx ssh.Context, password string) bool {
 }
 
 func (cfg *Config) PublicKeyHandler(ctx ssh.Context, pk ssh.PublicKey) bool {
-	if cfg.accessForKey("", pk) == gm.NoAccess {
-		return false
-	}
-	return true
+	return cfg.accessForKey("", pk) == gm.NoAccess
 }
 
 func (cfg *Config) accessForKey(repo string, pk ssh.PublicKey) gm.AccessLevel {

internal/tui/session.go 🔗

@@ -27,6 +27,9 @@ func SessionHandler(cfg *config.Config) func(ssh.Session) (tea.Model, []tea.Prog
 		}
 		scfg.Width = pty.Window.Width
 		scfg.Height = pty.Window.Height
+		if cfg.Stats != nil {
+			cfg.Stats.Tui()
+		}
 		return NewBubble(cfg, scfg), []tea.ProgramOption{tea.WithAltScreen()}
 	}
 }

server.go 🔗

@@ -24,8 +24,8 @@ type Config struct {
 	KeyPath         string `env:"SOFT_SERVE_KEY_PATH" default:".ssh/soft_serve_server_ed25519"`
 	RepoPath        string `env:"SOFT_SERVE_REPO_PATH" default:".repos"`
 	InitialAdminKey string `env:"SOFT_SERVE_INITIAL_ADMIN_KEY" default:""`
-	Cfg             *config.Config
 	Stats           stats.Stats
+	cfg             *config.Config
 }
 
 // DefaultConfig returns a Config with the values populated with the defaults
@@ -50,15 +50,15 @@ func NewServer(scfg *Config) *ssh.Server {
 	if err != nil {
 		log.Fatalln(err)
 	}
-	scfg.Cfg = cfg
+	if scfg.Stats != nil {
+		cfg = cfg.WithStats(scfg.Stats)
+	}
+	scfg.cfg = cfg
 	mw := []wish.Middleware{
 		bm.Middleware(tui.SessionHandler(cfg)),
 		gm.Middleware(scfg.RepoPath, cfg),
 		lm.Middleware(),
 	}
-	if scfg.Stats != nil {
-		mw = append(mw, stats.Middleware(scfg.Stats))
-	}
 	s, err := wish.NewServer(
 		ssh.PublicKeyAuth(cfg.PublicKeyHandler),
 		ssh.PasswordAuth(cfg.PasswordHandler),

stats/stats.go 🔗

@@ -0,0 +1,8 @@
+package stats
+
+// Stats provides an interface that can be used to collect metrics about the server.
+type Stats interface {
+	Tui()
+	Push()
+	Fetch()
+}