bidet / internal / handlers / directory.go

@ main | history


package handlers

import (
	"errors"
	"os"
	"strings"

	securejoin "github.com/cyphar/filepath-securejoin"
	"github.com/go-git/go-git/v6"
	"nmyk.io/bidet/internal/core"
)

const dotGit = ".git"

func (s Server) List() ([]*core.Repo, error) {
	entries, err := os.ReadDir(s.Dir)
	if err != nil {
		return nil, err
	}
	var repos []*core.Repo
	for _, e := range entries {
		if e.Name() == dotGit {
			continue
		}
		repo, err := s.Open(strings.TrimSuffix(e.Name(), dotGit))
		if err == nil {
			if _, err = repo.Worktree(); errors.Is(err, git.ErrIsBareRepository) {
				repos = append(repos, repo)
			}
		}
	}
	if len(repos) == 0 {
		return nil, errors.New("No repos found in " + s.Dir)
	}
	return repos, nil
}

func (s Server) repoPath(repoName string) (string, error) {
	cleanPath, err := securejoin.SecureJoin(s.Dir, repoName)
	if err != nil {
		return "", err
	}
	return cleanPath + dotGit, nil
}

func (s Server) Open(repoName string) (*core.Repo, error) {
	repoPath, err := s.repoPath(repoName)
	if err != nil {
		return nil, err
	}
	if _, err := os.Stat(repoPath); os.IsNotExist(err) {
		return nil, err
	}
	repo, err := git.PlainOpen(repoPath)
	if err != nil {
		return nil, err
	}
	return &core.Repo{Repository: repo, Name: repoName}, nil
}