Scope candidate blob readers to validation
This commit is contained in:
@@ -18,6 +18,9 @@ type CandidateTree struct {
|
||||
byPath map[string]int
|
||||
directories map[string]struct{}
|
||||
blobs map[string][]byte
|
||||
blobReader *git.BlobReader
|
||||
closed bool
|
||||
closeErr error
|
||||
}
|
||||
|
||||
// ReadCandidateTree enumerates the captured commit without reading from the
|
||||
@@ -52,6 +55,9 @@ func (tree *CandidateTree) Entries() []git.TreeEntry {
|
||||
// ReadFile returns the committed blob bytes for path. Contents are cached by
|
||||
// object ID for later reads from this tree.
|
||||
func (tree *CandidateTree) ReadFile(ctx context.Context, path string) ([]byte, error) {
|
||||
if tree.closed {
|
||||
return nil, fmt.Errorf("read committed path %q: candidate tree is closed", path)
|
||||
}
|
||||
index, ok := tree.byPath[path]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("committed path %q does not exist", path)
|
||||
@@ -63,14 +69,36 @@ func (tree *CandidateTree) ReadFile(ctx context.Context, path string) ([]byte, e
|
||||
if contents, ok := tree.blobs[entry.ObjectID]; ok {
|
||||
return append([]byte(nil), contents...), nil
|
||||
}
|
||||
contents, err := git.ReadBlob(ctx, tree.repositoryDir, entry.ObjectID)
|
||||
if tree.blobReader == nil {
|
||||
// The reader belongs to the tree and can outlive an individual read
|
||||
// context. Each Read call still applies its own cancellation to the
|
||||
// in-flight exchange.
|
||||
tree.blobReader = git.NewBlobReader(context.Background(), tree.repositoryDir)
|
||||
}
|
||||
contents, err := tree.blobReader.Read(ctx, entry.ObjectID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read committed path %q: %w", path, err)
|
||||
}
|
||||
if tree.blobs == nil {
|
||||
tree.blobs = make(map[string][]byte)
|
||||
}
|
||||
tree.blobs[entry.ObjectID] = append([]byte(nil), contents...)
|
||||
return contents, nil
|
||||
}
|
||||
|
||||
// Close closes the scoped local Git blob reader, if content was requested.
|
||||
// Metadata-only trees have no child process to close.
|
||||
func (tree *CandidateTree) Close() error {
|
||||
if tree.closed {
|
||||
return tree.closeErr
|
||||
}
|
||||
tree.closed = true
|
||||
if tree.blobReader != nil {
|
||||
tree.closeErr = tree.blobReader.Close()
|
||||
}
|
||||
return tree.closeErr
|
||||
}
|
||||
|
||||
// Entry returns the committed metadata for path when present.
|
||||
func (tree *CandidateTree) Entry(path string) (git.TreeEntry, bool) {
|
||||
index, ok := tree.byPath[path]
|
||||
|
||||
Reference in New Issue
Block a user