Skip to content

Commit 2c34c2a

Browse files
authored
Merge pull request #292 from yaroot/zstd
add zstd support
2 parents b5c372b + 000cae8 commit 2c34c2a

14 files changed

+215
-0
lines changed

decompress.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ func init() {
2626
tbzDecompressor := new(TarBzip2Decompressor)
2727
tgzDecompressor := new(TarGzipDecompressor)
2828
txzDecompressor := new(TarXzDecompressor)
29+
tzstDecompressor := new(TarZstdDecompressor)
2930

3031
Decompressors = map[string]Decompressor{
3132
"bz2": new(Bzip2Decompressor),
@@ -34,10 +35,13 @@ func init() {
3435
"tar.bz2": tbzDecompressor,
3536
"tar.gz": tgzDecompressor,
3637
"tar.xz": txzDecompressor,
38+
"tar.zst": tzstDecompressor,
3739
"tbz2": tbzDecompressor,
3840
"tgz": tgzDecompressor,
3941
"txz": txzDecompressor,
42+
"tzst": tzstDecompressor,
4043
"zip": new(ZipDecompressor),
44+
"zst": new(ZstdDecompressor),
4145
}
4246
}
4347

decompress_tzst.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package getter
2+
3+
import (
4+
"fmt"
5+
"github.com/klauspost/compress/zstd"
6+
"os"
7+
"path/filepath"
8+
)
9+
10+
// TarZstdDecompressor is an implementation of Decompressor that can
11+
// decompress tar.zstd files.
12+
type TarZstdDecompressor struct{}
13+
14+
func (d *TarZstdDecompressor) Decompress(dst, src string, dir bool, umask os.FileMode) error {
15+
// If we're going into a directory we should make that first
16+
mkdir := dst
17+
if !dir {
18+
mkdir = filepath.Dir(dst)
19+
}
20+
if err := os.MkdirAll(mkdir, mode(0755, umask)); err != nil {
21+
return err
22+
}
23+
24+
// File first
25+
f, err := os.Open(src)
26+
if err != nil {
27+
return err
28+
}
29+
defer f.Close()
30+
31+
// Zstd compression is second
32+
zstdR, err := zstd.NewReader(f)
33+
if err != nil {
34+
return fmt.Errorf("Error opening a zstd reader for %s: %s", src, err)
35+
}
36+
defer zstdR.Close()
37+
38+
return untar(zstdR, dst, src, dir, umask)
39+
}

decompress_tzst_test.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package getter
2+
3+
import (
4+
"path/filepath"
5+
"testing"
6+
)
7+
8+
func TestTarZstdDecompressor(t *testing.T) {
9+
10+
multiplePaths := []string{"dir/", "dir/test2", "test1"}
11+
orderingPaths := []string{"workers/", "workers/mq/", "workers/mq/__init__.py"}
12+
13+
cases := []TestDecompressCase{
14+
{
15+
"empty.tar.zst",
16+
false,
17+
true,
18+
nil,
19+
"",
20+
nil,
21+
},
22+
23+
{
24+
"single.tar.zst",
25+
false,
26+
false,
27+
nil,
28+
"d3b07384d113edec49eaa6238ad5ff00",
29+
nil,
30+
},
31+
32+
{
33+
"single.tar.zst",
34+
true,
35+
false,
36+
[]string{"file"},
37+
"",
38+
nil,
39+
},
40+
41+
{
42+
"multiple.tar.zst",
43+
true,
44+
false,
45+
[]string{"file1", "file2"},
46+
"",
47+
nil,
48+
},
49+
50+
{
51+
"multiple.tar.zst",
52+
false,
53+
true,
54+
nil,
55+
"",
56+
nil,
57+
},
58+
59+
{
60+
"multiple_dir.tar.zst",
61+
true,
62+
false,
63+
multiplePaths,
64+
"",
65+
nil,
66+
},
67+
68+
// Tests when the file is listed before the parent folder
69+
{
70+
"ordering.tar.zst",
71+
true,
72+
false,
73+
orderingPaths,
74+
"",
75+
nil,
76+
},
77+
78+
// Tests that a tar.zst can't contain references with "..".
79+
// GNU `tar` also disallows this.
80+
{
81+
"outside_parent.tar.zst",
82+
true,
83+
true,
84+
nil,
85+
"",
86+
nil,
87+
},
88+
}
89+
90+
for i, tc := range cases {
91+
cases[i].Input = filepath.Join("./testdata", "decompress-tzst", tc.Input)
92+
}
93+
94+
TestDecompressor(t, new(TarZstdDecompressor), cases)
95+
}

decompress_zstd.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package getter
2+
3+
import (
4+
"fmt"
5+
"github.com/klauspost/compress/zstd"
6+
"os"
7+
"path/filepath"
8+
)
9+
10+
// ZstdDecompressor is an implementation of Decompressor that
11+
// can decompress .zst files.
12+
type ZstdDecompressor struct{}
13+
14+
func (d *ZstdDecompressor) Decompress(dst, src string, dir bool, umask os.FileMode) error {
15+
if dir {
16+
return fmt.Errorf("zstd-compressed files can only unarchive to a single file")
17+
}
18+
19+
// If we're going into a directory we should make that first
20+
if err := os.MkdirAll(filepath.Dir(dst), mode(0755, umask)); err != nil {
21+
return err
22+
}
23+
24+
// File first
25+
f, err := os.Open(src)
26+
if err != nil {
27+
return err
28+
}
29+
defer f.Close()
30+
31+
// zstd compression is second
32+
zstdR, err := zstd.NewReader(f)
33+
if err != nil {
34+
return err
35+
}
36+
defer zstdR.Close()
37+
38+
// Copy it out
39+
return copyReader(dst, zstdR, 0622, umask)
40+
}

decompress_zstd_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package getter
2+
3+
import (
4+
"path/filepath"
5+
"testing"
6+
)
7+
8+
func TestZstdDecompressor(t *testing.T) {
9+
cases := []TestDecompressCase{
10+
{
11+
"single.zst",
12+
false,
13+
false,
14+
nil,
15+
"d3b07384d113edec49eaa6238ad5ff00",
16+
nil,
17+
},
18+
19+
{
20+
"single.zst",
21+
true,
22+
true,
23+
nil,
24+
"",
25+
nil,
26+
},
27+
}
28+
29+
for i, tc := range cases {
30+
cases[i].Input = filepath.Join("./testdata", "decompress-zst", tc.Input)
31+
}
32+
33+
TestDecompressor(t, new(ZstdDecompressor), cases)
34+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ require (
1010
github.com/hashicorp/go-cleanhttp v0.5.0
1111
github.com/hashicorp/go-safetemp v1.0.0
1212
github.com/hashicorp/go-version v1.1.0
13+
github.com/klauspost/compress v1.11.2
1314
github.com/mattn/go-colorable v0.0.9 // indirect
1415
github.com/mattn/go-isatty v0.0.4 // indirect
1516
github.com/mattn/go-runewidth v0.0.4 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
5454
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE=
5555
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
5656
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
57+
github.com/klauspost/compress v1.11.2 h1:MiK62aErc3gIiVEtyzKfeOHgW7atJb5g/KNX5m3c2nQ=
58+
github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
5759
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
5860
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
5961
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
22 Bytes
Binary file not shown.
121 Bytes
Binary file not shown.
153 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)