diff options
Diffstat (limited to 'pkg/archive.go')
| -rw-r--r-- | pkg/archive.go | 67 |
1 files changed, 40 insertions, 27 deletions
diff --git a/pkg/archive.go b/pkg/archive.go index e9f76f5b..ba7c61b9 100644 --- a/pkg/archive.go +++ b/pkg/archive.go @@ -314,36 +314,25 @@ func (archiveArtifact) IsExclusive() bool { return false } // Revision satisfies [RevisionArtifact] for status behaviour. func (archiveArtifact) Revision() uint64 { return 0 } -// Cure cures the [Artifact], producing a directory located at work. -func (a archiveArtifact) Cure(t *TContext) (err error) { - var status io.Writer - if status, err = t.GetStatusWriter(); err != nil { - return - } - - var r io.ReadCloser - if r, err = t.Open(a.f); err != nil { - return - } - - defer func() { - closeErr := r.Close() - if err == nil { - err = closeErr - } - }() - +// Extract reads an archive stream from r and writes its contents to dir. If +// writeStatus is non-nil, it is called with a user-facing message after +// each successfully extracted entry. +func Extract( + r io.Reader, + dir string, + writeStatus func(s string) error, +) (err error) { type dirTargetPerm struct { path string mode fs.FileMode } var madeDirectories []dirTargetPerm - if err = os.MkdirAll(t.GetWorkDir().String(), 0700); err != nil { + if err = os.MkdirAll(dir, 0700); err != nil { return } var root *os.Root - if root, err = os.OpenRoot(t.GetWorkDir().String()); err != nil { + if root, err = os.OpenRoot(dir); err != nil { return } defer func() { @@ -355,7 +344,6 @@ func (a archiveArtifact) Cure(t *TContext) (err error) { var header *ArchiveHeader ar := NewReader(r) - msg := t.GetMessage() for header, err = ar.Next(); err == nil; header, err = ar.Next() { var m string if header.Mode.IsRegular() { @@ -422,11 +410,8 @@ func (a archiveArtifact) Cure(t *TContext) (err error) { return InvalidFileModeError(header.Mode) } - if m != "" { - msg.Verbose(m) - if _, err = io.WriteString(status, m); err != nil { - return - } else if _, err = status.Write([]byte{'\n'}); err != nil { + if writeStatus != nil && m != "" { + if err = writeStatus(m); err != nil { return } } @@ -446,6 +431,34 @@ func (a archiveArtifact) Cure(t *TContext) (err error) { return } +// Cure cures the [Artifact], producing a directory located at work. +func (a archiveArtifact) Cure(t *TContext) (err error) { + var status io.Writer + if status, err = t.GetStatusWriter(); err != nil { + return + } + + var r io.ReadCloser + if r, err = t.Open(a.f); err != nil { + return + } + + msg := t.GetMessage() + err = Extract(r, t.GetWorkDir().String(), func(s string) (err error) { + msg.Verbose(s) + if _, err = io.WriteString(status, s); err != nil { + return + } + _, err = status.Write([]byte{'\n'}) + return + }) + + if closeErr := r.Close(); err == nil { + err = closeErr + } + return +} + // CuresExempt exempts the cheap [KindArchive] implementation often found at // the end of a [FileArtifact] pipeline. func (archiveArtifact) CuresExempt() {} |
