@@ -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
147146func (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
230229func getParentPath (path string ) string {
0 commit comments