From be75cc82a43fcbc165bec427882b81d72220b49c Mon Sep 17 00:00:00 2001 From: Catherine Date: Wed, 3 Dec 2025 18:10:54 +0000 Subject: [PATCH] Factor out functions to create and fill a manifest. NFCI --- src/extract.go | 56 ++++++++++++------------------------------------- src/fetch.go | 12 ++++------- src/manifest.go | 39 ++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 51 deletions(-) diff --git a/src/extract.go b/src/extract.go index 27d028f..3dc7d7d 100644 --- a/src/extract.go +++ b/src/extract.go @@ -13,7 +13,6 @@ import ( "github.com/c2h5oh/datasize" "github.com/klauspost/compress/zstd" - "google.golang.org/protobuf/proto" ) var ErrArchiveTooLarge = errors.New("archive too large") @@ -46,11 +45,7 @@ func ExtractZstd(reader io.Reader, next func(io.Reader) (*Manifest, error)) (*Ma func ExtractTar(reader io.Reader) (*Manifest, error) { archive := tar.NewReader(reader) - manifest := Manifest{ - Contents: map[string]*Entry{ - "": {Type: Type_Directory.Enum()}, - }, - } + manifest := NewManifest() for { header, err := archive.Next() if err == io.EOF { @@ -70,38 +65,23 @@ func ExtractTar(reader io.Reader) (*Manifest, error) { } } - manifestEntry := Entry{} switch header.Typeflag { case tar.TypeReg: fileData, err := io.ReadAll(archive) if err != nil { return nil, fmt.Errorf("tar: %s: %w", fileName, err) } - - manifestEntry.Type = Type_InlineFile.Enum() - manifestEntry.Data = fileData - manifestEntry.Transform = Transform_Identity.Enum() - manifestEntry.OriginalSize = proto.Int64(header.Size) - manifestEntry.CompressedSize = proto.Int64(header.Size) - + AddFile(manifest, fileName, fileData) case tar.TypeSymlink: - manifestEntry.Type = Type_Symlink.Enum() - manifestEntry.Data = []byte(header.Linkname) - manifestEntry.Transform = Transform_Identity.Enum() - manifestEntry.OriginalSize = proto.Int64(header.Size) - manifestEntry.CompressedSize = proto.Int64(header.Size) - + AddSymlink(manifest, fileName, header.Linkname) case tar.TypeDir: - manifestEntry.Type = Type_Directory.Enum() - fileName = strings.TrimSuffix(fileName, "/") - + AddDirectory(manifest, fileName) default: - AddProblem(&manifest, fileName, "unsupported type '%c'", header.Typeflag) + AddProblem(manifest, fileName, "unsupported type '%c'", header.Typeflag) continue } - manifest.Contents[fileName] = &manifestEntry } - return &manifest, nil + return manifest, nil } func ExtractZip(reader io.Reader) (*Manifest, error) { @@ -128,14 +108,11 @@ func ExtractZip(reader io.Reader) (*Manifest, error) { ) } - manifest := Manifest{ - Contents: map[string]*Entry{ - "": {Type: Type_Directory.Enum()}, - }, - } + manifest := NewManifest() for _, file := range archive.File { - manifestEntry := Entry{} - if !strings.HasSuffix(file.Name, "/") { + if strings.HasSuffix(file.Name, "/") { + AddDirectory(manifest, file.Name) + } else { fileReader, err := file.Open() if err != nil { return nil, err @@ -148,18 +125,11 @@ func ExtractZip(reader io.Reader) (*Manifest, error) { } if file.Mode()&os.ModeSymlink != 0 { - manifestEntry.Type = Type_Symlink.Enum() + AddSymlink(manifest, file.Name, string(fileData)) } else { - manifestEntry.Type = Type_InlineFile.Enum() + AddFile(manifest, file.Name, fileData) } - manifestEntry.Data = fileData - manifestEntry.Transform = Transform_Identity.Enum() - manifestEntry.OriginalSize = proto.Int64(int64(file.UncompressedSize64)) - manifestEntry.CompressedSize = proto.Int64(int64(file.UncompressedSize64)) - } else { - manifestEntry.Type = Type_Directory.Enum() } - manifest.Contents[strings.TrimSuffix(file.Name, "/")] = &manifestEntry } - return &manifest, nil + return manifest, nil } diff --git a/src/fetch.go b/src/fetch.go index 4f987b5..d03652f 100644 --- a/src/fetch.go +++ b/src/fetch.go @@ -96,14 +96,10 @@ func FetchRepository( // Create a manifest for the tree object corresponding to `branch`, but do not populate it // with data yet; instead, record all the blobs we'll need. - manifest := &Manifest{ - RepoUrl: proto.String(repoURL), - Branch: proto.String(branch), - Commit: proto.String(ref.Hash().String()), - Contents: map[string]*Entry{ - "": {Type: Type_Directory.Enum()}, - }, - } + manifest := NewManifest() + manifest.RepoUrl = proto.String(repoURL) + manifest.Branch = proto.String(branch) + manifest.Commit = proto.String(ref.Hash().String()) blobsNeeded := map[plumbing.Hash]*Entry{} for { name, entry, err := walker.Next() diff --git a/src/manifest.go b/src/manifest.go index c16b8c2..9c94b38 100644 --- a/src/manifest.go +++ b/src/manifest.go @@ -36,6 +36,14 @@ var ( }) ) +func NewManifest() *Manifest { + return &Manifest{ + Contents: map[string]*Entry{ + "": {Type: Type_Directory.Enum()}, + }, + } +} + func IsManifestEmpty(manifest *Manifest) bool { if len(manifest.Contents) > 1 { return false @@ -82,6 +90,37 @@ func DecodeManifest(data []byte) (manifest *Manifest, err error) { return } +func NewManifestEntry(type_ Type, data []byte) *Entry { + entry := &Entry{} + entry.Type = type_.Enum() + if data != nil { + entry.Data = data + entry.Transform = Transform_Identity.Enum() + entry.OriginalSize = proto.Int64(int64(len(data))) + entry.CompressedSize = proto.Int64(int64(len(data))) + } + return entry +} + +func AddFile(manifest *Manifest, path string, data []byte) *Entry { + entry := NewManifestEntry(Type_InlineFile, data) + manifest.Contents[path] = entry + return entry +} + +func AddSymlink(manifest *Manifest, path string, target string) *Entry { + entry := NewManifestEntry(Type_Symlink, []byte(target)) + manifest.Contents[path] = entry + return entry +} + +func AddDirectory(manifest *Manifest, path string) *Entry { + path = strings.TrimSuffix(path, "/") + entry := NewManifestEntry(Type_Directory, nil) + manifest.Contents[path] = entry + return entry +} + func AddProblem(manifest *Manifest, path, format string, args ...any) error { cause := fmt.Sprintf(format, args...) manifest.Problems = append(manifest.Problems, &Problem{