-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathacquisition.go
More file actions
123 lines (113 loc) · 3.91 KB
/
Copy pathacquisition.go
File metadata and controls
123 lines (113 loc) · 3.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package app
import (
"context"
"errors"
"fmt"
"strings"
"time"
"github.com/morluto/gitcontribute/internal/acquire"
"github.com/morluto/gitcontribute/internal/codeindex"
"github.com/morluto/gitcontribute/internal/contracts"
"github.com/morluto/gitcontribute/internal/domain"
)
// Acquire clones or fetches a repository into the managed cache, records the
// resolved remote URL/default branch/commit SHA/acquired time, and indexes the
// clean checkout into the corpus. It does not execute repository code.
func (s *Service) Acquire(ctx context.Context, repo contracts.RepoRef, remote string) (result *contracts.AcquisitionResult, returnErr error) {
ref, err := domain.NewRepoRef(repo.Owner, repo.Repo)
if err != nil {
return nil, err
}
remote = strings.TrimSpace(remote)
if remote == "" {
remote = fmt.Sprintf("https://github.com/%s/%s.git", ref.Owner(), ref.Repo())
}
cacheRoot, err := s.paths.AcquisitionCacheDir()
if err != nil {
return nil, err
}
mgr, err := acquire.NewManager(cacheRoot, nil)
if err != nil {
return nil, fmt.Errorf("create acquisition manager: %w", err)
}
acq, err := mgr.Acquire(ctx, ref.Owner(), ref.Repo(), remote)
if err != nil {
return nil, fmt.Errorf("acquire %s: %w", ref, err)
}
defer func() {
cleanupCtx, cancel := context.WithTimeout(context.WithoutCancel(ctx), 10*time.Second)
defer cancel()
if err := mgr.Cleanup(cleanupCtx, acq); err != nil {
returnErr = errors.Join(returnErr, fmt.Errorf("cleanup acquired checkout: %w", err))
}
}()
c, err := s.openCorpus(ctx)
if err != nil {
return nil, err
}
existing, err := c.CodeSnapshot(ctx, ref, acq.CommitSHA)
if err != nil {
return nil, fmt.Errorf("find code snapshot: %w", err)
}
if existing != nil && existing.Manifest.FormatVersion == codeindex.FormatVersion {
_, confirmedCommit, err := codeindex.Probe(ctx, acq.Path)
if err != nil {
return nil, fmt.Errorf("verify acquired checkout: %w", err)
}
if confirmedCommit != acq.CommitSHA {
return nil, fmt.Errorf("acquired checkout changed before snapshot reuse: commit %q", confirmedCommit)
}
artifact, err := c.LatestCodeIndexArtifact(ctx, ref, acq.CommitSHA)
if err != nil || artifact == nil {
return nil, fmt.Errorf("resolve immutable code-index artifact: %w", err)
}
return &contracts.AcquisitionResult{
Repo: repo,
Remote: acq.Remote,
DefaultBranch: acq.DefaultBranch,
CommitSHA: acq.CommitSHA,
Files: existing.Manifest.IndexedFiles,
Bytes: existing.TotalBytes,
Indexed: true,
Inserted: false,
AcquiredAt: formatTime(acq.AcquiredAt),
Message: "acquired; snapshot already indexed",
IndexManifest: existing.Manifest,
ArtifactDigest: artifact.Digest,
ManifestDigest: artifact.ManifestSHA256,
SnapshotToken: artifact.SnapshotToken,
}, nil
}
snapshot, err := codeindex.Index(ctx, acq.Path, codeindex.Options{})
if err != nil {
return nil, fmt.Errorf("index acquired checkout: %w", err)
}
_, inserted, _, err := c.StoreCodeSnapshotWithRevision(ctx, ref, snapshot)
if err != nil {
return nil, fmt.Errorf("store code snapshot: %w", err)
}
artifact, err := c.LatestCodeIndexArtifact(ctx, ref, snapshot.Commit)
if err != nil || artifact == nil {
return nil, fmt.Errorf("resolve immutable code-index artifact: %w", err)
}
message := "acquired and indexed"
if !inserted {
message = "acquired; snapshot already indexed"
}
return &contracts.AcquisitionResult{
Repo: repo,
Remote: acq.Remote,
DefaultBranch: acq.DefaultBranch,
CommitSHA: acq.CommitSHA,
Files: len(snapshot.Documents),
Bytes: snapshot.TotalBytes,
Indexed: true,
Inserted: inserted,
AcquiredAt: formatTime(acq.AcquiredAt),
Message: message,
IndexManifest: snapshot.Manifest,
ArtifactDigest: artifact.Digest,
ManifestDigest: artifact.ManifestSHA256,
SnapshotToken: artifact.SnapshotToken,
}, nil
}