Source file src/cmd/go/internal/fsys/walk.go

     1  // Copyright 2024 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package fsys
     6  
     7  import (
     8  	"io/fs"
     9  	"path/filepath"
    10  )
    11  
    12  // Copied from path/filepath.
    13  
    14  // WalkDir is like filepath.WalkDir but over the virtual file system.
    15  func WalkDir(root string, fn fs.WalkDirFunc) error {
    16  	info, err := Lstat(root)
    17  	if err != nil {
    18  		err = fn(root, nil, err)
    19  	} else {
    20  		err = walkDir(root, fs.FileInfoToDirEntry(info), fn)
    21  	}
    22  	if err == filepath.SkipDir || err == filepath.SkipAll {
    23  		return nil
    24  	}
    25  	return err
    26  }
    27  
    28  // walkDir recursively descends path, calling walkDirFn.
    29  func walkDir(path string, d fs.DirEntry, walkDirFn fs.WalkDirFunc) error {
    30  	if err := walkDirFn(path, d, nil); err != nil || !d.IsDir() {
    31  		if err == filepath.SkipDir && d.IsDir() {
    32  			// Successfully skipped directory.
    33  			err = nil
    34  		}
    35  		return err
    36  	}
    37  
    38  	dirs, err := ReadDir(path)
    39  	if err != nil {
    40  		// Second call, to report ReadDir error.
    41  		err = walkDirFn(path, d, err)
    42  		if err != nil {
    43  			if err == filepath.SkipDir && d.IsDir() {
    44  				err = nil
    45  			}
    46  			return err
    47  		}
    48  	}
    49  
    50  	for _, d1 := range dirs {
    51  		path1 := filepath.Join(path, d1.Name())
    52  		if err := walkDir(path1, d1, walkDirFn); err != nil {
    53  			if err == filepath.SkipDir {
    54  				break
    55  			}
    56  			return err
    57  		}
    58  	}
    59  	return nil
    60  }
    61  

View as plain text