MCPcopy
hub / github.com/go-task/task / getOrCloneRepo

Method getOrCloneRepo

taskfile/node_git.go:124–159  ·  view source on GitHub ↗

getOrCloneRepo returns the path to a cached git repository. If the repository is not cached, it clones it first. This function is thread-safe: multiple goroutines cloning the same repo+ref will synchronize, and only one clone operation will occur. The cache directory is /tmp/task-git-repos/{cache_k

(ctx context.Context)

Source from the content-addressed store, hash-verified

122//
123// The cache directory is /tmp/task-git-repos/{cache_key}/
124func (node *GitNode) getOrCloneRepo(ctx context.Context) (string, error) {
125 cacheKey := node.repoCacheKey()
126
127 repoMutex := globalGitRepoCache.getLockForRepo(cacheKey)
128 repoMutex.Lock()
129 defer repoMutex.Unlock()
130
131 cacheDir := filepath.Join(os.TempDir(), "task-git-repos", cacheKey)
132
133 // Check cache FIRST - if already cloned, no network needed, timeout irrelevant
134 gitDir := filepath.Join(cacheDir, ".git")
135 if _, err := os.Stat(gitDir); err == nil {
136 return cacheDir, nil
137 }
138
139 // Only check context if we need to clone (requires network)
140 if err := ctx.Err(); err != nil {
141 return "", fmt.Errorf("context cancelled while waiting for repository lock: %w", err)
142 }
143
144 getterURL := node.buildURL()
145
146 client := &getter.Client{
147 Ctx: ctx,
148 Src: getterURL,
149 Dst: cacheDir,
150 Mode: getter.ClientModeDir,
151 }
152
153 if err := client.Get(); err != nil {
154 _ = os.RemoveAll(cacheDir)
155 return "", fmt.Errorf("failed to clone repository: %w", err)
156 }
157
158 return cacheDir, nil
159}
160
161func (node *GitNode) ReadContext(ctx context.Context) ([]byte, error) {
162 // Get or clone the repository into cache

Callers 1

ReadContextMethod · 0.95

Calls 5

repoCacheKeyMethod · 0.95
buildURLMethod · 0.95
getLockForRepoMethod · 0.80
ErrMethod · 0.80
GetMethod · 0.45

Tested by

no test coverage detected