Diff
1diff --git a/internal/config/config.go b/internal/config/config.go
2index 8c716305a5cee07abe6cbff2c2786cf7d0f70e6c..430c1fba814c67780d11bb3a7d3c67633337f3c7 100644
3--- a/internal/config/config.go
4+++ b/internal/config/config.go
5@@ -8,6 +8,7 @@ import (
6 "path/filepath"
7
8 "github.com/charmbracelet/soft/internal/git"
9+ "github.com/charmbracelet/soft/stats"
10 gg "github.com/go-git/go-git/v5"
11 "github.com/go-git/go-git/v5/plumbing/object"
12 )
13@@ -21,6 +22,7 @@ type Config struct {
14 Users []User `yaml:"users"`
15 Repos []Repo `yaml:"repos"`
16 Source *git.RepoSource
17+ Stats stats.Stats
18 }
19
20 type User struct {
21@@ -37,6 +39,11 @@ type Repo struct {
22 Private bool `yaml:"private"`
23 }
24
25+func (cfg *Config) WithStats(s stats.Stats) *Config {
26+ cfg.Stats = s
27+ return cfg
28+}
29+
30 func NewConfig(host string, port int, pk string, rs *git.RepoSource) (*Config, error) {
31 var anonAccess string
32 var yamlUsers string
33diff --git a/internal/config/git.go b/internal/config/git.go
34index c2569b20f1b6b06f54faac2319dd116840d1f7d1..184dde11e1d84f0cf04dd5c3b462546c2195806d 100644
35--- a/internal/config/git.go
36+++ b/internal/config/git.go
37@@ -13,10 +13,16 @@ func (cfg *Config) Push(repo string, pk ssh.PublicKey) {
38 if err != nil {
39 log.Printf("error reloading after push: %s", err)
40 }
41+ if cfg.Stats != nil {
42+ cfg.Stats.Push()
43+ }
44 }
45
46 func (cfg *Config) Fetch(repo string, pk ssh.PublicKey) {
47 log.Printf("git fetch: %s", repo)
48+ if cfg.Stats != nil {
49+ cfg.Stats.Fetch()
50+ }
51 }
52
53 func (cfg *Config) AuthRepo(repo string, pk ssh.PublicKey) gm.AccessLevel {
54@@ -28,10 +34,7 @@ func (cfg *Config) PasswordHandler(ctx ssh.Context, password string) bool {
55 }
56
57 func (cfg *Config) PublicKeyHandler(ctx ssh.Context, pk ssh.PublicKey) bool {
58- if cfg.accessForKey("", pk) == gm.NoAccess {
59- return false
60- }
61- return true
62+ return cfg.accessForKey("", pk) == gm.NoAccess
63 }
64
65 func (cfg *Config) accessForKey(repo string, pk ssh.PublicKey) gm.AccessLevel {
66diff --git a/internal/tui/session.go b/internal/tui/session.go
67index 848cb56718e2400890d69719b15843c53932c77b..8bdd5c5d5b56ac7f409f9d4f897848c626914346 100644
68--- a/internal/tui/session.go
69+++ b/internal/tui/session.go
70@@ -27,6 +27,9 @@ func SessionHandler(cfg *config.Config) func(ssh.Session) (tea.Model, []tea.Prog
71 }
72 scfg.Width = pty.Window.Width
73 scfg.Height = pty.Window.Height
74+ if cfg.Stats != nil {
75+ cfg.Stats.Tui()
76+ }
77 return NewBubble(cfg, scfg), []tea.ProgramOption{tea.WithAltScreen()}
78 }
79 }
80diff --git a/server.go b/server.go
81index 4144896e2fc2842867e73b79252f6fbaf2cf6a2f..51fcf2b9d0119b58d190b64850067cb7bbd1a53d 100644
82--- a/server.go
83+++ b/server.go
84@@ -24,8 +24,8 @@ type Config struct {
85 KeyPath string `env:"SOFT_SERVE_KEY_PATH" default:".ssh/soft_serve_server_ed25519"`
86 RepoPath string `env:"SOFT_SERVE_REPO_PATH" default:".repos"`
87 InitialAdminKey string `env:"SOFT_SERVE_INITIAL_ADMIN_KEY" default:""`
88- Cfg *config.Config
89 Stats stats.Stats
90+ cfg *config.Config
91 }
92
93 // DefaultConfig returns a Config with the values populated with the defaults
94@@ -50,15 +50,15 @@ func NewServer(scfg *Config) *ssh.Server {
95 if err != nil {
96 log.Fatalln(err)
97 }
98- scfg.Cfg = cfg
99+ if scfg.Stats != nil {
100+ cfg = cfg.WithStats(scfg.Stats)
101+ }
102+ scfg.cfg = cfg
103 mw := []wish.Middleware{
104 bm.Middleware(tui.SessionHandler(cfg)),
105 gm.Middleware(scfg.RepoPath, cfg),
106 lm.Middleware(),
107 }
108- if scfg.Stats != nil {
109- mw = append(mw, stats.Middleware(scfg.Stats))
110- }
111 s, err := wish.NewServer(
112 ssh.PublicKeyAuth(cfg.PublicKeyHandler),
113 ssh.PasswordAuth(cfg.PasswordHandler),
114diff --git a/stats/stats.go b/stats/stats.go
115new file mode 100644
116index 0000000000000000000000000000000000000000..847cce8bba9d88ca15aec3b6dcf17ff2af8f8a11
117--- /dev/null
118+++ b/stats/stats.go
119@@ -0,0 +1,8 @@
120+package stats
121+
122+// Stats provides an interface that can be used to collect metrics about the server.
123+type Stats interface {
124+ Tui()
125+ Push()
126+ Fetch()
127+}