aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/pkg/tar.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-01-07 22:15:55 +0900
committerOphestra <cat@gensokyo.uk>2026-01-07 22:16:26 +0900
commitc86ff02d8d794ef31d8f646ae85e776b714c7ef9 (patch)
tree6c8fce143e3c0b22d094b8f9c73bacb92c4d1f0d /internal/pkg/tar.go
parente8dda70c417a78647ae31930acc0a98ecf5ad097 (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.go54
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: