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:
parent
789980ec0e
commit
845fff35c6
1
api/next/54898.txt
Normal file
1
api/next/54898.txt
Normal file
@ -0,0 +1 @@
|
||||
pkg archive/zip, method (*Writer) AddFS(fs.FS) error #54898
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user