diff options
| author | Ophestra <cat@gensokyo.uk> | 2026-01-07 22:15:55 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2026-01-07 22:16:26 +0900 |
| commit | c86ff02d8d794ef31d8f646ae85e776b714c7ef9 (patch) | |
| tree | 6c8fce143e3c0b22d094b8f9c73bacb92c4d1f0d /internal/pkg/tar.go | |
| parent | e8dda70c417a78647ae31930acc0a98ecf5ad097 (diff) | |
internal/pkg: tar optional file
This allows tar to take a single-file directory Artifact as input.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/pkg/tar.go')
| -rw-r--r-- | internal/pkg/tar.go | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/internal/pkg/tar.go b/internal/pkg/tar.go index 240a3980..6c3e5c50 100644 --- a/internal/pkg/tar.go +++ b/internal/pkg/tar.go @@ -28,15 +28,17 @@ const ( // A tarArtifact is an [Artifact] unpacking a tarball backed by a [File]. type tarArtifact struct { // Caller-supplied backing tarball. - f File + f Artifact // Compression on top of the tarball. compression uint64 } -// NewTar returns a new [Artifact] backed by the supplied [File] and -// compression method. -func NewTar(f File, compression uint64) Artifact { - return &tarArtifact{f: f, compression: compression} +// NewTar returns a new [Artifact] backed by the supplied [Artifact] and +// compression method. If f implements [File], its data might be used directly, +// eliminating the roundtrip to vfs. If f is a directory, it must contain a +// single regular file. +func NewTar(a Artifact, compression uint64) Artifact { + return &tarArtifact{a, compression} } // NewHTTPGetTar is abbreviation for NewHTTPGet passed to NewTar. @@ -76,26 +78,46 @@ func (a *tarArtifact) Cure(c *CureContext) (err error) { temp := c.GetTempDir() var tr io.ReadCloser - { + if file, ok := a.f.(File); ok { + if tr, err = c.OpenFile(file); err != nil { + return + } + } else { + var pathname *check.Absolute + if pathname, _, err = c.Cure(a.f); err != nil { + return + } - if tr, err = c.OpenFile(a.f); err != nil { + var entries []os.DirEntry + if entries, err = os.ReadDir(pathname.String()); err != nil { + return + } + + if len(entries) != 1 || !entries[0].Type().IsRegular() { + return errors.New( + "input directory does not contain a single regular file", + ) + } else { + pathname = pathname.Append(entries[0].Name()) + } + + if tr, err = os.Open(pathname.String()); err != nil { return } - defer func(f io.ReadCloser) { - closeErr := f.Close() - if err == nil { - err = closeErr - } - }(tr) - tr = io.NopCloser(tr) } - defer func() { + defer func(f io.ReadCloser) { closeErr := tr.Close() if err == nil { err = closeErr } - }() + + closeErr = f.Close() + if err == nil { + err = closeErr + } + }(tr) + tr = io.NopCloser(tr) switch a.compression { case TarUncompressed: |
