Skip to content

Commit 83dd451

Browse files
MagicalTuxclaude
andcommitted
refactor: replace SetSourceFS/Add with AddFS, clean up writer API
Remove Writer.srcFS field and SetSourceFS method which could point to the wrong filesystem when multiple AddFS calls are made. Replace the exported Add WalkDirFunc with AddFS which captures the source fs.FS in a closure, ensuring each inode references the correct filesystem. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 57e0888 commit 83dd451

5 files changed

Lines changed: 80 additions & 105 deletions

File tree

debug_writer_test.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package squashfs
33
import (
44
"bytes"
55
"fmt"
6-
"io/fs"
76
"testing"
87
"testing/fstest"
98
)
@@ -27,9 +26,7 @@ func TestDebugWriterEntries(t *testing.T) {
2726
t.Fatalf("NewWriter failed: %s", err)
2827
}
2928

30-
w.SetSourceFS(testFS)
31-
32-
err = fs.WalkDir(testFS, ".", w.Add)
29+
err = w.AddFS(testFS)
3330
if err != nil {
3431
t.Fatalf("WalkDir failed: %s", err)
3532
}

writer.go

Lines changed: 66 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ type Writer struct {
3232
// Data tracking
3333
idTable map[uint32]uint32
3434
idList []uint32
35-
srcFS fs.FS
3635

3736
// Table positions (filled during Finalize)
3837
idTableStart uint64
@@ -145,86 +144,86 @@ func NewWriter(w io.Writer, opts ...WriterOption) (*Writer, error) {
145144
}
146145

147146
func (w *Writer) SetCompression(comp Compression) { w.comp = comp }
148-
func (w *Writer) SetSourceFS(srcFS fs.FS) { w.srcFS = srcFS }
149147

150-
func (w *Writer) Add(path string, d fs.DirEntry, err error) error {
151-
if err != nil {
152-
return err
153-
}
154-
if path == "." || path == "" {
155-
return nil
156-
}
148+
// AddFS walks the given filesystem and adds all entries to the writer.
149+
func (w *Writer) AddFS(srcFS fs.FS) error {
150+
return fs.WalkDir(srcFS, ".", func(p string, d fs.DirEntry, err error) error {
151+
if err != nil {
152+
return err
153+
}
154+
if p == "." || p == "" {
155+
return nil
156+
}
157157

158-
info, err := d.Info()
159-
if err != nil {
160-
return err
161-
}
158+
info, err := d.Info()
159+
if err != nil {
160+
return err
161+
}
162162

163-
w.inodeCount++
164-
inode := &writerInode{
165-
path: path,
166-
name: info.Name(),
167-
ino: w.inodeCount,
168-
mode: info.Mode(),
169-
size: uint64(info.Size()),
170-
modTime: info.ModTime().Unix(),
171-
nlink: 1,
172-
srcFS: w.srcFS,
173-
}
174-
175-
if sys := info.Sys(); sys != nil {
176-
if statT, ok := sys.(interface {
177-
Uid() uint32
178-
Gid() uint32
179-
}); ok {
180-
inode.uid = statT.Uid()
181-
inode.gid = statT.Gid()
163+
w.inodeCount++
164+
inode := &writerInode{
165+
path: p,
166+
name: info.Name(),
167+
ino: w.inodeCount,
168+
mode: info.Mode(),
169+
size: uint64(info.Size()),
170+
modTime: info.ModTime().Unix(),
171+
nlink: 1,
172+
srcFS: srcFS,
182173
}
183-
if statT, ok := sys.(interface {
184-
Rdev() uint32
185-
}); ok {
186-
inode.rdev = statT.Rdev()
174+
175+
if sys := info.Sys(); sys != nil {
176+
if statT, ok := sys.(interface {
177+
Uid() uint32
178+
Gid() uint32
179+
}); ok {
180+
inode.uid = statT.Uid()
181+
inode.gid = statT.Gid()
182+
}
183+
if statT, ok := sys.(interface {
184+
Rdev() uint32
185+
}); ok {
186+
inode.rdev = statT.Rdev()
187+
}
187188
}
188-
}
189189

190-
switch {
191-
case info.Mode().IsDir():
192-
inode.fileType = DirType
193-
inode.entries = make([]*writerInode, 0)
194-
inode.nlink = 2
195-
case info.Mode().IsRegular():
196-
inode.fileType = FileType
197-
case info.Mode()&fs.ModeSymlink != 0:
198-
inode.fileType = SymlinkType
199-
if inode.srcFS != nil {
200-
target, err := fs.ReadLink(inode.srcFS, path)
190+
switch {
191+
case info.Mode().IsDir():
192+
inode.fileType = DirType
193+
inode.entries = make([]*writerInode, 0)
194+
inode.nlink = 2
195+
case info.Mode().IsRegular():
196+
inode.fileType = FileType
197+
case info.Mode()&fs.ModeSymlink != 0:
198+
inode.fileType = SymlinkType
199+
target, err := fs.ReadLink(srcFS, p)
201200
if err != nil {
202201
return fmt.Errorf("readlink: %w", err)
203202
}
204203
inode.symTarget = target
205204
inode.size = uint64(len(target))
205+
case info.Mode()&fs.ModeCharDevice != 0:
206+
inode.fileType = CharDevType
207+
case info.Mode()&fs.ModeDevice != 0:
208+
inode.fileType = BlockDevType
209+
case info.Mode()&fs.ModeNamedPipe != 0:
210+
inode.fileType = FifoType
211+
case info.Mode()&fs.ModeSocket != 0:
212+
inode.fileType = SocketType
213+
default:
214+
inode.fileType = FileType
206215
}
207-
case info.Mode()&fs.ModeCharDevice != 0:
208-
inode.fileType = CharDevType
209-
case info.Mode()&fs.ModeDevice != 0:
210-
inode.fileType = BlockDevType
211-
case info.Mode()&fs.ModeNamedPipe != 0:
212-
inode.fileType = FifoType
213-
case info.Mode()&fs.ModeSocket != 0:
214-
inode.fileType = SocketType
215-
default:
216-
inode.fileType = FileType
217-
}
218216

219-
w.inodeMap[path] = inode
220-
parent := w.inodeMap[getParentPath(path)]
221-
if parent == nil {
222-
return fmt.Errorf("parent not found: %s", path)
223-
}
224-
inode.parent = parent
225-
parent.entries = append(parent.entries, inode)
217+
w.inodeMap[p] = inode
218+
parent := w.inodeMap[getParentPath(p)]
219+
if parent == nil {
220+
return fmt.Errorf("parent not found: %s", p)
221+
}
222+
inode.parent = parent
223+
parent.entries = append(parent.entries, inode)
226224

227-
return nil
225+
return nil
226+
})
228227
}
229228

230229
func getParentPath(path string) string {

writer_advanced_test.go

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,8 @@ func TestWriterWithSubdirectories(t *testing.T) {
2828
t.Fatalf("NewWriter failed: %s", err)
2929
}
3030

31-
// Set source filesystem for reading file data
32-
w.SetSourceFS(testFS)
33-
3431
// Add all files from testFS
35-
err = fs.WalkDir(testFS, ".", w.Add)
32+
err = w.AddFS(testFS)
3633
if err != nil {
3734
t.Fatalf("WalkDir failed: %s", err)
3835
}
@@ -104,11 +101,8 @@ func TestWriterWithLargeDirectory(t *testing.T) {
104101
t.Fatalf("NewWriter failed: %s", err)
105102
}
106103

107-
// Set source filesystem
108-
w.SetSourceFS(testFS)
109-
110104
// Add all files
111-
err = fs.WalkDir(testFS, ".", w.Add)
105+
err = w.AddFS(testFS)
112106
if err != nil {
113107
t.Fatalf("WalkDir failed: %s", err)
114108
}
@@ -179,11 +173,8 @@ func TestWriterWithNestedDirectories(t *testing.T) {
179173
t.Fatalf("NewWriter failed: %s", err)
180174
}
181175

182-
// Set source filesystem
183-
w.SetSourceFS(testFS)
184-
185176
// Add all files
186-
err = fs.WalkDir(testFS, ".", w.Add)
177+
err = w.AddFS(testFS)
187178
if err != nil {
188179
t.Fatalf("WalkDir failed: %s", err)
189180
}
@@ -250,11 +241,8 @@ func TestWriterMixedContent(t *testing.T) {
250241
t.Fatalf("NewWriter failed: %s", err)
251242
}
252243

253-
// Set source filesystem
254-
w.SetSourceFS(testFS)
255-
256244
// Add all files
257-
err = fs.WalkDir(testFS, ".", w.Add)
245+
err = w.AddFS(testFS)
258246
if err != nil {
259247
t.Fatalf("WalkDir failed: %s", err)
260248
}

writer_edge_cases_test.go

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ func TestWriterLongFilenames(t *testing.T) {
3737
t.Fatalf("NewWriter failed: %s", err)
3838
}
3939

40-
w.SetSourceFS(testFS)
41-
err = fs.WalkDir(testFS, ".", w.Add)
40+
err = w.AddFS(testFS)
4241
if err != nil {
4342
t.Fatalf("WalkDir failed: %s", err)
4443
}
@@ -110,8 +109,7 @@ func TestWriterVeryDeepNesting(t *testing.T) {
110109
t.Fatalf("NewWriter failed: %s", err)
111110
}
112111

113-
w.SetSourceFS(testFS)
114-
err = fs.WalkDir(testFS, ".", w.Add)
112+
err = w.AddFS(testFS)
115113
if err != nil {
116114
t.Fatalf("WalkDir failed: %s", err)
117115
}
@@ -174,8 +172,7 @@ func TestWriterWideDirectoryTree(t *testing.T) {
174172
t.Fatalf("NewWriter failed: %s", err)
175173
}
176174

177-
w.SetSourceFS(testFS)
178-
err = fs.WalkDir(testFS, ".", w.Add)
175+
err = w.AddFS(testFS)
179176
if err != nil {
180177
t.Fatalf("WalkDir failed: %s", err)
181178
}
@@ -260,8 +257,7 @@ func TestWriterSpecialCharactersInNames(t *testing.T) {
260257
t.Fatalf("NewWriter failed: %s", err)
261258
}
262259

263-
w.SetSourceFS(testFS)
264-
err = fs.WalkDir(testFS, ".", w.Add)
260+
err = w.AddFS(testFS)
265261
if err != nil {
266262
t.Fatalf("WalkDir failed: %s", err)
267263
}
@@ -332,8 +328,7 @@ func TestWriterMixedWideAndDeep(t *testing.T) {
332328
t.Fatalf("NewWriter failed: %s", err)
333329
}
334330

335-
w.SetSourceFS(testFS)
336-
err = fs.WalkDir(testFS, ".", w.Add)
331+
err = w.AddFS(testFS)
337332
if err != nil {
338333
t.Fatalf("WalkDir failed: %s", err)
339334
}
@@ -403,8 +398,7 @@ func TestWriterEmptyDirectoriesAtVariousLevels(t *testing.T) {
403398
t.Fatalf("NewWriter failed: %s", err)
404399
}
405400

406-
w.SetSourceFS(testFS)
407-
err = fs.WalkDir(testFS, ".", w.Add)
401+
err = w.AddFS(testFS)
408402
if err != nil {
409403
t.Fatalf("WalkDir failed: %s", err)
410404
}
@@ -468,8 +462,7 @@ func TestWriterLargeNumberOfInodes(t *testing.T) {
468462
t.Fatalf("NewWriter failed: %s", err)
469463
}
470464

471-
w.SetSourceFS(testFS)
472-
err = fs.WalkDir(testFS, ".", w.Add)
465+
err = w.AddFS(testFS)
473466
if err != nil {
474467
t.Fatalf("WalkDir failed: %s", err)
475468
}
@@ -543,8 +536,7 @@ func TestWriterVeryLongPath(t *testing.T) {
543536
t.Fatalf("NewWriter failed: %s", err)
544537
}
545538

546-
w.SetSourceFS(testFS)
547-
err = fs.WalkDir(testFS, ".", w.Add)
539+
err = w.AddFS(testFS)
548540
if err != nil {
549541
t.Fatalf("WalkDir failed: %s", err)
550542
}

writer_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package squashfs_test
22

33
import (
44
"bytes"
5-
"io/fs"
65
"os"
76
"testing"
87

@@ -19,7 +18,7 @@ func TestWriterBasic(t *testing.T) {
1918
}
2019

2120
// Add files using WalkDir
22-
err = fs.WalkDir(os.DirFS("testdata"), ".", w.Add)
21+
err = w.AddFS(os.DirFS("testdata"))
2322
if err != nil {
2423
t.Fatalf("WalkDir failed: %s", err)
2524
}

0 commit comments

Comments
 (0)