node-fs-updater
Repeatedly write an in-memory directory tree to disk, with incremental updating.
Installation
This package requires Node version 6.0.0 or newer.
npm install --save fs-updater
Usage
let FSUpdater = ;let File Directory DirectoryIndex = FSUpdater; // output_dir must either be an empty directory or not exist at alllet fsUpdater = './output_dir'
Let's create the following directory structure, where ->
indicates a symlink
(or a copy on Windows):
output_dir
├── file -> /path/to/some/file
├── dir1/ -> /path/to/some/dir
└── dir2/
└── another_file -> /path/to/another/file
let dir = 'file' '/path/to/some/file' 'dir1' '/path/to/some/dir' 'dir2' 'another_file' '/path/to/another/file' ; // Write it to ./output_dirfsUpdater;
Now let's create an updated similar directory structure:
.
├── file -> /path/to/some/file
└── dir1/ -> /path/to/some/dir
dir = 'file' '/path/to/some/file' 'dir1' '/path/to/some/dir'; // Now update output_dir incrementallyfsUpdater;
Object re-use
It is recommended that you rebuild all your File
, Directory
and
DirectoryIndex
objects from scratch each time you call fsUpdater.update
. If
you re-use objects, the following rules apply:
First, do not mutate the objects that you pass into FSUpdater
, or their
sub-objects. That is, after calling fsUpdater.update(dir)
, you must no longer
call dir.set(...)
.
Second, you may re-use unchanged File
, Directory
and DirectoryIndex
objects only if you know that the file contents they point to recursively
have not changed. This is typically only the case if they point into directories
that you control, and if those directories in turn contain no symlinks to
outside directories under the user's control.
For example, this is always OK:
let file = '/the/file';fsUpdater
But this is only OK if the contents of /the/file
have not changed between
calls to .update
:
let file = '/the/file';fsUpdater
Reference
-
FSUpdater
: An object used to repeatedly update an output directory.-
new FSUpdater(outputPath, options)
: Create a newFSUpdater
object. TheoutputPath
must be an empty directory or absent.It is important that the
FSUpdater
has exclusive access to theoutputPath
directory.FSUpdater.prototype.update
calls rimraf, which can be dangerous in the presence of symlinks if unexpected changes have been made to theoutputPath
directory.options.canSymlink
(boolean): If true, use symlinks; if false, copy files and use junctions. Ifnull
(default), auto-detect. -
FSUpdater.prototype.update(directory)
: Update theoutputPath
directory to mirror the contents of thedirectory
object, which is either aDirectoryIndex
(an in-memory directory) or aDirectory
(a directory on disk).Important note: You may re-use
File
objects contained in theDirectoryIndex
between repeated calls to.update()
only if the file contents have not changed. Similarly, you may re-useDirectoryIndex
andDirectory
objects only if no changes have been made to the directory or any files or subdirectories recursively, including those reachable through symlinks.
-
-
FSUpdater.DirectoryIndex
: A subclass of Map representing an in-memory directory; see the documentation there.DirectoryIndex
objects map file names (string
primitives, without paths) toDirectoryIndex
,Directory
orFile
objects. -
FSUpdater.Directory
: A directory on disk. Think of this as an in-memory symlink to a directory.-
new Directory(path)
: Create a newDirectory
object pointing to the directory atpath
. -
Directory.prototype.valueOf()
: Return thepath
. -
Directory.prototype.getIndexSync()
: Read the physical directory and return aDirectoryIndex
. TheDirectoryIndex
object is cached between repeated calls togetIndexSync()
.
-
-
FSUpdater.File
: Represents a file on disk. Think of this as an in-memory symlink.-
new File(path)
: Create a newFile
object pointing to the file atpath
. -
File.prototype.valueOf()
: Return thepath
.
-
-
FSUpdater.makeFSObject(path)
: Return aFile
orDirectory
object, depending on the file type on disk. This function follows symlinks.
Contributing
Clone this repo and run the tests like so:
npm install
npm test
Issues and pull requests are welcome. If you change code, be sure to re-run
npm test
. Oftentimes it's useful to add or update tests as well.