Skip to content

Instantly share code, notes, and snippets.

@larzconwell
Created September 27, 2012 03:20
Show Gist options
  • Save larzconwell/3791977 to your computer and use it in GitHub Desktop.
Save larzconwell/3791977 to your computer and use it in GitHub Desktop.
#!/usr/bin/env node
var fs = require('fs')
, Path = require('path');
// Merge two objects together into the first one
function merge (object, otherObject) {
var obj = object || {}
, otherObj = otherObject || {}
, key, value;
for (key in otherObj) {
value = otherObj[key];
// Check if a value is an Object, if so recursively add it's key/values
if (typeof value === 'object' && !(value instanceof Array)) {
// Update value of object to the one from otherObj
obj[key] = merge(obj[key], value);
}
// Value is anything other than an Object, so just add it
else {
obj[key] = value;
}
}
return obj;
};
// Create a path, if it's a file can include content, otherwise
// just makes a directory
function writePath (path, content) {
var p = Path.normalize(path);
if (fs.existsSync(p)) {
return;
}
if (!content) {
content = '';
}
var type = 'directory';
if (Path.extname(p)) {
type = 'file';
}
switch (type) {
case 'directory':
fs.mkdirSync(p);
break;
case 'file':
fs.writeFileSync(p, content, 'utf8');
break;
}
}
// Generates a tree for the given path
// The structure should look like:
// {
// "/path/to/file.txt": "contents"
// "/path/to/dir": {
// "/path/to/dir/file.txt": "contents",
// "/path/to/dir/another_dir": {
// "/path/to/dir/another_dir/file.txt": "contents"
// }
// }
// }
function genPathTree (path) {
var p = Path.normalize(path);
if (!fs.existsSync(p)) {
return {};
}
var stat = fs.statSync(p)
, tree = {};
// If path is a directory then recursively add it's contents
if (stat.isDirectory()) {
var contents = fs.readdirSync(p)
, i = contents.length
, childPath;
while (--i >= 0) {
childPath = Path.join(p, contents[i]);
tree[p] = merge(tree[p], genPathTree(childPath));
}
}
// If path is a file read the content and add it
else if (stat.isFile()) {
tree[p] = fs.readFileSync(p, 'utf8');
}
return tree;
}
// Write the generated tree's files recursively replacing original source
// paths with the correct destination path
function writePathTree (tree, source, destination) {
var stat = {}
, key, value;
for (key in tree) {
value = tree[key];
stat = fs.statSync(key);
// Replace the original source for the destination
key = key.replace(source, destination);
if (stat.isDirectory()) {
// Do something
if (!fs.existsSync(key)) {
fs.mkdirSync(key);
}
writePathTree(value, source, destination);
}
else if (stat.isFile()) {
fs.writeFileSync(key, value, 'utf8');
}
}
}
// Recursively copy files and directories
function copy (source, destination) {
var from = Path.normalize(source)
, to = Path.normalize(destination)
, fromTree = {};
console.log('cp -r ' + from + ' ' + to);
if (from == to) {
return;
}
// If the source path doesn't exist we can't copy
if (!fs.existsSync(from)) {
throw new Error("ENOENT, no such file or directory '" + from + "'");
}
// Generate tree for the source path
fromTree = genPathTree(from, to);
writePathTree(fromTree, from, to);
}
// Create files and directories
writePath('test_file.txt', 'sdfsdfsdfsdfasdfkhasdfkjhasdfkjhk');
writePath('test_dir');
writePath('test_dir/base_file.txt', 'omgomgomgmg text');
writePath('test_dir/base_dir');
writePath('test_dir/base_sdfsdffile.txt', 'omgomgomgmg text');
writePath('test_dir/base_dsdfsdfsdfir');
writePath('test_dir/base_dsdfsdfsdfir/base_sdfsdffile.txt', 'omgomgomgmg text');
writePath('test_dir/base_dsdfsdfsdfir/omgomgomgomgomgomgomgomg');
writePath('test_dir/base_dsdfsdfsdfir/omgomgomgomgomgomgomgomg/hey_there.txt');
writePath('test_dir/base_dir/nested_file.txt', 'sdfsdfsdfsdfsdf');
writePath('test_dir/base_dir_second');
writePath('test_dir/base_dir_second/nested_file.txt', 'sdfsdfsdfsdfsdf');
writePath('test_dir/base_dir/nested_dir');
writePath('test_dir/base_dir/nested_dir/nested_file_again.txt', 'sdfsdfsdfsdfsdfsdfsdf');
copy('test_file.txt', 'test_file_copy.txt');
copy('test_dir', 'test_dir_copy');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment