feat(cmd): new cmd middleware

Ayman Bagabas created

Set repository properties and show/list files

Change summary

server/cmd/cat.go        | 130 ------------
server/cmd/cmd.go        |   5 
server/cmd/git.go        |  62 ------
server/cmd/list.go       |  87 --------
server/cmd/middleware.go |   2 
server/cmd/reload.go     |  23 --
server/cmd/repo.go       | 427 ++++++++++++++++++++++++++++++++++++++++++
server/server.go         |   6 
server/server_test.go    |   9 
9 files changed, 431 insertions(+), 320 deletions(-)

Detailed changes

server/cmd/cat.go 🔗

@@ -1,130 +0,0 @@
-package cmd
-
-import (
-	"fmt"
-	"strings"
-
-	"github.com/alecthomas/chroma/lexers"
-	gansi "github.com/charmbracelet/glamour/ansi"
-	"github.com/charmbracelet/lipgloss"
-	"github.com/charmbracelet/soft-serve/proto"
-	"github.com/charmbracelet/soft-serve/ui/common"
-	"github.com/muesli/termenv"
-	"github.com/spf13/cobra"
-)
-
-var (
-	lineDigitStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("239"))
-	lineBarStyle   = lipgloss.NewStyle().Foreground(lipgloss.Color("236"))
-	dirnameStyle   = lipgloss.NewStyle().Foreground(lipgloss.Color("#00AAFF"))
-	filenameStyle  = lipgloss.NewStyle()
-	filemodeStyle  = lipgloss.NewStyle().Foreground(lipgloss.Color("#777777"))
-)
-
-// CatCommand returns a command that prints the contents of a file.
-func CatCommand() *cobra.Command {
-	var linenumber bool
-	var color bool
-
-	catCmd := &cobra.Command{
-		Use:   "cat PATH",
-		Short: "Outputs the contents of the file at path.",
-		Args:  cobra.ExactArgs(1),
-		RunE: func(cmd *cobra.Command, args []string) error {
-			cfg, s := fromContext(cmd)
-			ps := strings.Split(args[0], "/")
-			rn := strings.TrimSuffix(ps[0], ".git")
-			fp := strings.Join(ps[1:], "/")
-			auth := cfg.AuthRepo(rn, s.PublicKey())
-			if auth < proto.ReadOnlyAccess {
-				return ErrUnauthorized
-			}
-			var repo proto.Repository
-			repoExists := false
-			repos, err := cfg.ListRepos()
-			if err != nil {
-				return err
-			}
-			for _, rp := range repos {
-				if rp.Name() == rn {
-					re, err := rp.Open()
-					if err != nil {
-						continue
-					}
-					repoExists = true
-					repo = re
-					break
-				}
-			}
-			if !repoExists {
-				return ErrRepoNotFound
-			}
-			c, _, err := proto.LatestFile(repo, fp)
-			if err != nil {
-				return err
-			}
-			if color {
-				c, err = withFormatting(fp, c)
-				if err != nil {
-					return err
-				}
-			}
-			if linenumber {
-				c = withLineNumber(c, color)
-			}
-			fmt.Fprint(s, c)
-			return nil
-		},
-	}
-	catCmd.Flags().BoolVarP(&linenumber, "linenumber", "l", false, "Print line numbers")
-	catCmd.Flags().BoolVarP(&color, "color", "c", false, "Colorize output")
-
-	return catCmd
-}
-
-func withLineNumber(s string, color bool) string {
-	lines := strings.Split(s, "\n")
-	// NB: len() is not a particularly safe way to count string width (because
-	// it's counting bytes instead of runes) but in this case it's okay
-	// because we're only dealing with digits, which are one byte each.
-	mll := len(fmt.Sprintf("%d", len(lines)))
-	for i, l := range lines {
-		digit := fmt.Sprintf("%*d", mll, i+1)
-		bar := "│"
-		if color {
-			digit = lineDigitStyle.Render(digit)
-			bar = lineBarStyle.Render(bar)
-		}
-		if i < len(lines)-1 || len(l) != 0 {
-			// If the final line was a newline we'll get an empty string for
-			// the final line, so drop the newline altogether.
-			lines[i] = fmt.Sprintf(" %s %s %s", digit, bar, l)
-		}
-	}
-	return strings.Join(lines, "\n")
-}
-
-func withFormatting(p, c string) (string, error) {
-	zero := uint(0)
-	lang := ""
-	lexer := lexers.Match(p)
-	if lexer != nil && lexer.Config() != nil {
-		lang = lexer.Config().Name
-	}
-	formatter := &gansi.CodeBlockElement{
-		Code:     c,
-		Language: lang,
-	}
-	r := strings.Builder{}
-	styles := common.StyleConfig()
-	styles.CodeBlock.Margin = &zero
-	rctx := gansi.NewRenderContext(gansi.Options{
-		Styles:       styles,
-		ColorProfile: termenv.TrueColor,
-	})
-	err := formatter.Render(&r, rctx)
-	if err != nil {
-		return "", err
-	}
-	return r.String(), nil
-}

server/cmd/cmd.go 🔗

@@ -68,10 +68,7 @@ func RootCommand() *cobra.Command {
 	rootCmd.SetUsageTemplate(usageTemplate)
 	rootCmd.CompletionOptions.DisableDefaultCmd = true
 	rootCmd.AddCommand(
-		ReloadCommand(),
-		CatCommand(),
-		ListCommand(),
-		GitCommand(),
+		RepoCommand(),
 	)
 
 	return rootCmd

server/cmd/git.go 🔗

@@ -1,62 +0,0 @@
-package cmd
-
-import (
-	"io"
-	"os/exec"
-
-	"github.com/charmbracelet/soft-serve/proto"
-	"github.com/spf13/cobra"
-)
-
-// TODO: remove this command.
-// GitCommand returns a command that handles Git operations.
-func GitCommand() *cobra.Command {
-	gitCmd := &cobra.Command{
-		Use:   "git REPO COMMAND",
-		Short: "Perform Git operations on a repository.",
-		RunE: func(cmd *cobra.Command, args []string) error {
-			cfg, s := fromContext(cmd)
-			auth := cfg.AuthRepo("config", s.PublicKey())
-			if auth < proto.AdminAccess {
-				return ErrUnauthorized
-			}
-			if len(args) < 1 {
-				return runGit(nil, s, s, "")
-			}
-			var repo proto.Repository
-			rn := args[0]
-			repoExists := false
-			repos, err := cfg.ListRepos()
-			if err != nil {
-				return err
-			}
-			for _, rp := range repos {
-				if rp.Name() == rn {
-					re, err := rp.Open()
-					if err != nil {
-						continue
-					}
-					repoExists = true
-					repo = re
-					break
-				}
-			}
-			if !repoExists {
-				return ErrRepoNotFound
-			}
-			return runGit(nil, s, s, repo.Repository().Path, args[1:]...)
-		},
-	}
-	gitCmd.Flags().SetInterspersed(false)
-
-	return gitCmd
-}
-
-func runGit(in io.Reader, out, err io.Writer, dir string, args ...string) error {
-	cmd := exec.Command("git", args...)
-	cmd.Stdin = in
-	cmd.Stdout = out
-	cmd.Stderr = err
-	cmd.Dir = dir
-	return cmd.Run()
-}

server/cmd/list.go 🔗

@@ -1,87 +0,0 @@
-package cmd
-
-import (
-	"fmt"
-	"path/filepath"
-	"strings"
-
-	"github.com/charmbracelet/soft-serve/git"
-	"github.com/charmbracelet/soft-serve/proto"
-	"github.com/spf13/cobra"
-)
-
-// ListCommand returns a command that list file or directory at path.
-func ListCommand() *cobra.Command {
-	lsCmd := &cobra.Command{
-		Use:     "ls PATH",
-		Aliases: []string{"list"},
-		Short:   "List file or directory at path.",
-		Args:    cobra.RangeArgs(0, 1),
-		RunE: func(cmd *cobra.Command, args []string) error {
-			cfg, s := fromContext(cmd)
-			rn := ""
-			path := ""
-			ps := []string{}
-			if len(args) > 0 {
-				path = filepath.Clean(args[0])
-				ps = strings.Split(path, "/")
-				rn = strings.TrimSuffix(ps[0], ".git")
-				auth := cfg.AuthRepo(rn, s.PublicKey())
-				if auth < proto.ReadOnlyAccess {
-					return ErrUnauthorized
-				}
-			}
-			if path == "" || path == "." || path == "/" {
-				repos, err := cfg.ListRepos()
-				if err != nil {
-					return err
-				}
-				for _, r := range repos {
-					if cfg.AuthRepo(r.Name(), s.PublicKey()) >= proto.ReadOnlyAccess {
-						fmt.Fprintln(s, r.Name())
-					}
-				}
-				return nil
-			}
-			r, err := cfg.Open(rn)
-			if err != nil {
-				return err
-			}
-			head, err := r.Repository().HEAD()
-			if err != nil {
-				return err
-			}
-			tree, err := r.Repository().TreePath(head, "")
-			if err != nil {
-				return err
-			}
-			subpath := strings.Join(ps[1:], "/")
-			ents := git.Entries{}
-			te, err := tree.TreeEntry(subpath)
-			if err == git.ErrRevisionNotExist {
-				return ErrFileNotFound
-			}
-			if err != nil {
-				return err
-			}
-			if te.Type() == "tree" {
-				tree, err = tree.SubTree(subpath)
-				if err != nil {
-					return err
-				}
-				ents, err = tree.Entries()
-				if err != nil {
-					return err
-				}
-			} else {
-				ents = append(ents, te)
-			}
-			ents.Sort()
-			for _, ent := range ents {
-				fmt.Fprintf(s, "%s\t%d\t %s\n", ent.Mode(), ent.Size(), ent.Name())
-			}
-			return nil
-		},
-	}
-	return lsCmd
-}

server/cmd/middleware.go 🔗

@@ -22,7 +22,7 @@ func Middleware(cfg *config.Config) wish.Middleware {
 				ctx = context.WithValue(ctx, SessionCtxKey, s)
 
 				use := "ssh"
-				port := cfg.Port
+				port := cfg.SSH.Port
 				if port != 22 {
 					use += fmt.Sprintf(" -p%d", port)
 				}

server/cmd/reload.go 🔗

@@ -1,23 +0,0 @@
-package cmd
-
-import (
-	"github.com/charmbracelet/soft-serve/proto"
-	"github.com/spf13/cobra"
-)
-
-// ReloadCommand returns a command that reloads the server configuration.
-func ReloadCommand() *cobra.Command {
-	reloadCmd := &cobra.Command{
-		Use:   "reload",
-		Short: "Reloads the configuration",
-		RunE: func(cmd *cobra.Command, args []string) error {
-			cfg, s := fromContext(cmd)
-			auth := cfg.AuthRepo("config", s.PublicKey())
-			if auth < proto.AdminAccess {
-				return ErrUnauthorized
-			}
-			return nil
-		},
-	}
-	return reloadCmd
-}

server/cmd/repo.go 🔗

@@ -0,0 +1,427 @@
+package cmd
+
+import (
+	"fmt"
+	"path/filepath"
+	"strconv"
+	"strings"
+
+	"github.com/alecthomas/chroma/lexers"
+	gansi "github.com/charmbracelet/glamour/ansi"
+	"github.com/charmbracelet/lipgloss"
+	"github.com/charmbracelet/soft-serve/git"
+	"github.com/charmbracelet/soft-serve/proto"
+	"github.com/charmbracelet/soft-serve/ui/common"
+	"github.com/muesli/termenv"
+	"github.com/spf13/cobra"
+)
+
+// RepoCommand is the command for managing repositories.
+func RepoCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:     "repo COMMAND",
+		Aliases: []string{"repository", "repositories"},
+		Short:   "Manage repositories.",
+	}
+	cmd.AddCommand(
+		setCommand(),
+		createCommand(),
+		deleteCommand(),
+		listCommand(),
+		showCommand(),
+	)
+	return cmd
+}
+
+func setCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "set",
+		Short: "Set repository properties.",
+	}
+	cmd.AddCommand(
+		setName(),
+		setProjectName(),
+		setDescription(),
+		setPrivate(),
+		setDefaultBranch(),
+	)
+	return cmd
+}
+
+// createCommand is the command for creating a new repository.
+func createCommand() *cobra.Command {
+	var private bool
+	var description string
+	var projectName string
+	cmd := &cobra.Command{
+		Use:   "create REPOSITORY",
+		Short: "Create a new repository.",
+		Args:  cobra.ExactArgs(1),
+		PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
+			cfg, s := fromContext(cmd)
+			if !cfg.IsAdmin(s.PublicKey()) {
+				return ErrUnauthorized
+			}
+			return nil
+		},
+		RunE: func(cmd *cobra.Command, args []string) error {
+			cfg, _ := fromContext(cmd)
+			name := args[0]
+			if err := cfg.Create(name, projectName, description, private); err != nil {
+				return err
+			}
+			return nil
+		},
+	}
+	cmd.Flags().BoolVarP(&private, "private", "p", false, "make the repository private")
+	cmd.Flags().StringVarP(&description, "description", "d", "", "set the repository description")
+	cmd.Flags().StringVarP(&projectName, "project-name", "n", "", "set the project name")
+	return cmd
+}
+
+func deleteCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:               "delete REPOSITORY",
+		Short:             "Delete a repository.",
+		Args:              cobra.ExactArgs(1),
+		PersistentPreRunE: checkIfAdmin,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			cfg, _ := fromContext(cmd)
+			name := args[0]
+			if err := cfg.Delete(name); err != nil {
+				return err
+			}
+			return nil
+		},
+	}
+	return cmd
+}
+
+func checkIfReadable(cmd *cobra.Command, args []string) error {
+	var repo string
+	if len(args) > 0 {
+		repo = args[0]
+	}
+	cfg, s := fromContext(cmd)
+	rn := strings.TrimSuffix(repo, ".git")
+	auth := cfg.AuthRepo(rn, s.PublicKey())
+	if auth < proto.ReadOnlyAccess {
+		return ErrUnauthorized
+	}
+	return nil
+}
+
+func checkIfAdmin(cmd *cobra.Command, args []string) error {
+	cfg, s := fromContext(cmd)
+	if !cfg.IsAdmin(s.PublicKey()) {
+		return ErrUnauthorized
+	}
+	return nil
+}
+
+func checkIfCollab(cmd *cobra.Command, args []string) error {
+	var repo string
+	if len(args) > 0 {
+		repo = args[0]
+	}
+	cfg, s := fromContext(cmd)
+	rn := strings.TrimSuffix(repo, ".git")
+	auth := cfg.AuthRepo(rn, s.PublicKey())
+	if auth < proto.ReadWriteAccess {
+		return ErrUnauthorized
+	}
+	return nil
+}
+
+func setName() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:               "name REPOSITORY NEW_NAME",
+		Short:             "Set the name for a repository.",
+		Args:              cobra.ExactArgs(2),
+		PersistentPreRunE: checkIfAdmin,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			cfg, _ := fromContext(cmd)
+			oldName := args[0]
+			newName := args[1]
+			if err := cfg.Rename(oldName, newName); err != nil {
+				return err
+			}
+			return nil
+		},
+	}
+	return cmd
+}
+
+func setProjectName() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:               "project-name REPOSITORY NAME",
+		Short:             "Set the project name for a repository.",
+		Args:              cobra.MinimumNArgs(2),
+		PersistentPreRunE: checkIfCollab,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			cfg, _ := fromContext(cmd)
+			rn := strings.TrimSuffix(args[0], ".git")
+			if err := cfg.SetProjectName(rn, strings.Join(args[1:], " ")); err != nil {
+				return err
+			}
+			return nil
+		},
+	}
+	return cmd
+}
+
+func setDescription() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:               "description REPOSITORY DESCRIPTION",
+		Short:             "Set the description for a repository.",
+		Args:              cobra.MinimumNArgs(2),
+		PersistentPreRunE: checkIfCollab,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			cfg, _ := fromContext(cmd)
+			rn := strings.TrimSuffix(args[0], ".git")
+			if err := cfg.SetDescription(rn, strings.Join(args[1:], " ")); err != nil {
+				return err
+			}
+			return nil
+		},
+	}
+	return cmd
+}
+
+func setPrivate() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:               "private REPOSITORY [true|false]",
+		Short:             "Set a repository to private.",
+		Args:              cobra.ExactArgs(2),
+		PersistentPreRunE: checkIfCollab,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			cfg, _ := fromContext(cmd)
+			rn := strings.TrimSuffix(args[0], ".git")
+			isPrivate, err := strconv.ParseBool(args[1])
+			if err != nil {
+				return err
+			}
+			if err := cfg.SetPrivate(rn, isPrivate); err != nil {
+				return err
+			}
+			return nil
+		},
+	}
+	return cmd
+}
+
+func setDefaultBranch() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:               "default-branch REPOSITORY BRANCH",
+		Short:             "Set the default branch for a repository.",
+		Args:              cobra.ExactArgs(2),
+		PersistentPreRunE: checkIfAdmin,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			cfg, _ := fromContext(cmd)
+			rn := strings.TrimSuffix(args[0], ".git")
+			if err := cfg.SetDefaultBranch(rn, args[1]); err != nil {
+				return err
+			}
+			return nil
+		},
+	}
+	return cmd
+}
+
+// listCommand returns a command that list file or directory at path.
+func listCommand() *cobra.Command {
+	listCmd := &cobra.Command{
+		Use:               "list PATH",
+		Aliases:           []string{"ls"},
+		Short:             "List file or directory at path.",
+		Args:              cobra.RangeArgs(0, 1),
+		PersistentPreRunE: checkIfReadable,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			cfg, s := fromContext(cmd)
+			rn := ""
+			path := ""
+			ps := []string{}
+			if len(args) > 0 {
+				path = filepath.Clean(args[0])
+				ps = strings.Split(path, "/")
+				rn = strings.TrimSuffix(ps[0], ".git")
+				auth := cfg.AuthRepo(rn, s.PublicKey())
+				if auth < proto.ReadOnlyAccess {
+					return ErrUnauthorized
+				}
+			}
+			if path == "" || path == "." || path == "/" {
+				repos, err := cfg.ListRepos()
+				if err != nil {
+					return err
+				}
+				for _, r := range repos {
+					if cfg.AuthRepo(r.Name(), s.PublicKey()) >= proto.ReadOnlyAccess {
+						fmt.Fprintln(s, r.Name())
+					}
+				}
+				return nil
+			}
+			r, err := cfg.Open(rn)
+			if err != nil {
+				return err
+			}
+			head, err := r.Repository().HEAD()
+			if err != nil {
+				if bs, err := r.Repository().Branches(); err != nil && len(bs) == 0 {
+					return fmt.Errorf("repository is empty")
+				}
+				return err
+			}
+			tree, err := r.Repository().TreePath(head, "")
+			if err != nil {
+				return err
+			}
+			subpath := strings.Join(ps[1:], "/")
+			ents := git.Entries{}
+			te, err := tree.TreeEntry(subpath)
+			if err == git.ErrRevisionNotExist {
+				return ErrFileNotFound
+			}
+			if err != nil {
+				return err
+			}
+			if te.Type() == "tree" {
+				tree, err = tree.SubTree(subpath)
+				if err != nil {
+					return err
+				}
+				ents, err = tree.Entries()
+				if err != nil {
+					return err
+				}
+			} else {
+				ents = append(ents, te)
+			}
+			ents.Sort()
+			for _, ent := range ents {
+				fmt.Fprintf(s, "%s\t%d\t %s\n", ent.Mode(), ent.Size(), ent.Name())
+			}
+			return nil
+		},
+	}
+	return listCmd
+}
+
+var (
+	lineDigitStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("239"))
+	lineBarStyle   = lipgloss.NewStyle().Foreground(lipgloss.Color("236"))
+	dirnameStyle   = lipgloss.NewStyle().Foreground(lipgloss.Color("#00AAFF"))
+	filenameStyle  = lipgloss.NewStyle()
+	filemodeStyle  = lipgloss.NewStyle().Foreground(lipgloss.Color("#777777"))
+)
+
+// showCommand returns a command that prints the contents of a file.
+func showCommand() *cobra.Command {
+	var linenumber bool
+	var color bool
+
+	showCmd := &cobra.Command{
+		Use:               "show PATH",
+		Aliases:           []string{"cat"},
+		Short:             "Outputs the contents of the file at path.",
+		Args:              cobra.ExactArgs(1),
+		PersistentPreRunE: checkIfReadable,
+		RunE: func(cmd *cobra.Command, args []string) error {
+			cfg, s := fromContext(cmd)
+			ps := strings.Split(args[0], "/")
+			rn := strings.TrimSuffix(ps[0], ".git")
+			fp := strings.Join(ps[1:], "/")
+			auth := cfg.AuthRepo(rn, s.PublicKey())
+			if auth < proto.ReadOnlyAccess {
+				return ErrUnauthorized
+			}
+			var repo proto.Repository
+			repoExists := false
+			repos, err := cfg.ListRepos()
+			if err != nil {
+				return err
+			}
+			for _, rp := range repos {
+				if rp.Name() == rn {
+					re, err := rp.Open()
+					if err != nil {
+						continue
+					}
+					repoExists = true
+					repo = re
+					break
+				}
+			}
+			if !repoExists {
+				return ErrRepoNotFound
+			}
+			c, _, err := proto.LatestFile(repo, fp)
+			if err != nil {
+				return err
+			}
+			if color {
+				c, err = withFormatting(fp, c)
+				if err != nil {
+					return err
+				}
+			}
+			if linenumber {
+				c = withLineNumber(c, color)
+			}
+			fmt.Fprint(s, c)
+			return nil
+		},
+	}
+	showCmd.Flags().BoolVarP(&linenumber, "linenumber", "l", false, "Print line numbers")
+	showCmd.Flags().BoolVarP(&color, "color", "c", false, "Colorize output")
+
+	return showCmd
+}
+
+func withLineNumber(s string, color bool) string {
+	lines := strings.Split(s, "\n")
+	// NB: len() is not a particularly safe way to count string width (because
+	// it's counting bytes instead of runes) but in this case it's okay
+	// because we're only dealing with digits, which are one byte each.
+	mll := len(fmt.Sprintf("%d", len(lines)))
+	for i, l := range lines {
+		digit := fmt.Sprintf("%*d", mll, i+1)
+		bar := "│"
+		if color {
+			digit = lineDigitStyle.Render(digit)
+			bar = lineBarStyle.Render(bar)
+		}
+		if i < len(lines)-1 || len(l) != 0 {
+			// If the final line was a newline we'll get an empty string for
+			// the final line, so drop the newline altogether.
+			lines[i] = fmt.Sprintf(" %s %s %s", digit, bar, l)
+		}
+	}
+	return strings.Join(lines, "\n")
+}
+
+func withFormatting(p, c string) (string, error) {
+	zero := uint(0)
+	lang := ""
+	lexer := lexers.Match(p)
+	if lexer != nil && lexer.Config() != nil {
+		lang = lexer.Config().Name
+	}
+	formatter := &gansi.CodeBlockElement{
+		Code:     c,
+		Language: lang,
+	}
+	r := strings.Builder{}
+	styles := common.StyleConfig()
+	styles.CodeBlock.Margin = &zero
+	rctx := gansi.NewRenderContext(gansi.Options{
+		Styles:       styles,
+		ColorProfile: termenv.TrueColor,
+	})
+	err := formatter.Render(&r, rctx)
+	if err != nil {
+		return "", err
+	}
+	return r.String(), nil
+}

server/server.go 🔗

@@ -85,12 +85,6 @@ func NewServer(cfg *config.Config) *Server {
 	return s
 }
 
-// Reload reloads the server configuration.
-func (s *Server) Reload() error {
-	return nil
-	// return s.config.Reload()
-}
-
 // Start starts the SSH server.
 func (s *Server) Start() error {
 	var errg errgroup.Group

server/server_test.go 🔗

@@ -24,9 +24,7 @@ import (
 
 func TestPushRepo(t *testing.T) {
 	is := is.New(t)
-	s, cfg, pkPath := setupServer(t)
-	err := s.Reload()
-	is.NoErr(err)
+	_, cfg, pkPath := setupServer(t)
 	rp := t.TempDir()
 	r, err := git.PlainInit(rp, false)
 	is.NoErr(err)
@@ -65,11 +63,8 @@ func TestPushRepo(t *testing.T) {
 
 func TestCloneRepo(t *testing.T) {
 	is := is.New(t)
-	s, cfg, pkPath := setupServer(t)
+	_, cfg, pkPath := setupServer(t)
 	t.Log("starting server")
-	err := s.Reload()
-	t.Log("reloaded server")
-	is.NoErr(err)
 	dst := t.TempDir()
 	t.Cleanup(func() { is.NoErr(os.RemoveAll(dst)) })
 	url := fmt.Sprintf("ssh://localhost:%d/config", cfg.SSH.Port)