Skip to content

Instantly share code, notes, and snippets.

@neilnaveen
Created November 27, 2023 19:42
Show Gist options
  • Select an option

  • Save neilnaveen/039b19ca4c11c9517d17f9577d5a7b0b to your computer and use it in GitHub Desktop.

Select an option

Save neilnaveen/039b19ca4c11c9517d17f9577d5a7b0b to your computer and use it in GitHub Desktop.
Blob.go
// SPDX-License-Identifier: Apache-2.0
package gitinterface
import (
"bytes"
"errors"
"io"
"os/exec"
"github.com/gittuf/gittuf/internal/third_party/go-git"
"github.com/gittuf/gittuf/internal/third_party/go-git/plumbing"
"github.com/gittuf/gittuf/internal/third_party/go-git/plumbing/object"
"github.com/gittuf/gittuf/internal/third_party/go-git/storage/memory"
)
type Blob interface {
GetBlob(repo *git.Repository, blobID plumbing.Hash) (*object.Blob, error)
WriteBlob(repo *git.Repository, contents []byte) (plumbing.Hash, error)
ReadBlob(repo *git.Repository, blobID plumbing.Hash) ([]byte, error)
EmptyBlob() plumbing.Hash
}
type blob struct{}
type BlobType int
const (
GoGitBlob BlobType = iota
GitBinaryBlob // Use git binary to get blob
)
func NewBlob(gitType BlobType) Blob {
switch gitType {
case GoGitBlob:
return &blob{}
case GitBinaryBlob:
return &blob{}
}
}
var ErrWrittenBlobLengthMismatch = errors.New("length of blob written does not match length of contents")
// ReadBlob returns the contents of a the blob referenced by blobID.
func (b *blob) ReadBlob(repo *git.Repository, blobID plumbing.Hash) ([]byte, error) {
blob1, err := b.GetBlob(repo, blobID)
if err != nil {
return nil, err
}
reader, err := blob1.Reader()
if err != nil {
return nil, err
}
return io.ReadAll(reader)
}
// WriteBlob creates a blob object with the specified contents and returns the
// ID of the resultant blob.
func (b *blob) WriteBlob(repo *git.Repository, contents []byte) (plumbing.Hash, error) {
obj := repo.Storer.NewEncodedObject()
obj.SetType(plumbing.BlobObject)
writer, err := obj.Writer()
if err != nil {
return plumbing.ZeroHash, err
}
length, err := writer.Write(contents)
if err != nil {
return plumbing.ZeroHash, err
}
if length != len(contents) {
return plumbing.ZeroHash, ErrWrittenBlobLengthMismatch
}
return repo.Storer.SetEncodedObject(obj)
}
// GetBlob returns the requested blob object.
func (b *blob) GetBlob(repo *git.Repository, blobID plumbing.Hash) (*object.Blob, error) {
return repo.BlobObject(blobID)
}
// EmptyBlob returns the hash of an empty blob in a Git repository.
// Note: it is generated on the fly rather than stored as a constant to support
// SHA-256 repositories in future.
func (b *blob) EmptyBlob() plumbing.Hash {
obj := memory.NewStorage().NewEncodedObject()
obj.SetType(plumbing.BlobObject)
return obj.Hash()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment