Skip to content

Commit

Permalink
Adds tar XZ decompression to vacation
Browse files Browse the repository at this point in the history
  • Loading branch information
ForestEckhardt committed Apr 3, 2020
1 parent 7fa9226 commit f28a085
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 10 deletions.
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ go 1.13

require (
github.com/BurntSushi/toml v0.3.1
github.com/MasterMinds/semver v1.5.0
github.com/Masterminds/semver v1.5.0
github.com/blang/semver v3.5.1+incompatible
github.com/cheggaaa/pb/v3 v3.0.4
github.com/fatih/color v1.9.0 // indirect
github.com/golang/protobuf v1.3.2 // indirect
Expand All @@ -16,6 +14,7 @@ require (
github.com/onsi/ginkgo v1.11.0 // indirect
github.com/onsi/gomega v1.9.0
github.com/sclevine/spec v1.4.0
github.com/ulikunitz/xz v0.5.7
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa // indirect
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 // indirect
golang.org/x/text v0.3.2 // indirect
Expand Down
9 changes: 2 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/MasterMinds/semver v1.5.0 h1:o48A/g5pIW8F7DsAw/uxspF/Yi1BNgVoSd2LnCiEKIU=
github.com/MasterMinds/semver v1.5.0/go.mod h1:VgTz+o1W0Y0VH2fNMYqTNX5yF13A7uet9xzz3Iqu2pY=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
github.com/blang/semver v1.1.0 h1:ol1rO7QQB5uy7umSNV7VAmLugfLRD+17sYJujRNYPhg=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/cheggaaa/pb/v3 v3.0.4 h1:QZEPYOj2ix6d5oEg63fbHmpolrnNiwjUsk+h74Yt4bM=
github.com/cheggaaa/pb/v3 v3.0.4/go.mod h1:7rgWxLrAUcFMkvJuv09+DYi7mMUYi8nO9iOWcvGJPfw=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
Expand Down Expand Up @@ -44,12 +39,12 @@ github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg=
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8=
github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM=
github.com/ulikunitz/xz v0.5.7 h1:YvTNdFzX6+W5m9msiYg/zpkSURPPtOlzbqYjrFn7Yt4=
github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down
21 changes: 20 additions & 1 deletion vacation/vacation.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"io"
"os"
"path/filepath"

"github.com/ulikunitz/xz"
)

type TarArchive struct {
Expand All @@ -17,6 +19,10 @@ type TarGzipArchive struct {
reader io.Reader
}

type TarXZArchive struct {
reader io.Reader
}

func NewTarArchive(inputReader io.Reader) TarArchive {
return TarArchive{reader: inputReader}
}
Expand All @@ -25,6 +31,10 @@ func NewTarGzipArchive(inputReader io.Reader) TarGzipArchive {
return TarGzipArchive{reader: inputReader}
}

func NewTarXZArchive(inputReader io.Reader) TarXZArchive {
return TarXZArchive{reader: inputReader}
}

func (ta TarArchive) Decompress(destination string) error {
tarReader := tar.NewReader(ta.reader)
for {
Expand Down Expand Up @@ -75,8 +85,17 @@ func (ta TarArchive) Decompress(destination string) error {
func (gz TarGzipArchive) Decompress(destination string) error {
gzr, err := gzip.NewReader(gz.reader)
if err != nil {
return fmt.Errorf("failed to create gzip reader: %s", err)
return fmt.Errorf("failed to create gzip reader: %w", err)
}

return NewTarArchive(gzr).Decompress(destination)
}

func (txz TarXZArchive) Decompress(destination string) error {
xzr, err := xz.NewReader(txz.reader)
if err != nil {
return fmt.Errorf("failed to create xz reader: %w", err)
}

return NewTarArchive(xzr).Decompress(destination)
}
91 changes: 91 additions & 0 deletions vacation/vacation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/cloudfoundry/packit/vacation"
"github.com/sclevine/spec"
"github.com/ulikunitz/xz"

. "github.com/onsi/gomega"
)
Expand Down Expand Up @@ -250,4 +251,94 @@ func testVacation(t *testing.T, context spec.G, it spec.S) {
})
})
})

context("TarXZArchive.Decompress", func() {
var (
tempDir string
tarXZArchive vacation.TarXZArchive
)

it.Before(func() {
var err error
tempDir, err = ioutil.TempDir("", "vacation")
Expect(err).NotTo(HaveOccurred())

buffer := bytes.NewBuffer(nil)
xzw, err := xz.NewWriter(buffer)
Expect(err).NotTo(HaveOccurred())

tw := tar.NewWriter(xzw)

Expect(tw.WriteHeader(&tar.Header{Name: "some-dir", Mode: 0755, Typeflag: tar.TypeDir})).To(Succeed())
_, err = tw.Write(nil)
Expect(err).NotTo(HaveOccurred())

Expect(tw.WriteHeader(&tar.Header{Name: filepath.Join("some-dir", "some-other-dir"), Mode: 0755, Typeflag: tar.TypeDir})).To(Succeed())
_, err = tw.Write(nil)
Expect(err).NotTo(HaveOccurred())

nestedFile := filepath.Join("some-dir", "some-other-dir", "some-file")
Expect(tw.WriteHeader(&tar.Header{Name: nestedFile, Mode: 0755, Size: int64(len(nestedFile))})).To(Succeed())
_, err = tw.Write([]byte(nestedFile))
Expect(err).NotTo(HaveOccurred())

for _, file := range []string{"first", "second", "third"} {
Expect(tw.WriteHeader(&tar.Header{Name: file, Mode: 0755, Size: int64(len(file))})).To(Succeed())
_, err = tw.Write([]byte(file))
Expect(err).NotTo(HaveOccurred())
}

Expect(tw.WriteHeader(&tar.Header{Name: "symlink", Mode: 0777, Size: int64(0), Typeflag: tar.TypeSymlink, Linkname: "first"})).To(Succeed())
_, err = tw.Write([]byte{})
Expect(err).NotTo(HaveOccurred())

Expect(tw.Close()).To(Succeed())
Expect(xzw.Close()).To(Succeed())

tarXZArchive = vacation.NewTarXZArchive(bytes.NewReader(buffer.Bytes()))

})

it.After(func() {
Expect(os.RemoveAll(tempDir)).To(Succeed())
})

it("downloads the dependency and unpackages it into the path", func() {
var err error
err = tarXZArchive.Decompress(tempDir)
Expect(err).ToNot(HaveOccurred())

files, err := filepath.Glob(fmt.Sprintf("%s/*", tempDir))
Expect(err).NotTo(HaveOccurred())
Expect(files).To(ConsistOf([]string{
filepath.Join(tempDir, "first"),
filepath.Join(tempDir, "second"),
filepath.Join(tempDir, "third"),
filepath.Join(tempDir, "some-dir"),
filepath.Join(tempDir, "symlink"),
}))

info, err := os.Stat(filepath.Join(tempDir, "first"))
Expect(err).NotTo(HaveOccurred())
Expect(info.Mode()).To(Equal(os.FileMode(0755)))

Expect(filepath.Join(tempDir, "some-dir", "some-other-dir")).To(BeADirectory())
Expect(filepath.Join(tempDir, "some-dir", "some-other-dir", "some-file")).To(BeARegularFile())

data, err := ioutil.ReadFile(filepath.Join(tempDir, "symlink"))
Expect(err).NotTo(HaveOccurred())
Expect(data).To(Equal([]byte(`first`)))
})

context("failure cases", func() {
context("when it fails to create a xz reader", func() {
it("returns an error", func() {
readyArchive := vacation.NewTarXZArchive(bytes.NewBuffer([]byte(`something`)))

err := readyArchive.Decompress(tempDir)
Expect(err).To(MatchError(ContainSubstring("failed to create xz reader")))
})
})
})
})
}

0 comments on commit f28a085

Please sign in to comment.