mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-01-30 04:50:45 +02:00
parent
fbddb7081d
commit
e538341179
2
go.mod
2
go.mod
@ -215,7 +215,7 @@ require (
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||
github.com/klauspost/compress v1.17.7 // indirect
|
||||
github.com/klauspost/compress v1.17.7
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/letsencrypt/boulder v0.0.0-20231026200631-000cd05d5491 // indirect
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"github.com/goreleaser/goreleaser/pkg/archive/tar"
|
||||
"github.com/goreleaser/goreleaser/pkg/archive/targz"
|
||||
"github.com/goreleaser/goreleaser/pkg/archive/tarxz"
|
||||
"github.com/goreleaser/goreleaser/pkg/archive/tarzst"
|
||||
"github.com/goreleaser/goreleaser/pkg/archive/zip"
|
||||
"github.com/goreleaser/goreleaser/pkg/config"
|
||||
)
|
||||
@ -31,6 +32,8 @@ func New(w io.Writer, format string) (Archive, error) {
|
||||
return gzip.New(w), nil
|
||||
case "tar.xz", "txz":
|
||||
return tarxz.New(w), nil
|
||||
case "tar.zst":
|
||||
return tarzst.New(w), nil
|
||||
case "zip":
|
||||
return zip.New(w), nil
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ func TestArchive(t *testing.T) {
|
||||
require.NoError(t, empty.Close())
|
||||
require.NoError(t, os.Mkdir(folder+"/folder-inside", 0o755))
|
||||
|
||||
for _, format := range []string{"tar.gz", "zip", "gz", "tar.xz", "tar", "tgz", "txz"} {
|
||||
for _, format := range []string{"tar.gz", "zip", "gz", "tar.xz", "tar", "tgz", "txz", "tar.zst"} {
|
||||
format := format
|
||||
t.Run(format, func(t *testing.T) {
|
||||
f1, err := os.Create(filepath.Join(t.TempDir(), "1.tar"))
|
||||
@ -37,7 +37,7 @@ func TestArchive(t *testing.T) {
|
||||
require.NoError(t, archive.Close())
|
||||
require.NoError(t, f1.Close())
|
||||
|
||||
if format == "tar.xz" || format == "txz" || format == "gz" {
|
||||
if format == "tar.xz" || format == "txz" || format == "gz" || format == "tar.zst" {
|
||||
_, err := Copying(f1, io.Discard, format)
|
||||
require.Error(t, err)
|
||||
return
|
||||
|
40
pkg/archive/tarzst/tarzst.go
Normal file
40
pkg/archive/tarzst/tarzst.go
Normal file
@ -0,0 +1,40 @@
|
||||
// Package tarzst implements the Archive interface providing tar.zst archiving
|
||||
// and compression.
|
||||
package tarzst
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/goreleaser/goreleaser/pkg/archive/tar"
|
||||
"github.com/goreleaser/goreleaser/pkg/config"
|
||||
"github.com/klauspost/compress/zstd"
|
||||
)
|
||||
|
||||
// Archive as tar.zst.
|
||||
type Archive struct {
|
||||
zstw *zstd.Encoder
|
||||
tw *tar.Archive
|
||||
}
|
||||
|
||||
// New tar.zst archive.
|
||||
func New(target io.Writer) Archive {
|
||||
zstw, _ := zstd.NewWriter(target)
|
||||
tw := tar.New(zstw)
|
||||
return Archive{
|
||||
zstw: zstw,
|
||||
tw: &tw,
|
||||
}
|
||||
}
|
||||
|
||||
// Close all closeables.
|
||||
func (a Archive) Close() error {
|
||||
if err := a.tw.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return a.zstw.Close()
|
||||
}
|
||||
|
||||
// Add file to the archive.
|
||||
func (a Archive) Add(f config.File) error {
|
||||
return a.tw.Add(f)
|
||||
}
|
157
pkg/archive/tarzst/tarzst_test.go
Normal file
157
pkg/archive/tarzst/tarzst_test.go
Normal file
@ -0,0 +1,157 @@
|
||||
package tarzst
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/goreleaser/goreleaser/pkg/config"
|
||||
"github.com/klauspost/compress/zstd"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestTarZstFile(t *testing.T) {
|
||||
tmp := t.TempDir()
|
||||
f, err := os.Create(filepath.Join(tmp, "test.tar.zst"))
|
||||
require.NoError(t, err)
|
||||
defer f.Close() // nolint: errcheck
|
||||
archive := New(f)
|
||||
defer archive.Close() // nolint: errcheck
|
||||
|
||||
require.Error(t, archive.Add(config.File{
|
||||
Source: "../testdata/nope.txt",
|
||||
Destination: "nope.txt",
|
||||
}))
|
||||
require.NoError(t, archive.Add(config.File{
|
||||
Source: "../testdata/foo.txt",
|
||||
Destination: "foo.txt",
|
||||
}))
|
||||
require.NoError(t, archive.Add(config.File{
|
||||
Source: "../testdata/sub1",
|
||||
Destination: "sub1",
|
||||
}))
|
||||
require.NoError(t, archive.Add(config.File{
|
||||
Source: "../testdata/sub1/bar.txt",
|
||||
Destination: "sub1/bar.txt",
|
||||
}))
|
||||
require.NoError(t, archive.Add(config.File{
|
||||
Source: "../testdata/sub1/executable",
|
||||
Destination: "sub1/executable",
|
||||
}))
|
||||
require.NoError(t, archive.Add(config.File{
|
||||
Source: "../testdata/sub1/sub2",
|
||||
Destination: "sub1/sub2",
|
||||
}))
|
||||
require.NoError(t, archive.Add(config.File{
|
||||
Source: "../testdata/sub1/sub2/subfoo.txt",
|
||||
Destination: "sub1/sub2/subfoo.txt",
|
||||
}))
|
||||
require.NoError(t, archive.Add(config.File{
|
||||
Source: "../testdata/regular.txt",
|
||||
Destination: "regular.txt",
|
||||
}))
|
||||
require.NoError(t, archive.Add(config.File{
|
||||
Source: "../testdata/link.txt",
|
||||
Destination: "link.txt",
|
||||
}))
|
||||
|
||||
require.NoError(t, archive.Close())
|
||||
require.Error(t, archive.Add(config.File{
|
||||
Source: "tar.go",
|
||||
Destination: "tar.go",
|
||||
}))
|
||||
require.NoError(t, f.Close())
|
||||
|
||||
f, err = os.Open(f.Name())
|
||||
require.NoError(t, err)
|
||||
defer f.Close() // nolint: errcheck
|
||||
|
||||
info, err := f.Stat()
|
||||
require.NoError(t, err)
|
||||
require.Lessf(t, info.Size(), int64(500), "archived file should be smaller than %d", info.Size())
|
||||
|
||||
zstf, err := zstd.NewReader(f)
|
||||
require.NoError(t, err)
|
||||
|
||||
var paths []string
|
||||
r := tar.NewReader(zstf)
|
||||
for {
|
||||
next, err := r.Next()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
require.NoError(t, err)
|
||||
paths = append(paths, next.Name)
|
||||
if next.Name == "sub1/executable" {
|
||||
ex := next.FileInfo().Mode()&0o111 != 0
|
||||
require.True(t, ex, "expected executable permissions, got %s", next.FileInfo().Mode())
|
||||
}
|
||||
if next.Name == "link.txt" {
|
||||
require.Equal(t, "regular.txt", next.Linkname)
|
||||
}
|
||||
}
|
||||
require.Equal(t, []string{
|
||||
"foo.txt",
|
||||
"sub1",
|
||||
"sub1/bar.txt",
|
||||
"sub1/executable",
|
||||
"sub1/sub2",
|
||||
"sub1/sub2/subfoo.txt",
|
||||
"regular.txt",
|
||||
"link.txt",
|
||||
}, paths)
|
||||
}
|
||||
|
||||
func TestTarZstFileInfo(t *testing.T) {
|
||||
now := time.Now().Truncate(time.Second)
|
||||
f, err := os.Create(filepath.Join(t.TempDir(), "test.tar.gz"))
|
||||
require.NoError(t, err)
|
||||
defer f.Close() // nolint: errcheck
|
||||
archive := New(f)
|
||||
defer archive.Close() // nolint: errcheck
|
||||
|
||||
require.NoError(t, archive.Add(config.File{
|
||||
Source: "../testdata/foo.txt",
|
||||
Destination: "nope.txt",
|
||||
Info: config.FileInfo{
|
||||
Mode: 0o755,
|
||||
Owner: "carlos",
|
||||
Group: "root",
|
||||
ParsedMTime: now,
|
||||
},
|
||||
}))
|
||||
|
||||
require.NoError(t, archive.Close())
|
||||
require.NoError(t, f.Close())
|
||||
|
||||
f, err = os.Open(f.Name())
|
||||
require.NoError(t, err)
|
||||
defer f.Close() // nolint: errcheck
|
||||
|
||||
zstf, err := zstd.NewReader(f)
|
||||
require.NoError(t, err)
|
||||
|
||||
var found int
|
||||
r := tar.NewReader(zstf)
|
||||
for {
|
||||
next, err := r.Next()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
found++
|
||||
require.Equal(t, "nope.txt", next.Name)
|
||||
require.Equal(t, now, next.ModTime)
|
||||
require.Equal(t, fs.FileMode(0o755), next.FileInfo().Mode())
|
||||
require.Equal(t, "carlos", next.Uname)
|
||||
require.Equal(t, 0, next.Uid)
|
||||
require.Equal(t, "root", next.Gname)
|
||||
require.Equal(t, 0, next.Gid)
|
||||
}
|
||||
require.Equal(t, 1, found)
|
||||
}
|
@ -24,7 +24,17 @@ archives:
|
||||
# If format is `binary`, no archives are created and the binaries are instead
|
||||
# uploaded directly.
|
||||
#
|
||||
# Valid options are `tar.gz`, `tgz`, `tar.xz`, `txz`, tar`, `gz`, `zip`, and `binary`.
|
||||
# Valid options are:
|
||||
# - `tar.gz`
|
||||
# - `tgz`
|
||||
# - `tar.xz`
|
||||
# - `txz`
|
||||
# - `tar.zst` (Since v1.26)
|
||||
# - `tar`
|
||||
# - `gz`
|
||||
# - `zip`
|
||||
# - `binary`
|
||||
#
|
||||
# Default: 'tar.gz'
|
||||
format: zip
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user