1
0
mirror of https://github.com/golang/go synced 2024-11-26 03:17:57 -07:00

archive/zip: add AddFS method to zip Writer

The method AddFS can be used to add the contents of a fs.FS filesystem
to a zip archive.
This method walks the directory tree starting at the root of the filesystem
and adds each file to the archive.

Fixes #54898

Change-Id: I80511cbd91a1d7e09ee52d2d1b09fb5eed25f45f
GitHub-Last-Rev: 1e17f2e6ba
GitHub-Pull-Request: golang/go#61602
Reviewed-on: https://go-review.googlesource.com/c/go/+/513438
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@google.com>
This commit is contained in:
Mauri de Souza Meneguzzo 2023-07-27 23:11:59 +00:00 committed by Gopher Robot
parent 789980ec0e
commit 845fff35c6
3 changed files with 83 additions and 0 deletions

1
api/next/54898.txt Normal file
View File

@ -0,0 +1 @@
pkg archive/zip, method (*Writer) AddFS(fs.FS) error #54898

View File

@ -11,6 +11,7 @@ import (
"hash"
"hash/crc32"
"io"
"io/fs"
"strings"
"unicode/utf8"
)
@ -495,6 +496,41 @@ func (w *Writer) RegisterCompressor(method uint16, comp Compressor) {
w.compressors[method] = comp
}
// AddFS adds the files from fs.FS to the archive.
// It walks the directory tree starting at the root of the filesystem
// adding each file to the zip using deflate while maintaining the directory structure.
func (w *Writer) AddFS(fsys fs.FS) error {
return fs.WalkDir(fsys, ".", func(name string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
info, err := d.Info()
if err != nil {
return err
}
h, err := FileInfoHeader(info)
if err != nil {
return err
}
h.Name = name
h.Method = Deflate
fw, err := w.CreateHeader(h)
if err != nil {
return err
}
f, err := fsys.Open(name)
if err != nil {
return err
}
defer f.Close()
_, err = io.Copy(fw, f)
return err
})
}
func (w *Writer) compressor(method uint16) Compressor {
comp := w.compressors[method]
if comp == nil {

View File

@ -16,6 +16,7 @@ import (
"os"
"strings"
"testing"
"testing/fstest"
"time"
)
@ -602,3 +603,48 @@ func BenchmarkCompressedZipGarbage(b *testing.B) {
}
})
}
func writeTestsToFS(tests []WriteTest) fs.FS {
fsys := fstest.MapFS{}
for _, wt := range tests {
fsys[wt.Name] = &fstest.MapFile{
Data: wt.Data,
Mode: wt.Mode,
}
}
return fsys
}
func TestWriterAddFS(t *testing.T) {
buf := new(bytes.Buffer)
w := NewWriter(buf)
tests := []WriteTest{
{
Name: "file.go",
Data: []byte("hello"),
Mode: 0644,
},
{
Name: "subfolder/another.go",
Data: []byte("world"),
Mode: 0644,
},
}
err := w.AddFS(writeTestsToFS(tests))
if err != nil {
t.Fatal(err)
}
if err := w.Close(); err != nil {
t.Fatal(err)
}
// read it back
r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
if err != nil {
t.Fatal(err)
}
for i, wt := range tests {
testReadFile(t, r.File[i], &wt)
}
}