title: Recursive directory creation for Node.js 0.5.x
body: <p>I have a function that downloads a file and saves it in a nested directory structure based on parameters sent to it (ex: ./somedir/a/b/c or ./somedir2/a/d/b). I cannot trust that any directory along the way has been created so I need to have each directory along the filepath checked and created if it doesn't exist. Now, I have some code that works perfectly for Node 0.4.x, but something has broken in at least the Windows version of Node 0.5.x (tested on 0.5.10 specifically). </p>
  
  <p>I am terrible with understanding filesystems, so if someone could figure out how I could make this work or replace it with something else that works similarly, I would very much appreciate it. The goal is to have code that would function properly on both Unix and Windows as well as Node 0.4.x and 0.5.x.</p>
  
  <pre><code>// automatically create directories if they do not exist at a path
  function mkdirs(_path, mode, callback) {
    var dirs = _path.split("/");
    var walker = [dirs.shift()];
  
    var walk = function (ds, acc, m, cb) {
      if (ds.length &gt; 0) {
        var d = ds.shift();
        acc.push(d);
        var dir = acc.join("/");
  
        fs.stat(dir, function (err, stat) {
          if (err) {
            // file does not exist
            if (err.errno == 2) {
              fs.mkdir(dir, m, function (erro) {
                if (erro &amp;&amp; erro.errno != 17) {
                  terminal.error(erro, "Failed to make " + dir);
                  return cb(new Error("Failed to make " + dir + "\n" + erro));
                } else {
                  return walk(ds, acc, m, cb);
                }
              });
            } else {
              return cb(err);
            }
          } else {
            if (stat.isDirectory()) {
              return walk(ds, acc, m, cb);
            } else {
              return cb(new Error("Failed to mkdir " + dir + ": File exists\n"));
            }
          }
        });
      } else {
        return cb();
      }
    };
    return walk(dirs, walker, mode, callback);
  };
  </code></pre>
  
  <p>Example Usage:</p>
  
  <pre><code>mkdirs('/path/to/file/directory/', 0777, function(err){
  </code></pre>
  
  <p>EDIT: Update for Node 0.8.x (in CoffeeScript):</p>
  
  <pre><code># 
  # Function mkdirs
  # Ensures all directories in a path exist by creating those that don't
  # @params
  #    path:      string of the path to create (directories only, no files!)
  #    mode:      the integer permission level
  #    callback:  the callback to be used when complete
  # @callback
  #    an error object or false
  #
  mkdirs = (path, mode, callback) -&gt;
    tryDirectory = (dir, cb) -&gt;
      fs.stat dir, (err, stat) -&gt;
        if err #the file doesn't exist, try one stage earlier then create
          if err.errno is 2 or err.errno is 32 or err.errno is 34
            if dir.lastIndexOf("/") is dir.indexOf("/") #only slash remaining is initial slash
              #should only be triggered when path is '/' in Unix, or 'C:/' in Windows
              cb new Error("notfound")
            else
              tryDirectory dir.substr(0, dir.lastIndexOf("/")), (err) -&gt;
                if err #error, return
                  cb err
                else #make this directory
                  fs.mkdir dir, mode, (error) -&gt;
                    if error and error.errno isnt 17
                      cb new Error("failed")
                    else
                      cb()
          else #unkown error
            cb err
        else
          if stat.isDirectory() #directory exists, no need to check previous directories
            cb()
          else #file exists at location, cannot make folder
            cb new Error("exists")
    path = (if path.indexOf("\\") &gt;= 0 then path.replace("\\", "/") else path) #change windows slashes to unix
    path = path.substr(0, path.length - 1)  if path.substr(path.length - 1) is "/" #remove trailing slash
    tryDirectory path, callback
  </code></pre>