The new io/fs package introduced in Go 1.16 gives us a powerful new way of working with filesystems: that is, trees of files. In fact, the fs.FS interface can be used with more than just files: it abstracts the idea of a path-value map.
In principle, any set of objects that can be addressed by a hierarchy of pathnames can be represented by an fs.FS. A tree of disk files is the obvious example, but if we design our program to operate on an fs.FS value, it can also process ZIP and tar archives, Go modules, arbitrary JSON, YAML, or CUE data, or even Web resources addressed by URLs.
Walk with me, then, as we take a tour of the new io/fs package, the fs.FS interface in particular, and the power of the filesystem abstraction.
Suppose we have been tasked with writing a tool that will count the number of Go source files contained in some tree (for example, a project repository).
Now, how do we walk this tree? In other words, how do we recursively traverse each folder within the tree, and visit every file, no matter how deeply nested?