Created
August 5, 2012 01:26
-
-
Save cbiffle/3260999 to your computer and use it in GitHub Desktop.
Recursively walk a filesystem using node.js (CoffeeScript)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| fs = require 'fs' | |
| path = require 'path' | |
| events = require 'events' | |
| # Recursively walks a filesystem tree, emitting what it finds. | |
| # The EventEmitter produces the following events: | |
| # ('file', pathname) for each file discovered. | |
| # ('dir', pathname) for each directory discovered. | |
| # ('end') when traversal is complete. | |
| walk = (pathname) -> | |
| ee = new events.EventEmitter | |
| # outstanding, closureCreated, and closureCompleted provide reference counting | |
| # of the EventEmitter ee. This lets us determine the right moment to emit | |
| # the 'end' event. | |
| outstanding = 0 | |
| closureCreated = (count = 1) -> | |
| outstanding += count | |
| closureCompleted = -> | |
| outstanding-- | |
| if outstanding == 0 then ee.emit 'end' | |
| # Recursion helper function that does the real work | |
| helper = (pathname) -> | |
| ee.emit 'dir', pathname | |
| closureCreated() | |
| fs.readdir pathname, (err, children) -> | |
| if children | |
| closureCreated(children.length) | |
| children.forEach (child) -> | |
| childpath = path.join(pathname, child) | |
| closureCreated() | |
| fs.stat childpath, (err, stat) -> | |
| if stat and stat.isDirectory() | |
| helper childpath | |
| else | |
| ee.emit 'file', childpath | |
| closureCompleted() | |
| closureCompleted() | |
| closureCompleted() | |
| # Kick off recursion and return | |
| helper pathname | |
| return ee | |
| files = (pathname) -> | |
| ee = walk pathname | |
| filtered = new events.EventEmitter | |
| ee.on 'file', (pathname) -> filtered.emit 'file', pathname | |
| ee.on 'end', -> filtered.emit 'end' | |
| return filtered | |
| module.exports = { | |
| all: walk | |
| files: files | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment