3d7eb7bd4b207d2334a8661ca979f702c464218e

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

Message

feat: use context

Diff

This diff is truncated to protect this page.

  1diff --git a/cmd/soft/migrate_config.go b/cmd/soft/migrate_config.go
  2index e4731ab608bb1252b9786d0a995175157bc58387..ea03f751367c3430b18467f88a6f3ab6175f140a 100644
  3--- a/cmd/soft/migrate_config.go
  4+++ b/cmd/soft/migrate_config.go
  5@@ -23,12 +23,13 @@ var (
  6 	migrateConfig = &cobra.Command{
  7 		Use:   "migrate-config",
  8 		Short: "Migrate config to new format",
  9-		RunE: func(_ *cobra.Command, _ []string) error {
 10+		RunE: func(cmd *cobra.Command, _ []string) error {
 11 			keyPath := os.Getenv("SOFT_SERVE_KEY_PATH")
 12 			reposPath := os.Getenv("SOFT_SERVE_REPO_PATH")
 13 			bindAddr := os.Getenv("SOFT_SERVE_BIND_ADDRESS")
 14+			ctx := cmd.Context()
 15 			cfg := config.DefaultConfig()
 16-			sb, err := sqlite.NewSqliteBackend(cfg)
 17+			sb, err := sqlite.NewSqliteBackend(ctx, cfg)
 18 			if err != nil {
 19 				return fmt.Errorf("failed to create sqlite backend: %w", err)
 20 			}
 21diff --git a/cmd/soft/root.go b/cmd/soft/root.go
 22index af4c56c3f97d518e569e9b63aede54a2106808a6..44b6e8ab84f9631fa0fcfd069a90e17b60183f86 100644
 23--- a/cmd/soft/root.go
 24+++ b/cmd/soft/root.go
 25@@ -1,9 +1,11 @@
 26 package main
 27 
 28 import (
 29+	"context"
 30 	"os"
 31 	"runtime/debug"
 32 
 33+	"github.com/charmbracelet/log"
 34 	_ "github.com/charmbracelet/soft-serve/log"
 35 	"github.com/spf13/cobra"
 36 )
 37@@ -49,7 +51,17 @@ func init() {
 38 }
 39 
 40 func main() {
 41-	if err := rootCmd.Execute(); err != nil {
 42+	logger := log.NewWithOptions(os.Stderr, log.Options{
 43+		ReportTimestamp: true,
 44+		TimeFormat:      "2006-01-02",
 45+	})
 46+	if os.Getenv("SOFT_SERVE_DEBUG") == "true" {
 47+		logger.SetLevel(log.DebugLevel)
 48+	}
 49+
 50+	ctx := context.Background()
 51+	ctx = log.WithContext(ctx, logger)
 52+	if err := rootCmd.ExecuteContext(ctx); err != nil {
 53 		os.Exit(1)
 54 	}
 55 }
 56diff --git a/cmd/soft/serve.go b/cmd/soft/serve.go
 57index 5841f2cdd36113eab15b5b07fd0b5084e82f4012..f0d3a42151137795ef3d650b75fc50f60644f876 100644
 58--- a/cmd/soft/serve.go
 59+++ b/cmd/soft/serve.go
 60@@ -7,6 +7,7 @@ import (
 61 	"syscall"
 62 	"time"
 63 
 64+	_ "github.com/charmbracelet/soft-serve/log"
 65 	"github.com/charmbracelet/soft-serve/server"
 66 	"github.com/charmbracelet/soft-serve/server/config"
 67 	"github.com/spf13/cobra"
 68@@ -19,19 +20,19 @@ var (
 69 		Long:  "Start the server",
 70 		Args:  cobra.NoArgs,
 71 		RunE: func(cmd *cobra.Command, args []string) error {
 72+			ctx := cmd.Context()
 73 			cfg := config.DefaultConfig()
 74-			s, err := server.NewServer(cfg)
 75+			s, err := server.NewServer(ctx, cfg)
 76 			if err != nil {
 77 				return err
 78 			}
 79 
 80-			ctx := cmd.Context()
 81 			done := make(chan os.Signal, 1)
 82 			lch := make(chan error, 1)
 83 			go func() {
 84 				defer close(lch)
 85 				defer close(done)
 86-				lch <- s.Start(ctx)
 87+				lch <- s.Start()
 88 			}()
 89 
 90 			signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
 91diff --git a/examples/setuid/main.go b/examples/setuid/main.go
 92index 8999dbcc25fe9f2c379c5d46ddd2f998da524067..e9cc1f751a431c961e36d050fa62f809479bd8c1 100644
 93--- a/examples/setuid/main.go
 94+++ b/examples/setuid/main.go
 95@@ -44,9 +44,10 @@ func main() {
 96 	if err := syscall.Setuid(*uid); err != nil {
 97 		log.Fatal("Setuid error", "err", err)
 98 	}
 99+	ctx := context.Background()
100 	cfg := config.DefaultConfig()
101 	cfg.SSH.ListenAddr = fmt.Sprintf(":%d", *port)
102-	s, err := server.NewServer(cfg)
103+	s, err := server.NewServer(ctx, cfg)
104 	if err != nil {
105 		log.Fatal(err)
106 	}
107@@ -64,7 +65,7 @@ func main() {
108 	<-done
109 
110 	log.Print("Stopping SSH server", "addr", cfg.SSH.ListenAddr)
111-	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
112+	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
113 	defer func() { cancel() }()
114 	if err := s.Shutdown(ctx); err != nil {
115 		log.Fatal(err)
116diff --git a/server/backend/sqlite/sqlite.go b/server/backend/sqlite/sqlite.go
117index d3dcb81ade248ca0ecb7fa688978d37a0413e8fc..fe73c57238cba7c6c0abdbdb90e6598daaa9e982 100644
118--- a/server/backend/sqlite/sqlite.go
119+++ b/server/backend/sqlite/sqlite.go
120@@ -26,6 +26,7 @@ var (
121 // backend.
122 type SqliteBackend struct {
123 	cfg *config.Config
124+	ctx context.Context
125 	dp  string
126 	db  *sqlx.DB
127 }
128@@ -37,7 +38,7 @@ func (d *SqliteBackend) reposPath() string {
129 }
130 
131 // NewSqliteBackend creates a new SqliteBackend.
132-func NewSqliteBackend(cfg *config.Config) (*SqliteBackend, error) {
133+func NewSqliteBackend(ctx context.Context, cfg *config.Config) (*SqliteBackend, error) {
134 	dataPath := cfg.DataPath
135 	if err := os.MkdirAll(dataPath, 0755); err != nil {
136 		return nil, err
137@@ -51,6 +52,7 @@ func NewSqliteBackend(cfg *config.Config) (*SqliteBackend, error) {
138 
139 	d := &SqliteBackend{
140 		cfg: cfg,
141+		ctx: ctx,
142 		dp:  dataPath,
143 		db:  db,
144 	}
145@@ -71,7 +73,7 @@ func NewSqliteBackend(cfg *config.Config) (*SqliteBackend, error) {
146 // It implements backend.Backend.
147 func (d *SqliteBackend) AllowKeyless() bool {
148 	var allow bool
149-	if err := wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error {
150+	if err := wrapTx(d.db, d.ctx, func(tx *sqlx.Tx) error {
151 		return tx.Get(&allow, "SELECT value FROM settings WHERE key = ?;", "allow_keyless")
152 	}); err != nil {
153 		return false
154@@ -85,7 +87,7 @@ func (d *SqliteBackend) AllowKeyless() bool {
155 // It implements backend.Backend.
156 func (d *SqliteBackend) AnonAccess() backend.AccessLevel {
157 	var level string
158-	if err := wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error {
159+	if err := wrapTx(d.db, d.ctx, func(tx *sqlx.Tx) error {
160 		return tx.Get(&level, "SELECT value FROM settings WHERE key = ?;", "anon_access")
161 	}); err != nil {
162 		return backend.NoAccess
163@@ -99,7 +101,7 @@ func (d *SqliteBackend) AnonAccess() backend.AccessLevel {
164 // It implements backend.Backend.
165 func (d *SqliteBackend) SetAllowKeyless(allow bool) error {
166 	return wrapDbErr(
167-		wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error {
168+		wrapTx(d.db, d.ctx, func(tx *sqlx.Tx) error {
169 			_, err := tx.Exec("UPDATE settings SET value = ?, updated_at = CURRENT_TIMESTAMP WHERE key = ?;", allow, "allow_keyless")
170 			return err
171 		}),
172@@ -111,7 +113,7 @@ func (d *SqliteBackend) SetAllowKeyless(allow bool) error {
173 // It implements backend.Backend.
174 func (d *SqliteBackend) SetAnonAccess(level backend.AccessLevel) error {
175 	return wrapDbErr(
176-		wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error {
177+		wrapTx(d.db, d.ctx, func(tx *sqlx.Tx) error {
178 			_, err := tx.Exec("UPDATE settings SET value = ?, updated_at = CURRENT_TIMESTAMP WHERE key = ?;", level.String(), "anon_access")
179 			return err
180 		}),
181@@ -147,7 +149,7 @@ func (d *SqliteBackend) CreateRepository(name string, opts backend.RepositoryOpt
182 		return nil, err
183 	}
184 
185-	if err := wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error {
186+	if err := wrapTx(d.db, d.ctx, func(tx *sqlx.Tx) error {
187 		_, err := tx.Exec(`INSERT INTO repo (name, project_name, description, private, mirror, hidden, updated_at)
188 			VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP);`,
189 			name, opts.ProjectName, opts.Description, opts.Private, opts.Mirror, opts.Hidden)
190@@ -210,7 +212,7 @@ func (d *SqliteBackend) DeleteRepository(name string) error {
191 		return os.ErrNotExist
192 	}
193 
194-	if err := wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error {
195+	if err := wrapTx(d.db, d.ctx, func(tx *sqlx.Tx) error {
196 		_, err := tx.Exec("DELETE FROM repo WHERE name = ?;", name)
197 		return err
198 	}); err != nil {
199@@ -245,7 +247,7 @@ func (d *SqliteBackend) RenameRepository(oldName string, newName string) error {
200 		return fmt.Errorf("repository %s already exists", newName)
201 	}
202 
203-	if err := wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error {
204+	if err := wrapTx(d.db, d.ctx, func(tx *sqlx.Tx) error {
205 		_, err := tx.Exec("UPDATE repo SET name = ?, updated_at = CURRENT_TIMESTAMP WHERE name = ?;", newName, oldName)
206 		return err
207 	}); err != nil {
208@@ -260,7 +262,7 @@ func (d *SqliteBackend) RenameRepository(oldName string, newName string) error {
209 // It implements backend.Backend.
210 func (d *SqliteBackend) Repositories() ([]backend.Repository, error) {
211 	repos := make([]backend.Repository, 0)
212-	if err := wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error {
213+	if err := wrapTx(d.db, d.ctx, func(tx *sqlx.Tx) error {
214 		rows, err := tx.Query("SELECT name FROM repo")
215 		if err != nil {
216 			return err
217@@ -299,7 +301,7 @@ func (d *SqliteBackend) Repository(repo string) (backend.Repository, error) {
218 	}
219 
220diff --git a/server/config/config.go b/server/config/config.go
221index ea4e42408ab4b8c26c7f9fc62b65d00290dd1005..032f566ba50155d1d283423616e3a18dd1900a41 100644
222--- a/server/config/config.go
223+++ b/server/config/config.go
224@@ -10,10 +10,6 @@ import (
225 	"gopkg.in/yaml.v3"
226 )
227 
228-var (
229-	logger = log.WithPrefix("server.config")
230-)
231-
232 // SSHConfig is the configuration for the SSH server.
233 type SSHConfig struct {
234 	// ListenAddr is the address on which the SSH server will listen.
235diff --git a/server/cron/cron.go b/server/cron/cron.go
236index b86b0eacf6b96c6d6e52c86a7de984efac504dbb..27e052dee20e8aeaa4dc77d2530a4f4ab87ef02d 100644
237--- a/server/cron/cron.go
238+++ b/server/cron/cron.go
239@@ -38,8 +38,8 @@ func (l cronLogger) Error(err error, msg string, keysAndValues ...interface{}) {
240 }
241 
242 // NewCronScheduler returns a new Cron.
243-func NewCronScheduler() *CronScheduler {
244-	logger := cronLogger{log.WithPrefix("server.cron")}
245+func NewCronScheduler(ctx context.Context) *CronScheduler {
246+	logger := cronLogger{log.FromContext(ctx).WithPrefix("server.cron")}
247 	return &CronScheduler{
248 		Cron: cron.New(cron.WithLogger(logger)),
249 	}
250diff --git a/server/daemon_test.go b/server/daemon_test.go
251index 4b5899ddd33341be670bb1426071e270713ca4c9..765e62c9a84cc7240529768e04744a982f46e573 100644
252--- a/server/daemon_test.go
253+++ b/server/daemon_test.go
254@@ -2,6 +2,7 @@ package server
255 
256 import (
257 	"bytes"
258+	"context"
259 	"errors"
260 	"fmt"
261 	"io"
262@@ -34,7 +35,8 @@ func TestMain(m *testing.M) {
263 	if err != nil {
264 		log.Fatal(err)
265 	}
266-	fb, err := sqlite.NewSqliteBackend(cfg)
267+	ctx := context.TODO()
268+	fb, err := sqlite.NewSqliteBackend(ctx, cfg)
269 	if err != nil {
270 		log.Fatal(err)
271 	}
272diff --git a/server/server.go b/server/server.go
273index beee1fa744ecc660e0274d5858750ef1e26aa945..b4645f3cab1262667c37a07bd6e2c15763085f8e 100644
274--- a/server/server.go
275+++ b/server/server.go
276@@ -30,6 +30,7 @@ type Server struct {
277 	Cron        *cron.CronScheduler
278 	Config      *config.Config
279 	Backend     backend.Backend
280+	ctx         context.Context
281 }
282 
283 // NewServer returns a new *ssh.Server configured to serve Soft Serve. The SSH
284@@ -37,10 +38,10 @@ type Server struct {
285 // key can be provided with authKey. If authKey is provided, access will be
286 // restricted to that key. If authKey is not provided, the server will be
287 // publicly writable until configured otherwise by cloning the `config` repo.
288-func NewServer(cfg *config.Config) (*Server, error) {
289+func NewServer(ctx context.Context, cfg *config.Config) (*Server, error) {
290 	var err error
291 	if cfg.Backend == nil {
292-		sb, err := sqlite.NewSqliteBackend(cfg)
293+		sb, err := sqlite.NewSqliteBackend(ctx, cfg)
294 		if err != nil {
295 			logger.Fatal(err)
296 		}
297@@ -71,9 +72,10 @@ func NewServer(cfg *config.Config) (*Server, error) {
298 	}
299 
300 	srv := &Server{
301-		Cron:    cron.NewCronScheduler(),
302+		Cron:    cron.NewCronScheduler(ctx),
303 		Config:  cfg,
304 		Backend: cfg.Backend,
305+		ctx:     ctx,
306 	}
307 
308 	// Add cron jobs.
309@@ -117,39 +119,39 @@ func start(ctx context.Context, fn func() error) error {
310 }
311 
312 // Start starts the SSH server.
313-func (s *Server) Start(ctx context.Context) error {
314-	var errg *errgroup.Group
315-	errg, ctx = errgroup.WithContext(ctx)
316+func (s *Server) Start() error {
317+	logger := log.FromContext(s.ctx).WithPrefix("server")
318+	errg, ctx := errgroup.WithContext(s.ctx)
319 	errg.Go(func() error {
320-		log.Print("Starting Git daemon", "addr", s.Config.Git.ListenAddr)
321+		logger.Print("Starting Git daemon", "addr", s.Config.Git.ListenAddr)
322 		if err := start(ctx, s.GitDaemon.Start); !errors.Is(err, ErrServerClosed) {
323 			return err
324 		}
325 		return nil
326 	})
327 	errg.Go(func() error {
328-		log.Print("Starting HTTP server", "addr", s.Config.HTTP.ListenAddr)
329+		logger.Print("Starting HTTP server", "addr", s.Config.HTTP.ListenAddr)
330 		if err := start(ctx, s.HTTPServer.ListenAndServe); !errors.Is(err, http.ErrServerClosed) {
331 			return err
332 		}
333 		return nil
334 	})
335 	errg.Go(func() error {
336-		log.Print("Starting SSH server", "addr", s.Config.SSH.ListenAddr)
337+		logger.Print("Starting SSH server", "addr", s.Config.SSH.ListenAddr)
338 		if err := start(ctx, s.SSHServer.ListenAndServe); !errors.Is(err, ssh.ErrServerClosed) {
339 			return err
340 		}
341 		return nil
342 	})
343 	errg.Go(func() error {
344-		log.Print("Starting Stats server", "addr", s.Config.Stats.ListenAddr)
345+		logger.Print("Starting Stats server", "addr", s.Config.Stats.ListenAddr)
346 		if err := start(ctx, s.StatsServer.ListenAndServe); !errors.Is(err, http.ErrServerClosed) {
347 			return err
348 		}
349 		return nil
350 	})
351 	errg.Go(func() error {
352-		log.Print("Starting cron scheduler")
353+		logger.Print("Starting cron scheduler")
354 		s.Cron.Start()
355 		return nil
356 	})
357diff --git a/server/server_test.go b/server/server_test.go
358index 07066d976412aacb4f1fb174609587a4731edac2..3992794e936426dcce2a477921552811666512bc 100644
359--- a/server/server_test.go
360+++ b/server/server_test.go
361@@ -33,13 +33,14 @@ func setupServer(tb testing.TB) (*Server, *config.Config, string) {
362 	tb.Setenv("SOFT_SERVE_GIT_LISTEN_ADDR", fmt.Sprintf(":%d", randomPort()))
363 	cfg := config.DefaultConfig()
364 	tb.Log("configuring server")
365-	s, err := NewServer(cfg)
366+	ctx := context.TODO()
367+	s, err := NewServer(ctx, cfg)
368 	if err != nil {
369 		tb.Fatal(err)
370 	}
371 	go func() {
372 		tb.Log("starting server")
373-		s.Start(context.TODO())
374+		s.Start()
375 	}()
376 	tb.Cleanup(func() {
377 		s.Close()
378diff --git a/server/session_test.go b/server/session_test.go
379index 56c0b59efc3872bf3e2b2c22f2cb335af61a3720..673e85a6099668009d6499ee4bfe70c812507214 100644
380--- a/server/session_test.go
381+++ b/server/session_test.go
382@@ -1,6 +1,7 @@
383 package server
384 
385 import (
386+	"context"
387 	"errors"
388 	"fmt"
389 	"log"
390@@ -55,8 +56,9 @@ func setup(tb testing.TB) (*gossh.Session, func() error) {
391 		is.NoErr(os.Unsetenv("SOFT_SERVE_SSH_LISTEN_ADDR"))
392 		is.NoErr(os.RemoveAll(dp))
393 	})
394+	ctx := context.TODO()
395 	cfg := config.DefaultConfig()
396-	fb, err := sqlite.NewSqliteBackend(cfg)
397+	fb, err := sqlite.NewSqliteBackend(ctx, cfg)
398 	if err != nil {
399 		log.Fatal(err)
400 	}