fs-pathdigger v2.0.4
fs-pathdigger
Recursively walks a filesystem and allows modifications and filtering to the rersults
Usage
const walk = require ('fs-pathdigger');
walk( /root/path/to/start/from, options )
// => returns an object with two properties,
// one for folders and one for files.
In a nutshell
fs-pathdigger
starts at a specified root folder and walks the file system, returning an object with a folders
property, containing all the folders it finds (including empty ones) and a files
property, containing all the files it finds.
By default, hidden files are not returned and links are not followed, but that behavior can be altered by specifying the hidden
and followLinks
options, respectively.
fs-pathdigger understands the following options:
hidden => type: Boolean
=> Include hidden files/folders? (default: false)
followLinks => type: Boolean
=> Follow links? (default: false)
relative => type: Boolean
=> Return relative paths? (default: false)
include => type: RegEx, String, or Array
=> A pattern, or array of patterns
return only and any results that match
exclude => type: RegEx, String, or Array
=> A pattern, or array of patterns
exclude any results that match
precedence => type: String
=> Valid settings are 'folders' or 'files'
restricts filtering to one or the other
beforeRoot => type: String
=> Text to insert into each result
before the root folder
afterRoot => type: String
=> Text to insert into each result
after the root folder
beforeExt => type: String
=> Text to insert into each result
before the file extension
afterExt => type: String
=> Text to insert into each result
after the file extension
replaceExt => type: Map
=> A Map of extensions search and replace pairings
happens before insertions
Examples
All examples use the following tree:
.
|____test
| |____lab
| | |____otherFiles
| | | |____asset.png
| | |____index.html
| | |____source
| | | |____views2
| | | | |____view2a.js
| | | | |____view2b.js
| | | |____views1
| | | | |____view1a.jsx
| | | | |____view1b.jsx
| | |____emptyFolder
| | |____link (symbolic link to ../linked)
| | |____assets
| | | |____image1.jpg
| | | |____image2.jpg
| | |____.hiddenFile
| |____linked
| | |____linkedFile.html
Basic options - hidden, followLinks, relative
With no options at all (hidden files/folders being omitted and links treated like files),
walk ( "/test/lab" )
returns:
{
folders: [
'/test/lab',
'/test/lab/assets',
'/test/lab/emptyFolder',
'/test/lab/otherFiles',
'/test/lab/source',
'/test/lab/source/views1',
'/test/lab/source/views2'
],
files: [
'/test/lab/assets/image1.jpg',
'/test/lab/assets/image2.jpg',
'/test/lab/index.html',
'/test/lab/link',
'/test/lab/otherFiles/asset.png',
'/test/lab/source/views1/view1a.jsx',
'/test/lab/source/views1/view1b.jsx',
'/test/lab/source/views2/view2a.js',
'/test/lab/source/views2/view2b.js'
]
}
To include hidden files and following all links, set hidden
or followLinks
to true
, respectively
walk ( "/test/lab", { followLinks: true, hidden: true } )
would return the following:
{
folders: [
'/test/lab',
'/test/lab/assets',
'/test/lab/emptyFolder',
'/test/lab/link',
'/test/lab/otherFiles',
'/test/lab/source',
'/test/lab/source/views1',
'/test/lab/source/views2'
],
files: [
'/test/lab/.hiddenFile',
'/test/lab/assets/image1.jpg',
'/test/lab/assets/image2.jpg',
'/test/lab/index.html',
'/test/lab/link/linkedFile.html',
'/test/lab/otherFiles/asset.png',
'/test/lab/source/views1/view1a.jsx',
'/test/lab/source/views1/view1b.jsx',
'/test/lab/source/views2/view2a.js',
'/test/lab/source/views2/view2b.js'
]
}
To produce the same output as the last example, but return realtive paths, instead, set relative
to true
.
walk ( "/test/lab", { followLinks: true, hidden: true, relative: true } )
returns:
{
folders: [
'.',
'assets',
'emptyFolder',
'link',
'otherFiles',
'source',
'source/views1',
'source/views2'
],
files: [
'.hiddenFile',
'assets/image1.jpg',
'assets/image2.jpg',
'index.html',
'link/linkedFile.html',
'otherFiles/asset.png',
'source/views1/view1a.jsx',
'source/views1/view1b.jsx',
'source/views2/view2a.js',
'source/views2/view2b.js'
]
}
Advanced options - filtering and precedence
By default, fs-pathdigger
will return both arrays, folders
and files
with any filters applied to both results equally. In other words, by default, there is no correlation between the two results. Ergo,
walk ( "/test/lab", { include: /html/ } ) // => Using a regex pattern
returns:
{
folders: [],
files: [
'/test/lab/index.html'
]
}
and
walk ( "/test/lab", { include: "asset" } ) // => Using a regex string
returns:
{
folders: [
'/test/lab/assets',
],
files: [
'/test/lab/assets/image1.jpg',
'/test/lab/assets/image2.jpg',
'/test/lab/otherFiles/asset.png'
]
}
If you want to apply a filter only to one set of results, files
/folders
, and produce matching results for the other that correlate, use precedence
For example, let's say you wanted to apply filters to just the files
and have the folders
returned be just the parent folders for those file results, you would set the option precedence: 'files'
.
Likewise to apply filters to just the folders
returned, you would set the option precedence: 'folders'
. The files
returned would be all children of those folders
, regardless of filters applied.
Thus,
walk ( "/test/lab", { include: "asset", precedence: 'files' } )
returns:
{
folders: [
'/test/lab/assets',
'/test/lab/otherFiles'
],
files: [
'/test/lab/assets/image1.jpg',
'/test/lab/assets/image2.jpg',
'/test/lab/otherFiles/asset.png'
]
}
and
walk ( "/test/lab", { include: "asset", precedence: 'folders' } )
returns:
{
folders: [
'/test/lab/assets'
],
files: [
'/test/lab/assets/image1.jpg',
'/test/lab/assets/image2.jpg'
]
}
You can also exclude
patterns, as well, by using the exclude
option. Like, include
, the option takes either a pattern or an array of patterns.
walk ( "/test/lab", { exclude: [ /\.js.?$/, "html" ] } )
returns:
{
folders: [
'/test/lab',
'/test/lab/assets',
'/test/lab/emptyFolder',
'/test/lab/otherFiles',
'/test/lab/source',
'/test/lab/source/views1',
'/test/lab/source/views2'
],
files: [
'/test/lab/assets/image1.jpg',
'/test/lab/assets/image2.jpg',
'/test/lab/link',
'/test/lab/otherFiles/asset.png'
]
}
Using the same pattern in an include
and an exclude
will always produce a null result.
So, this:
walk ( "/test/lab", { exclude: [ /\.js.?$/, "html" ], include "html" } )
returns:
{
folders: [],
files: []
}
Extra options for inserting text and replacing file extensions
You can insert text before and after the root folder specified, in the results, by using the beforeRoot
and afterRoot
options. Paths will be normalized, so don't worry about unneeded slashes.
For example:
walk ( "/test/lab", { beforeRoot: "C:/", afterRoot: "/test/" } )
returns
{
folders: [
'C:/test/lab/test',
'C:/test/lab/test/assets',
'C:/test/lab/test/emptyFolder',
'C:/test/lab/test/otherFiles',
'C:/test/lab/test/source',
'C:/test/lab/test/source/views1',
'C:/test/lab/test/source/views2'
],
files: [
'C:/test/lab/test/assets/image1.jpg',
'C:/test/lab/test/assets/image2.jpg',
'C:/test/lab/test/index.html',
'C:/test/lab/test/link',
'C:/test/lab/test/source/views1/view1a.jsx',
'C:/test/lab/test/source/views1/view1b.jsx',
'C:/test/lab/test/source/views2/view2a.js',
'C:/test/lab/test/source/views2/view2b.js'
]
}
You can also insert text before and after all file extensions, in the results, by using the beforeExt
and afterExt
options. Note that files without extensions will be ignored by these options.
For example:
walk ( "/test/lab", { beforeExt: ".spec", afterExt: ".backup" } )
returns
{
folders: [
'/test/lab',
'/test/lab/assets',
'/test/lab/emptyFolder',
'/test/lab/otherFiles',
'/test/lab/source',
'/test/lab/source/views1',
'/test/lab/source/views2'
],
files: [
'/test/lab/assets/image1.spec.jpg.backup',
'/test/lab/assets/image2.spec.jpg.backup',
'/test/lab/index.spec.html.backup',
'/test/lab/link',
'/test/lab/otherFiles/asset.spec.png.backup',
'/test/lab/source/views1/view1a.spec.jsx.backup',
'/test/lab/source/views1/view1b.spec.jsx.backup',
'/test/lab/source/views2/view2a.spec.js.backup',
'/test/lab/source/views2/view2b.spec.js.backup'
]
}
If you want to be more specific, when modifying extensions, use the 'replaceExt' option. This option takes a Map of extensions to search for and their corresponding replacements. Provided extensions should be literal strings starting with a dot (.); patterns are not supported with this option.
Note that if for some reason you wanted to add an extension to all files with no extension, you can add ['','.some_extension']
to your Map.
For example:
let swapit = new Map([ ['.js','.spec.js'], ['.jsx','.spec.jsx'] ]);
walk ( "/test/lab", { replaceExt: swapit } )
returns:
{
folders: [
'/test/lab',
'/test/lab/assets',
'/test/lab/emptyFolder',
'/test/lab/otherFiles',
'/test/lab/source',
'/test/lab/source/views1',
'/test/lab/source/views2'
],
files: [
'/test/lab/assets/image1.jpg',
'/test/lab/assets/image2.jpg',
'/test/lab/index.html',
'/test/lab/link',
'/test/lab/otherFiles/asset.png',
'/test/lab/source/views1/view1a.spec.jsx',
'/test/lab/source/views1/view1b.spec.jsx',
'/test/lab/source/views2/view2a.spec.js',
'/test/lab/source/views2/view2b.spec.js'
]
}
TO-DOs
I don't know. You tell me.
Credit
fs-pathdigger
wouldn't be possible without my good friend, Oibaf.
I mostly did this for fun and to create something a little more robust and easier to use than other solutions I've tried. I hope you enjoy!
License
Licensed under MIT (Mother Insured Task) - a.k.a. contribute please, but no criticizing Oibaf's mother's cooking or she will beat you senseless with an old wooden soup ladel.
Copyleft (c) 2019 by Nosaj and Oibaf - "we code, you like, that how work"