Something went wrong. Try again.
forked from charmbracelet/soft-serve
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101package git
import ( "context" "errors" "fmt" "io" "path/filepath" "strings"
"charm.land/log/v2" gitm "github.com/aymanbagabas/git-module" "github.com/charmbracelet/soft-serve/git" "github.com/go-git/go-git/v5/plumbing/format/pktline")
// ErrNoBranches is returned when a repo has no branches.var ErrNoBranches = errors.New("no branches found")
// WritePktline encodes and writes a pktline to the given writer.func WritePktline(w io.Writer, v ...interface{}) error { msg := fmt.Sprintln(v...) pkt := pktline.NewEncoder(w) if err := pkt.EncodeString(msg); err != nil { return fmt.Errorf("git: error writing pkt-line message: %w", err) } if err := pkt.Flush(); err != nil { return fmt.Errorf("git: error flushing pkt-line message: %w", err) }
return nil}
// WritePktlineErr writes an error pktline to the given writer.func WritePktlineErr(w io.Writer, err error) error { return WritePktline(w, "ERR", err.Error())}
// EnsureWithin ensures the given repo is within the repos directory.func EnsureWithin(reposDir string, repo string) error { repoDir := filepath.Join(reposDir, repo) absRepos, err := filepath.Abs(reposDir) if err != nil { log.Debugf("failed to get absolute path for repo: %s", err) return ErrSystemMalfunction } absRepo, err := filepath.Abs(repoDir) if err != nil { log.Debugf("failed to get absolute path for repos: %s", err) return ErrSystemMalfunction }
// ensure the repo is within the repos directory if !strings.HasPrefix(absRepo, absRepos) { log.Debugf("repo path is outside of repos directory: %s", absRepo) return ErrInvalidRepo }
return nil}
// EnsureDefaultBranch ensures the repo has a default branch.// It will prefer choosing "main" or "master" if available.func EnsureDefaultBranch(ctx context.Context, repoPath string) error { r, err := git.Open(repoPath) if err != nil { return err } brs, err := r.Branches() if len(brs) == 0 { return ErrNoBranches } if err != nil { return err } // Rename the default branch to the first branch available _, err = r.HEAD() if err == git.ErrReferenceNotExist { branch := brs[0] // Prefer "main" or "master" as the default branch for _, b := range brs { if b == "main" || b == "master" { branch = b break } }
if _, err := r.SymbolicRef(git.HEAD, git.RefsHeads+branch, gitm.SymbolicRefOptions{ CommandOptions: gitm.CommandOptions{ Context: ctx, }, }); err != nil { return err } } if err != nil && err != git.ErrReferenceNotExist { return err } return nil}