1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-08 03:31:59 +02:00
goreleaser/internal/testlib/archive.go
Carlos Alexandro Becker 3c7a63979c
test: ensure utf-8 sources/archives filenames work properly (#3925)
This now works for files added to the source archive **after** the `git
archive` command is run. During the `git archive`, it seems that the
`tar` is still using some format that doesn't support utf-8 by default.

Tomorrow I'll look more into it.

see https://pkg.go.dev/archive/tar#Format

closes #3812

---------

Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com>
Co-Authored-By: Mohammed Al Sahaf <msaa1990@gmail.com>
2023-04-15 15:48:14 -03:00

153 lines
3.0 KiB
Go

package testlib
import (
"archive/tar"
"archive/zip"
"compress/gzip"
"io"
"os"
"testing"
"github.com/stretchr/testify/require"
"github.com/ulikunitz/xz"
)
// GetFileFromArchive returns the contents of filename inside the given archive
// path.
func GetFileFromArchive(tb testing.TB, path, format, filename string) []byte {
tb.Helper()
f := openFile(tb, path)
switch format {
case "tar.gz", "tgz":
return catTarFile(tb, openGzip(tb, f), filename)
case "tar.xz", "txz":
return catTarFile(tb, openXz(tb, f), filename)
case "tar":
return catTarFile(tb, f, filename)
case "zip":
return catZipFile(tb, f, filename)
case "gz":
out, err := io.ReadAll(openGzip(tb, f))
require.NoError(tb, err)
return out
default:
tb.Errorf("invalid format: %s", format)
return nil
}
}
// LsArchive return the file list of a given archive in a given formatkj
func LsArchive(tb testing.TB, path, format string) []string {
tb.Helper()
f := openFile(tb, path)
switch format {
case "tar.gz", "tgz":
return doLsTar(openGzip(tb, f))
case "tar.xz", "txz":
return doLsTar(openXz(tb, f))
case "tar":
return doLsTar(f)
case "zip":
return lsZip(tb, f)
case "gz":
return []string{openGzip(tb, f).Header.Name}
default:
tb.Errorf("invalid format: %s", format)
return nil
}
}
func openGzip(tb testing.TB, r io.Reader) *gzip.Reader {
tb.Helper()
gz, err := gzip.NewReader(r)
require.NoError(tb, err)
return gz
}
func openXz(tb testing.TB, r io.Reader) *xz.Reader {
tb.Helper()
xz, err := xz.NewReader(r)
require.NoError(tb, err)
return xz
}
func catZipFile(tb testing.TB, f *os.File, path string) []byte {
tb.Helper()
stat, err := f.Stat()
require.NoError(tb, err)
z, err := zip.NewReader(f, stat.Size())
require.NoError(tb, err)
for _, zf := range z.File {
if path == zf.Name {
zz, err := zf.Open()
require.NoError(tb, err)
tb.Cleanup(func() { require.NoError(tb, zz.Close()) })
bts, err := io.ReadAll(zz)
require.NoError(tb, err)
return bts
}
}
return nil
}
func lsZip(tb testing.TB, f *os.File) []string {
tb.Helper()
stat, err := f.Stat()
require.NoError(tb, err)
z, err := zip.NewReader(f, stat.Size())
require.NoError(tb, err)
var paths []string
for _, zf := range z.File {
paths = append(paths, zf.Name)
}
return paths
}
func catTarFile(tb testing.TB, f io.Reader, path string) []byte {
tb.Helper()
z := tar.NewReader(f)
for {
h, err := z.Next()
if h == nil || err == io.EOF {
break
}
if h.Format == tar.FormatPAX {
continue
}
if h.Name == path {
out, err := io.ReadAll(z)
require.NoError(tb, err)
return out
}
}
return nil
}
func doLsTar(f io.Reader) []string {
z := tar.NewReader(f)
var paths []string
for {
h, err := z.Next()
if h == nil || err == io.EOF {
break
}
if h.Name == "pax_global_header" {
continue
}
paths = append(paths, h.Name)
}
return paths
}
func openFile(tb testing.TB, path string) *os.File {
tb.Helper()
f, err := os.Open(path)
require.NoError(tb, err)
return f
}