diff --git a/postal/service_test.go b/postal/service_test.go index 9daea968..84827b0f 100644 --- a/postal/service_test.go +++ b/postal/service_test.go @@ -450,7 +450,8 @@ version = "this is super not semver" context("when the file contents are empty", func() { it.Before(func() { - buffer := bytes.NewBuffer(nil) + // This is a FLAC header + buffer := bytes.NewBuffer([]byte("\x66\x4C\x61\x43\x00\x00\x00\x22")) transport.DropCall.Returns.ReadCloser = io.NopCloser(buffer) sum := sha256.Sum256(buffer.Bytes()) @@ -703,7 +704,8 @@ version = "this is super not semver" context("when the file contents are empty", func() { it.Before(func() { - buffer := bytes.NewBuffer(nil) + // This is a FLAC header + buffer := bytes.NewBuffer([]byte("\x66\x4C\x61\x43\x00\x00\x00\x22")) transport.DropCall.Returns.ReadCloser = io.NopCloser(buffer) sum := sha256.Sum256(buffer.Bytes()) diff --git a/vacation/init_test.go b/vacation/init_test.go index 1a3addce..03e4fb37 100644 --- a/vacation/init_test.go +++ b/vacation/init_test.go @@ -13,6 +13,7 @@ func TestVacation(t *testing.T) { suite("VacationTar", testVacationTar) suite("VacationTarGzip", testVacationTarGzip) suite("VacationTarXZ", testVacationTarXZ) + suite("VacationText", testVacationText) suite("VacationZip", testVacationZip) suite.Run(t) } diff --git a/vacation/vacation.go b/vacation/vacation.go index 484170d0..31a000fc 100644 --- a/vacation/vacation.go +++ b/vacation/vacation.go @@ -141,7 +141,6 @@ func (ta TarArchive) Decompress(destination string) error { if err != nil { return fmt.Errorf("failed to extract symlink: %s", err) } - } } @@ -150,6 +149,10 @@ func (ta TarArchive) Decompress(destination string) error { // 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 +// "artifact" in the destination directory. func (a Archive) Decompress(destination string) error { // Convert reader into a buffered read so that the header can be peeked to // determine the type. @@ -176,6 +179,10 @@ func (a Archive) Decompress(destination string) error { return NewTarXZArchive(bufferedReader).StripComponents(a.components).Decompress(destination) case "application/zip": return NewZipArchive(bufferedReader).Decompress(destination) + case "text/plain; charset=utf-8": + // This function will write the contents of the reader to file called + // "artifact" in the destination directory + return writeTextFile(bufferedReader, destination) default: return fmt.Errorf("unsupported archive type: %s", mime.String()) } @@ -203,6 +210,20 @@ func (txz TarXZArchive) Decompress(destination string) error { return NewTarArchive(xzr).StripComponents(txz.components).Decompress(destination) } +func writeTextFile(reader io.Reader, destination string) error { + file, err := os.Create(filepath.Join(destination, "artifact")) + if err != nil { + panic(err) + } + + _, err = io.Copy(file, reader) + if err != nil { + return err + } + + return nil +} + // 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 diff --git a/vacation/vacation_archive_test.go b/vacation/vacation_archive_test.go index 33ad9985..a52e773b 100644 --- a/vacation/vacation_archive_test.go +++ b/vacation/vacation_archive_test.go @@ -264,7 +264,8 @@ func testVacationArchive(t *testing.T, context spec.G, it spec.S) { tempDir, err = os.MkdirTemp("", "vacation") Expect(err).NotTo(HaveOccurred()) - buffer := bytes.NewBuffer([]byte(`some contents`)) + // This is a FLAC header + buffer := bytes.NewBuffer([]byte("\x66\x4C\x61\x43\x00\x00\x00\x22")) archive = vacation.NewArchive(buffer) }) diff --git a/vacation/vacation_text_test.go b/vacation/vacation_text_test.go new file mode 100644 index 00000000..24496a46 --- /dev/null +++ b/vacation/vacation_text_test.go @@ -0,0 +1,49 @@ +package vacation_test + +import ( + "bytes" + "os" + "path/filepath" + "testing" + + "github.com/paketo-buildpacks/packit/vacation" + "github.com/sclevine/spec" + + . "github.com/onsi/gomega" +) + +func testVacationText(t *testing.T, context spec.G, it spec.S) { + var ( + Expect = NewWithT(t).Expect + ) + + context("when passed the reader of a text file", func() { + var ( + archive vacation.Archive + tempDir string + ) + + it.Before(func() { + var err error + tempDir, err = os.MkdirTemp("", "vacation") + Expect(err).NotTo(HaveOccurred()) + + buffer := bytes.NewBuffer([]byte(`some contents`)) + + archive = vacation.NewArchive(buffer) + }) + + it.After(func() { + Expect(os.RemoveAll(tempDir)).To(Succeed()) + }) + + it("writes a text file onto the path", func() { + err := archive.Decompress(tempDir) + Expect(err).NotTo(HaveOccurred()) + + content, err := os.ReadFile(filepath.Join(tempDir, "artifact")) + Expect(err).NotTo(HaveOccurred()) + Expect(content).To(Equal([]byte(`some contents`))) + }) + }) +}