if err != nil {
return err
}
- if d.IsDir() {
+ if name == "." {
return nil
}
info, err := d.Info()
return err
}
// TODO(#49580): Handle symlinks when fs.ReadLinkFS is available.
- if !info.Mode().IsRegular() {
+ if !d.IsDir() && !info.Mode().IsRegular() {
return errors.New("tar: cannot add non-regular file")
}
h, err := FileInfoHeader(info, "")
if err := tw.WriteHeader(h); err != nil {
return err
}
+ if d.IsDir() {
+ return nil
+ }
f, err := fsys.Open(name)
if err != nil {
return err
func (sw sparseFileWriter) logicalRemaining() int64 {
return sw.sp[len(sw.sp)-1].endOffset() - sw.pos
}
+
func (sw sparseFileWriter) physicalRemaining() int64 {
return sw.fw.physicalRemaining()
}
"os"
"path"
"slices"
+ "sort"
"strings"
"testing"
"testing/fstest"
func TestWriterAddFS(t *testing.T) {
fsys := fstest.MapFS{
+ "emptyfolder": {Mode: 0o755 | os.ModeDir},
"file.go": {Data: []byte("hello")},
"subfolder/another.go": {Data: []byte("world")},
+ // Notably missing here is the "subfolder" directory. This makes sure even
+ // if we don't have a subfolder directory listed.
}
var buf bytes.Buffer
tw := NewWriter(&buf)
if err := tw.AddFS(fsys); err != nil {
t.Fatal(err)
}
+ if err := tw.Close(); err != nil {
+ t.Fatal(err)
+ }
+
+ // Add subfolder into fsys to match what we'll read from the tar.
+ fsys["subfolder"] = &fstest.MapFile{Mode: 0o555 | os.ModeDir}
// Test that we can get the files back from the archive
tr := NewReader(&buf)
- entries, err := fsys.ReadDir(".")
- if err != nil {
- t.Fatal(err)
+ names := make([]string, 0, len(fsys))
+ for name := range fsys {
+ names = append(names, name)
}
+ sort.Strings(names)
- var curfname string
- for _, entry := range entries {
- curfname = entry.Name()
- if entry.IsDir() {
- curfname += "/"
- continue
+ entriesLeft := len(fsys)
+ for _, name := range names {
+ entriesLeft--
+
+ entryInfo, err := fsys.Stat(name)
+ if err != nil {
+ t.Fatalf("getting entry info error: %v", err)
}
hdr, err := tr.Next()
if err == io.EOF {
t.Fatal(err)
}
- data, err := io.ReadAll(tr)
- if err != nil {
- t.Fatal(err)
+ if hdr.Name != name {
+ t.Errorf("test fs has filename %v; archive header has %v",
+ name, hdr.Name)
}
- if hdr.Name != curfname {
- t.Fatalf("got filename %v, want %v",
- curfname, hdr.Name)
+ if entryInfo.Mode() != hdr.FileInfo().Mode() {
+ t.Errorf("%s: test fs has mode %v; archive header has %v",
+ name, entryInfo.Mode(), hdr.FileInfo().Mode())
+ }
+
+ if entryInfo.IsDir() {
+ continue
}
- origdata := fsys[curfname].Data
+ data, err := io.ReadAll(tr)
+ if err != nil {
+ t.Fatal(err)
+ }
+ origdata := fsys[name].Data
if string(data) != string(origdata) {
- t.Fatalf("got file content %v, want %v",
+ t.Fatalf("test fs has file content %v; archive header has %v",
data, origdata)
}
}
+ if entriesLeft > 0 {
+ t.Fatalf("not all entries are in the archive")
+ }
}
func TestWriterAddFSNonRegularFiles(t *testing.T) {
// TestWriterComment is test for EOCD comment read/write.
func TestWriterComment(t *testing.T) {
- var tests = []struct {
+ tests := []struct {
comment string
ok bool
}{
}
func TestWriterUTF8(t *testing.T) {
- var utf8Tests = []struct {
+ utf8Tests := []struct {
name string
comment string
nonUTF8 bool
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,
- },
+ {Name: "emptyfolder", Mode: 0o755 | os.ModeDir},
+ {Name: "file.go", Data: []byte("hello"), Mode: 0644},
+ {Name: "subfolder/another.go", Data: []byte("world"), Mode: 0644},
+ // Notably missing here is the "subfolder" directory. This makes sure even
+ // if we don't have a subfolder directory listed.
}
err := w.AddFS(writeTestsToFS(tests))
if err != nil {
t.Fatal(err)
}
-
if err := w.Close(); err != nil {
t.Fatal(err)
}
+ // Add subfolder into fsys to match what we'll read from the tar.
+ tests = append(tests[:2:2], WriteTest{Name: "subfolder", Mode: 0o555 | os.ModeDir}, tests[2])
+
// read it back
r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
if err != nil {