83 lines
2.2 KiB
Go
83 lines
2.2 KiB
Go
package worktree
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"os/exec"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/kandev/kandev/internal/gitcheckout"
|
|
"github.com/kandev/kandev/internal/task/models"
|
|
)
|
|
|
|
type checkoutContextKey struct{}
|
|
type checkoutContext struct {
|
|
options *models.RepositoryCheckoutOptions
|
|
env []string
|
|
}
|
|
|
|
func withCheckoutOptions(ctx context.Context, req CreateRequest) (context.Context, error) {
|
|
options, err := models.NormalizeRepositoryCheckoutOptions(req.CheckoutOptions)
|
|
if err != nil {
|
|
return ctx, err
|
|
}
|
|
if options == nil && len(req.CheckoutEnv) == 0 {
|
|
return ctx, nil
|
|
}
|
|
env := os.Environ()
|
|
keys := make([]string, 0, len(req.CheckoutEnv))
|
|
for key := range req.CheckoutEnv {
|
|
keys = append(keys, key)
|
|
}
|
|
sort.Strings(keys)
|
|
for _, key := range keys {
|
|
env = append(env, key+"="+req.CheckoutEnv[key])
|
|
}
|
|
return context.WithValue(ctx, checkoutContextKey{}, checkoutContext{options: options, env: env}), nil
|
|
}
|
|
|
|
func scopedCheckout(ctx context.Context) checkoutContext {
|
|
scope, _ := ctx.Value(checkoutContextKey{}).(checkoutContext)
|
|
return scope
|
|
}
|
|
|
|
func hasSparseCheckout(ctx context.Context) bool {
|
|
options := scopedCheckout(ctx).options
|
|
return options != nil && len(options.SparseDirectories) > 0
|
|
}
|
|
|
|
func configureCheckoutCommand(ctx context.Context, cmd *exec.Cmd) {
|
|
if scope := scopedCheckout(ctx); scope.env != nil {
|
|
cmd.Env = append([]string(nil), scope.env...)
|
|
}
|
|
}
|
|
|
|
func applySparseCheckout(ctx context.Context, path string) error {
|
|
return gitcheckout.ApplySparse(ctx, path, scopedCheckout(ctx).options, func(ctx context.Context, args []string, input string) ([]byte, error) {
|
|
cmd := newGitCommand(ctx, args...)
|
|
cmd.Stdin = strings.NewReader(input)
|
|
return runGitCmdCombinedOutput(ctx, cmd)
|
|
})
|
|
}
|
|
|
|
func (m *Manager) finishWorktreeCheckout(ctx context.Context, repoPath, worktreePath string, usesGitCrypt bool) error {
|
|
var err error
|
|
if usesGitCrypt {
|
|
err = m.unlockGitCryptAndCheckout(ctx, worktreePath)
|
|
} else {
|
|
err = applySparseCheckout(ctx, worktreePath)
|
|
}
|
|
if err == nil {
|
|
err = gitcheckout.Save(worktreePath, scopedCheckout(ctx).options)
|
|
}
|
|
if err != nil {
|
|
_ = m.removeWorktreeDir(ctx, worktreePath, repoPath)
|
|
return err
|
|
}
|
|
if !usesGitCrypt {
|
|
m.initSubmodules(ctx, worktreePath)
|
|
}
|
|
return nil
|
|
}
|