fix(backend): repo doesn't exist

Ayman Bagabas created

Change summary

server/backend/backend.go   |  4 --
server/backend/file/file.go | 73 ++++++++++----------------------------
server/backend/file/repo.go |  9 ++--
server/backend/noop/noop.go | 10 -----
server/backend/noop/repo.go |  2 
server/backend/repo.go      |  4 +-
server/backend/utils.go     |  2 
7 files changed, 27 insertions(+), 77 deletions(-)

Detailed changes

server/backend/backend.go 🔗

@@ -41,10 +41,6 @@ type Backend interface {
 	DeleteRepository(name string) error
 	// RenameRepository renames a repository.
 	RenameRepository(oldName, newName string) error
-	// DefaultBranch returns the repository's default branch.
-	DefaultBranch(repo string) (string, error)
-	// SetDefaultBranch sets the default branch for a repository.
-	SetDefaultBranch(repo string, branch string) error
 
 	// Description returns the repo's description.
 	Description(repo string) string

server/backend/file/file.go 🔗

@@ -33,7 +33,6 @@ import (
 	"github.com/charmbracelet/soft-serve/git"
 	"github.com/charmbracelet/soft-serve/server/backend"
 	"github.com/charmbracelet/ssh"
-	gitm "github.com/gogs/git-module"
 	gossh "golang.org/x/crypto/ssh"
 )
 
@@ -421,6 +420,7 @@ func (fb *FileBackend) SetAnonAccess(level backend.AccessLevel) error {
 //
 // It implements backend.Backend.
 func (fb *FileBackend) SetDescription(repo string, desc string) error {
+	repo = sanatizeRepo(repo) + ".git"
 	f, err := os.OpenFile(filepath.Join(fb.reposPath(), repo, description), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
 	if err != nil {
 		return fmt.Errorf("failed to open description file: %w", err)
@@ -501,6 +501,10 @@ func (fb *FileBackend) SetServerPort(port string) error {
 func (fb *FileBackend) CreateRepository(name string, private bool) (backend.Repository, error) {
 	name = sanatizeRepo(name) + ".git"
 	rp := filepath.Join(fb.reposPath(), name)
+	if _, err := os.Stat(rp); err == nil {
+		return nil, os.ErrExist
+	}
+
 	if _, err := git.Init(rp, true); err != nil {
 		logger.Debug("failed to create repository", "err", err)
 		return nil, err
@@ -524,9 +528,16 @@ func (fb *FileBackend) DeleteRepository(name string) error {
 //
 // It implements backend.Backend.
 func (fb *FileBackend) RenameRepository(oldName string, newName string) error {
-	oldName = sanatizeRepo(oldName) + ".git"
-	newName = sanatizeRepo(newName) + ".git"
-	return os.Rename(filepath.Join(fb.reposPath(), oldName), filepath.Join(fb.reposPath(), newName))
+	oldName = filepath.Join(fb.reposPath(), sanatizeRepo(oldName)+".git")
+	newName = filepath.Join(fb.reposPath(), sanatizeRepo(newName)+".git")
+	if _, err := os.Stat(oldName); errors.Is(err, os.ErrNotExist) {
+		return fmt.Errorf("repository %q does not exist", strings.TrimSuffix(filepath.Base(oldName), ".git"))
+	}
+	if _, err := os.Stat(newName); err == nil {
+		return fmt.Errorf("repository %q already exists", strings.TrimSuffix(filepath.Base(newName), ".git"))
+	}
+
+	return os.Rename(oldName, newName)
 }
 
 // Repository finds the given repository.
@@ -536,7 +547,10 @@ func (fb *FileBackend) Repository(repo string) (backend.Repository, error) {
 	repo = sanatizeRepo(repo) + ".git"
 	rp := filepath.Join(fb.reposPath(), repo)
 	_, err := os.Stat(rp)
-	if !errors.Is(err, os.ErrExist) {
+	if err != nil {
+		if errors.Is(err, os.ErrNotExist) {
+			return nil, os.ErrNotExist
+		}
 		return nil, err
 	}
 
@@ -569,52 +583,3 @@ func (fb *FileBackend) Repositories() ([]backend.Repository, error) {
 
 	return repos, nil
 }
-
-// DefaultBranch returns the default branch of the given repository.
-//
-// It implements backend.Backend.
-func (fb *FileBackend) DefaultBranch(repo string) (string, error) {
-	rr, err := fb.Repository(repo)
-	if err != nil {
-		logger.Debug("failed to get default branch", "err", err)
-		return "", err
-	}
-
-	r, err := rr.Repository()
-	if err != nil {
-		logger.Debug("failed to open repository for default branch", "err", err)
-		return "", err
-	}
-
-	head, err := r.HEAD()
-	if err != nil {
-		logger.Debug("failed to get HEAD for default branch", "err", err)
-		return "", err
-	}
-
-	return head.Name().Short(), nil
-}
-
-// SetDefaultBranch sets the default branch for the given repository.
-//
-// It implements backend.Backend.
-func (fb *FileBackend) SetDefaultBranch(repo string, branch string) error {
-	rr, err := fb.Repository(repo)
-	if err != nil {
-		logger.Debug("failed to get repository for default branch", "err", err)
-		return err
-	}
-
-	r, err := rr.Repository()
-	if err != nil {
-		logger.Debug("failed to open repository for default branch", "err", err)
-		return err
-	}
-
-	if _, err := r.SymbolicRef("HEAD", gitm.RefsHeads+branch); err != nil {
-		logger.Debug("failed to set default branch", "err", err)
-		return err
-	}
-
-	return nil
-}

server/backend/file/repo.go 🔗

@@ -1,7 +1,6 @@
 package file
 
 import (
-	"errors"
 	"os"
 	"path/filepath"
 	"strings"
@@ -39,7 +38,7 @@ func (r *Repo) Description() string {
 		return ""
 	}
 
-	return desc
+	return strings.TrimSpace(desc)
 }
 
 // IsPrivate returns whether the repository is private.
@@ -47,12 +46,12 @@ func (r *Repo) Description() string {
 // It implements backend.Repository.
 func (r *Repo) IsPrivate() bool {
 	_, err := os.Stat(filepath.Join(r.path, exportOk))
-	return errors.Is(err, os.ErrExist)
+	return err != nil
 }
 
-// Repository returns the underlying git.Repository.
+// Open returns the underlying git.Repository.
 //
 // It implements backend.Repository.
-func (r *Repo) Repository() (*git.Repository, error) {
+func (r *Repo) Open() (*git.Repository, error) {
 	return git.Open(r.path)
 }

server/backend/noop/noop.go 🔗

@@ -62,11 +62,6 @@ func (*Noop) CreateRepository(name string, private bool) (backend.Repository, er
 	return &repo{path: rp}, nil
 }
 
-// DefaultBranch implements backend.Backend
-func (*Noop) DefaultBranch(repo string) (string, error) {
-	return "", ErrNotImpl
-}
-
 // DeleteRepository implements backend.Backend
 func (*Noop) DeleteRepository(name string) error {
 	return ErrNotImpl
@@ -132,11 +127,6 @@ func (*Noop) SetAnonAccess(level backend.AccessLevel) error {
 	return ErrNotImpl
 }
 
-// SetDefaultBranch implements backend.Backend
-func (*Noop) SetDefaultBranch(repo string, branch string) error {
-	return ErrNotImpl
-}
-
 // SetDescription implements backend.Backend
 func (*Noop) SetDescription(repo string, desc string) error {
 	return ErrNotImpl

server/backend/noop/repo.go 🔗

@@ -27,6 +27,6 @@ func (*repo) Name() string {
 }
 
 // Repository implements backend.Repository
-func (r *repo) Repository() (*git.Repository, error) {
+func (r *repo) Open() (*git.Repository, error) {
 	return git.Open(r.path)
 }

server/backend/repo.go 🔗

@@ -10,6 +10,6 @@ type Repository interface {
 	Description() string
 	// IsPrivate returns whether the repository is private.
 	IsPrivate() bool
-	// Repository returns the underlying git.Repository.
-	Repository() (*git.Repository, error)
+	// Open returns the underlying git.Repository.
+	Open() (*git.Repository, error)
 }

server/backend/utils.go 🔗

@@ -12,7 +12,7 @@ import (
 func LatestFile(r Repository, pattern string) (string, string, error) {
 	g := glob.MustCompile(pattern)
 	dir := filepath.Dir(pattern)
-	repo, err := r.Repository()
+	repo, err := r.Open()
 	if err != nil {
 		return "", "", err
 	}