Documentation ¶
Overview ¶
Package vacation provides a set of functions that enable input stream decompression logic from several popular decompression formats. This allows from decompression from either a file or any other byte stream, which is useful for decompressing files that are being downloaded.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Archive ¶
type Archive struct {
// contains filtered or unexported fields
}
An Archive decompresses tar, gzip, xz, and bzip2 compressed tar, and zip files from an input stream.
Example ¶
package main import ( "archive/tar" "archive/zip" "bytes" "fmt" "log" "os" "path/filepath" "github.com/paketo-buildpacks/packit/v2/vacation" ) type ArchiveFile struct { Name string Content []byte } func main() { tarBuffer := bytes.NewBuffer(nil) tw := tar.NewWriter(tarBuffer) tarFiles := []ArchiveFile{ {Name: "some-tar-dir/"}, {Name: "some-tar-dir/some-tar-file", Content: []byte("some-tar-dir/some-tar-file")}, {Name: "tar-file", Content: []byte("tar-file")}, } for _, file := range tarFiles { err := tw.WriteHeader(&tar.Header{Name: file.Name, Mode: 0755, Size: int64(len(file.Content))}) if err != nil { log.Fatal(err) } _, err = tw.Write(file.Content) if err != nil { log.Fatal(err) } } tw.Close() zipBuffer := bytes.NewBuffer(nil) zw := zip.NewWriter(zipBuffer) zipFiles := []ArchiveFile{ {Name: "some-zip-dir/"}, {Name: "some-zip-dir/some-zip-file", Content: []byte("some-zip-dir/some-zip-file")}, {Name: "zip-file", Content: []byte("zip-file")}, } for _, file := range zipFiles { header := &zip.FileHeader{Name: file.Name} header.SetMode(0755) f, err := zw.CreateHeader(header) if err != nil { log.Fatal(err) } if _, err := f.Write(file.Content); err != nil { log.Fatal(err) } } zw.Close() destination, err := os.MkdirTemp("", "destination") if err != nil { log.Fatal(err) } defer os.RemoveAll(destination) archive := vacation.NewArchive(bytes.NewReader(tarBuffer.Bytes())) if err := archive.Decompress(destination); err != nil { log.Fatal(err) } archive = vacation.NewArchive(bytes.NewReader(zipBuffer.Bytes())) if err := archive.Decompress(destination); err != nil { log.Fatal(err) } err = filepath.Walk(destination, func(path string, info os.FileInfo, err error) error { if !info.IsDir() { rel, err := filepath.Rel(destination, path) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", rel) return nil } return nil }) if err != nil { log.Fatal(err) } }
Output: some-tar-dir/some-tar-file some-zip-dir/some-zip-file tar-file zip-file
func NewArchive ¶
NewArchive returns a new Archive that reads from inputReader.
func (Archive) Decompress ¶
Decompress reads from Archive, determines the archive type of the input stream, and writes files into the destination specified.
Archive decompression will also handle files that are types "text/plain; charset=utf-8" and write the contents of the input stream to a file name specified by the `Archive.WithName()` option in the destination directory.
func (Archive) StripComponents ¶
StripComponents behaves like the --strip-components flag on tar command removing the first n levels from the final decompression destination. Setting this is a no-op for archive types that do not use --strip-components (such as zip).
Example ¶
package main import ( "archive/tar" "archive/zip" "bytes" "fmt" "log" "os" "path/filepath" "github.com/paketo-buildpacks/packit/v2/vacation" ) type ArchiveFile struct { Name string Content []byte } func main() { tarBuffer := bytes.NewBuffer(nil) tw := tar.NewWriter(tarBuffer) tarFiles := []ArchiveFile{ {Name: "some-tar-dir/"}, {Name: "some-tar-dir/some-tar-file", Content: []byte("some-tar-dir/some-tar-file")}, {Name: "tar-file", Content: []byte("tar-file")}, } for _, file := range tarFiles { err := tw.WriteHeader(&tar.Header{Name: file.Name, Mode: 0755, Size: int64(len(file.Content))}) if err != nil { log.Fatal(err) } _, err = tw.Write(file.Content) if err != nil { log.Fatal(err) } } tw.Close() zipBuffer := bytes.NewBuffer(nil) zw := zip.NewWriter(zipBuffer) zipFiles := []ArchiveFile{ {Name: "some-zip-dir/"}, {Name: "some-zip-dir/some-zip-file", Content: []byte("some-zip-dir/some-zip-file")}, {Name: "zip-file", Content: []byte("zip-file")}, } for _, file := range zipFiles { header := &zip.FileHeader{Name: file.Name} header.SetMode(0755) f, err := zw.CreateHeader(header) if err != nil { log.Fatal(err) } if _, err := f.Write(file.Content); err != nil { log.Fatal(err) } } zw.Close() destination, err := os.MkdirTemp("", "destination") if err != nil { log.Fatal(err) } defer os.RemoveAll(destination) archive := vacation.NewArchive(bytes.NewReader(tarBuffer.Bytes())).StripComponents(1) if err := archive.Decompress(destination); err != nil { log.Fatal(err) } archive = vacation.NewArchive(bytes.NewReader(zipBuffer.Bytes())).StripComponents(1) if err := archive.Decompress(destination); err != nil { log.Fatal(err) } err = filepath.Walk(destination, func(path string, info os.FileInfo, err error) error { if !info.IsDir() { rel, err := filepath.Rel(destination, path) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", rel) return nil } return nil }) if err != nil { log.Fatal(err) } }
Output: some-tar-file some-zip-file
type Bzip2Archive ¶
type Bzip2Archive struct {
// contains filtered or unexported fields
}
A Bzip2Archive decompresses bzip2 files from an input stream.
Example ¶
package main import ( "bytes" "fmt" "log" "os" "path/filepath" dsnetBzip2 "github.com/dsnet/compress/bzip2" "github.com/paketo-buildpacks/packit/v2/vacation" ) func main() { buffer := bytes.NewBuffer(nil) // Using the dsnet library because the Go compression library does not // have a writer. There is recent discussion on this issue // https://github.com/golang/go/issues/4828 to add an encoder. The // library should be removed once there is a native encoder bz, err := dsnetBzip2.NewWriter(buffer, nil) if err != nil { log.Fatal(err) } _, err = bz.Write([]byte(`Bzip2 file contents`)) if err != nil { log.Fatal(err) } bz.Close() destination, err := os.MkdirTemp("", "destination") if err != nil { log.Fatal(err) } defer os.RemoveAll(destination) archive := vacation.NewBzip2Archive(bytes.NewReader(buffer.Bytes())).WithName("bzip2-file") if err := archive.Decompress(destination); err != nil { log.Fatal(err) } contents, err := os.ReadFile(filepath.Join(destination, "bzip2-file")) if err != nil { log.Fatal(err) } fmt.Println(string(contents)) }
Output: Bzip2 file contents
func NewBzip2Archive ¶
func NewBzip2Archive(inputReader io.Reader) Bzip2Archive
NewBzip2Archive returns a new Bzip2Archive that reads from inputReader.
func (Bzip2Archive) Decompress ¶
func (bz Bzip2Archive) Decompress(destination string) error
Decompress reads from Bzip2Archive and writes files into the destination specified.
func (Bzip2Archive) StripComponents ¶
func (bz Bzip2Archive) StripComponents(components int) Bzip2Archive
StripComponents behaves like the --strip-components flag on tar command removing the first n levels from the final decompression destination.
Example ¶
package main import ( "archive/tar" "bytes" "fmt" "log" "os" "path/filepath" dsnetBzip2 "github.com/dsnet/compress/bzip2" "github.com/paketo-buildpacks/packit/v2/vacation" ) type ArchiveFile struct { Name string Content []byte } func main() { buffer := bytes.NewBuffer(nil) // Using the dsnet library because the Go compression library does not // have a writer. There is recent discussion on this issue // https://github.com/golang/go/issues/4828 to add an encoder. The // library should be removed once there is a native encoder bz, err := dsnetBzip2.NewWriter(buffer, nil) if err != nil { log.Fatal(err) } tw := tar.NewWriter(bz) files := []ArchiveFile{ {Name: "some-dir/"}, {Name: "some-dir/some-other-dir/"}, {Name: "some-dir/some-other-dir/some-file", Content: []byte("some-dir/some-other-dir/some-file")}, {Name: "first", Content: []byte("first")}, {Name: "second", Content: []byte("second")}, {Name: "third", Content: []byte("third")}, } for _, file := range files { err := tw.WriteHeader(&tar.Header{Name: file.Name, Mode: 0755, Size: int64(len(file.Content))}) if err != nil { log.Fatal(err) } _, err = tw.Write(file.Content) if err != nil { log.Fatal(err) } } tw.Close() bz.Close() destination, err := os.MkdirTemp("", "destination") if err != nil { log.Fatal(err) } defer os.RemoveAll(destination) archive := vacation.NewBzip2Archive(bytes.NewReader(buffer.Bytes())).StripComponents(1) if err := archive.Decompress(destination); err != nil { log.Fatal(err) } err = filepath.Walk(destination, func(path string, info os.FileInfo, err error) error { if !info.IsDir() { rel, err := filepath.Rel(destination, path) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", rel) return nil } return nil }) if err != nil { log.Fatal(err) } }
Output: some-other-dir/some-file
func (Bzip2Archive) WithName ¶
func (bz Bzip2Archive) WithName(name string) Bzip2Archive
WithName provides a way of overriding the name of the file that the decompressed file will be copied into.
type Decompressor ¶
type Executable ¶
type Executable struct {
// contains filtered or unexported fields
}
An Executable writes an executable files from an input stream to the with a file name specified by the option `Executable.WithName()` (or defaults to `artifact`) in the destination directory with executable permissions (0755).
func NewExecutable ¶
func NewExecutable(inputReader io.Reader) Executable
NewExecutable returns a new Executable that reads from inputReader.
func (Executable) Decompress ¶
func (e Executable) Decompress(destination string) error
Decompress copies the reader contents into the destination specified and sets executable permissions.
func (Executable) WithName ¶
func (e Executable) WithName(name string) Executable
WithName provides a way of overriding the name of the file that the decompressed file will be copied into.
type GzipArchive ¶
type GzipArchive struct {
// contains filtered or unexported fields
}
A GzipArchive decompresses gzipped files from an input stream.
Example ¶
package main import ( "bytes" "compress/gzip" "fmt" "log" "os" "path/filepath" "github.com/paketo-buildpacks/packit/v2/vacation" ) func main() { buffer := bytes.NewBuffer(nil) gw := gzip.NewWriter(buffer) _, err := gw.Write([]byte(`Gzip file contents`)) if err != nil { log.Fatal(err) } gw.Close() destination, err := os.MkdirTemp("", "destination") if err != nil { log.Fatal(err) } defer os.RemoveAll(destination) archive := vacation.NewGzipArchive(bytes.NewReader(buffer.Bytes())).WithName("gzip-file") if err := archive.Decompress(destination); err != nil { log.Fatal(err) } content, err := os.ReadFile(filepath.Join(destination, "gzip-file")) if err != nil { log.Fatal(err) } fmt.Println(string(content)) }
Output: Gzip file contents
func NewGzipArchive ¶
func NewGzipArchive(inputReader io.Reader) GzipArchive
NewGzipArchive returns a new GzipArchive that reads from inputReader.
func (GzipArchive) Decompress ¶
func (gz GzipArchive) Decompress(destination string) error
Decompress reads from GzipArchive and writes files into the destination specified.
func (GzipArchive) StripComponents ¶
func (gz GzipArchive) StripComponents(components int) GzipArchive
StripComponents behaves like the --strip-components flag on tar command removing the first n levels from the final decompression destination.
Example ¶
package main import ( "archive/tar" "bytes" "compress/gzip" "fmt" "log" "os" "path/filepath" "github.com/paketo-buildpacks/packit/v2/vacation" ) type ArchiveFile struct { Name string Content []byte } func main() { buffer := bytes.NewBuffer(nil) gw := gzip.NewWriter(buffer) tw := tar.NewWriter(gw) files := []ArchiveFile{ {Name: "some-dir/"}, {Name: "some-dir/some-other-dir/"}, {Name: "some-dir/some-other-dir/some-file", Content: []byte("some-dir/some-other-dir/some-file")}, {Name: "first", Content: []byte("first")}, {Name: "second", Content: []byte("second")}, {Name: "third", Content: []byte("third")}, } for _, file := range files { err := tw.WriteHeader(&tar.Header{Name: file.Name, Mode: 0755, Size: int64(len(file.Content))}) if err != nil { log.Fatal(err) } _, err = tw.Write(file.Content) if err != nil { log.Fatal(err) } } tw.Close() gw.Close() destination, err := os.MkdirTemp("", "destination") if err != nil { log.Fatal(err) } defer os.RemoveAll(destination) archive := vacation.NewGzipArchive(bytes.NewReader(buffer.Bytes())).StripComponents(1) if err := archive.Decompress(destination); err != nil { log.Fatal(err) } err = filepath.Walk(destination, func(path string, info os.FileInfo, err error) error { if !info.IsDir() { rel, err := filepath.Rel(destination, path) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", rel) return nil } return nil }) if err != nil { log.Fatal(err) } }
Output: some-other-dir/some-file
func (GzipArchive) WithName ¶
func (gz GzipArchive) WithName(name string) GzipArchive
WithName provides a way of overriding the name of the file that the decompressed file will be copied into.
type NopArchive ¶
type NopArchive struct {
// contains filtered or unexported fields
}
A NopArchive implements the common archive interface, but acts as a no-op, simply copying the reader to the destination with a file name specified by the option `NopArchive.WithName()` (or defaults to `artifact`) in the destination directory.
func NewNopArchive ¶
func NewNopArchive(r io.Reader) NopArchive
NewNopArchive returns a new NopArchive
func (NopArchive) Decompress ¶
func (na NopArchive) Decompress(destination string) error
Decompress copies the reader contents into the destination specified.
func (NopArchive) WithName ¶
func (na NopArchive) WithName(name string) NopArchive
WithName provides a way of overriding the name of the file that the decompressed file will be copied into.
type TarArchive ¶
type TarArchive struct {
// contains filtered or unexported fields
}
A TarArchive decompresses tar files from an input stream.
Example ¶
package main import ( "archive/tar" "bytes" "fmt" "log" "os" "path/filepath" "github.com/paketo-buildpacks/packit/v2/vacation" ) type ArchiveFile struct { Name string Content []byte } func main() { buffer := bytes.NewBuffer(nil) tw := tar.NewWriter(buffer) files := []ArchiveFile{ {Name: "some-dir/"}, {Name: "some-dir/some-other-dir/"}, {Name: "some-dir/some-other-dir/some-file", Content: []byte("some-dir/some-other-dir/some-file")}, {Name: "first", Content: []byte("first")}, {Name: "second", Content: []byte("second")}, {Name: "third", Content: []byte("third")}, } for _, file := range files { err := tw.WriteHeader(&tar.Header{Name: file.Name, Mode: 0755, Size: int64(len(file.Content))}) if err != nil { log.Fatal(err) } _, err = tw.Write(file.Content) if err != nil { log.Fatal(err) } } tw.Close() destination, err := os.MkdirTemp("", "destination") if err != nil { log.Fatal(err) } defer os.RemoveAll(destination) archive := vacation.NewTarArchive(bytes.NewReader(buffer.Bytes())) if err := archive.Decompress(destination); err != nil { log.Fatal(err) } err = filepath.Walk(destination, func(path string, info os.FileInfo, err error) error { if !info.IsDir() { rel, err := filepath.Rel(destination, path) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", rel) return nil } return nil }) if err != nil { log.Fatal(err) } }
Output: first second some-dir/some-other-dir/some-file third
func NewTarArchive ¶
func NewTarArchive(inputReader io.Reader) TarArchive
NewTarArchive returns a new TarArchive that reads from inputReader.
func (TarArchive) Decompress ¶
func (ta TarArchive) Decompress(destination string) error
Decompress reads from TarArchive and writes files into the destination specified.
func (TarArchive) StripComponents ¶
func (ta TarArchive) StripComponents(components int) TarArchive
StripComponents behaves like the --strip-components flag on tar command removing the first n levels from the final decompression destination.
Example ¶
package main import ( "archive/tar" "bytes" "fmt" "log" "os" "path/filepath" "github.com/paketo-buildpacks/packit/v2/vacation" ) type ArchiveFile struct { Name string Content []byte } func main() { buffer := bytes.NewBuffer(nil) tw := tar.NewWriter(buffer) files := []ArchiveFile{ {Name: "some-dir/"}, {Name: "some-dir/some-other-dir/"}, {Name: "some-dir/some-other-dir/some-file", Content: []byte("some-dir/some-other-dir/some-file")}, {Name: "first", Content: []byte("first")}, {Name: "second", Content: []byte("second")}, {Name: "third", Content: []byte("third")}, } for _, file := range files { err := tw.WriteHeader(&tar.Header{Name: file.Name, Mode: 0755, Size: int64(len(file.Content))}) if err != nil { log.Fatal(err) } _, err = tw.Write(file.Content) if err != nil { log.Fatal(err) } } tw.Close() destination, err := os.MkdirTemp("", "destination") if err != nil { log.Fatal(err) } defer os.RemoveAll(destination) archive := vacation.NewTarArchive(bytes.NewReader(buffer.Bytes())).StripComponents(1) if err := archive.Decompress(destination); err != nil { log.Fatal(err) } err = filepath.Walk(destination, func(path string, info os.FileInfo, err error) error { if !info.IsDir() { rel, err := filepath.Rel(destination, path) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", rel) return nil } return nil }) if err != nil { log.Fatal(err) } }
Output: some-other-dir/some-file
type XZArchive ¶
type XZArchive struct {
// contains filtered or unexported fields
}
A XZArchive decompresses xz files from an input stream.
Example ¶
package main import ( "bytes" "fmt" "log" "os" "path/filepath" "github.com/paketo-buildpacks/packit/v2/vacation" "github.com/ulikunitz/xz" ) func main() { buffer := bytes.NewBuffer(nil) xw, err := xz.NewWriter(buffer) if err != nil { log.Fatal(err) } _, err = xw.Write([]byte(`XZ file contents`)) if err != nil { log.Fatal(err) } xw.Close() destination, err := os.MkdirTemp("", "destination") if err != nil { log.Fatal(err) } defer os.RemoveAll(destination) archive := vacation.NewXZArchive(bytes.NewReader(buffer.Bytes())).WithName("xz-file") if err := archive.Decompress(destination); err != nil { log.Fatal(err) } contents, err := os.ReadFile(filepath.Join(destination, "xz-file")) if err != nil { log.Fatal(err) } fmt.Println(string(contents)) }
Output: XZ file contents
func NewXZArchive ¶
NewXZArchive returns a new XZArchive that reads from inputReader.
func (XZArchive) Decompress ¶
Decompress reads from XZArchive and writes files into the destination specified.
func (XZArchive) StripComponents ¶
StripComponents behaves like the --strip-components flag on tar command removing the first n levels from the final decompression destination.
Example ¶
package main import ( "archive/tar" "bytes" "fmt" "log" "os" "path/filepath" "github.com/paketo-buildpacks/packit/v2/vacation" "github.com/ulikunitz/xz" ) type ArchiveFile struct { Name string Content []byte } func main() { buffer := bytes.NewBuffer(nil) xw, err := xz.NewWriter(buffer) if err != nil { log.Fatal(err) } tw := tar.NewWriter(xw) files := []ArchiveFile{ {Name: "some-dir/"}, {Name: "some-dir/some-other-dir/"}, {Name: "some-dir/some-other-dir/some-file", Content: []byte("some-dir/some-other-dir/some-file")}, {Name: "first", Content: []byte("first")}, {Name: "second", Content: []byte("second")}, {Name: "third", Content: []byte("third")}, } for _, file := range files { err := tw.WriteHeader(&tar.Header{Name: file.Name, Mode: 0755, Size: int64(len(file.Content))}) if err != nil { log.Fatal(err) } _, err = tw.Write(file.Content) if err != nil { log.Fatal(err) } } tw.Close() xw.Close() destination, err := os.MkdirTemp("", "destination") if err != nil { log.Fatal(err) } defer os.RemoveAll(destination) archive := vacation.NewXZArchive(bytes.NewReader(buffer.Bytes())).StripComponents(1) if err := archive.Decompress(destination); err != nil { log.Fatal(err) } err = filepath.Walk(destination, func(path string, info os.FileInfo, err error) error { if !info.IsDir() { rel, err := filepath.Rel(destination, path) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", rel) return nil } return nil }) if err != nil { log.Fatal(err) } }
Output: some-other-dir/some-file
type ZipArchive ¶
type ZipArchive struct {
// contains filtered or unexported fields
}
A ZipArchive decompresses zip files from an input stream.
Example ¶
package main import ( "archive/zip" "bytes" "fmt" "log" "os" "path/filepath" "github.com/paketo-buildpacks/packit/v2/vacation" ) type ArchiveFile struct { Name string Content []byte } func main() { buffer := bytes.NewBuffer(nil) zw := zip.NewWriter(buffer) files := []ArchiveFile{ {Name: "some-dir/"}, {Name: "some-dir/some-other-dir/"}, {Name: "some-dir/some-other-dir/some-file", Content: []byte("some-dir/some-other-dir/some-file")}, {Name: "first", Content: []byte("first")}, {Name: "second", Content: []byte("second")}, {Name: "third", Content: []byte("third")}, } for _, file := range files { header := &zip.FileHeader{Name: file.Name} header.SetMode(0755) f, err := zw.CreateHeader(header) if err != nil { log.Fatal(err) } if _, err := f.Write(file.Content); err != nil { log.Fatal(err) } } zw.Close() destination, err := os.MkdirTemp("", "destination") if err != nil { log.Fatal(err) } defer os.RemoveAll(destination) archive := vacation.NewZipArchive(bytes.NewReader(buffer.Bytes())) if err := archive.Decompress(destination); err != nil { log.Fatal(err) } err = filepath.Walk(destination, func(path string, info os.FileInfo, err error) error { if !info.IsDir() { rel, err := filepath.Rel(destination, path) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", rel) return nil } return nil }) if err != nil { log.Fatal(err) } }
Output: first second some-dir/some-other-dir/some-file third
func NewZipArchive ¶
func NewZipArchive(inputReader io.Reader) ZipArchive
NewZipArchive returns a new ZipArchive that reads from inputReader.
func (ZipArchive) Decompress ¶
func (z ZipArchive) Decompress(destination string) error
Decompress reads from ZipArchive and writes files into the destination specified.
func (ZipArchive) StripComponents ¶
func (z ZipArchive) StripComponents(components int) ZipArchive
StripComponents removes the first n levels from the final decompression destination.