c9-core/node_modules/nak/lib/nak.js

215 wiersze
5.6 KiB
JavaScript

// used when nak is run from a script
exports.run = function(options) {
if (!options) {
options = process.argv;
options.splice(0, 2);
// from a script
if (options[0] === "--json") {
options = JSON.parse(options[1]);
}
// from the bin
else {
options = require("../lib/options").parseArgs(options);
options.path = options.args.pop();
if (options.args.length == 1)
options.query = options.args.pop();
else if (options.args.length == 2) {
options.replacement = options.args.pop();
options.query = options.args.pop();
}
}
}
main(options);
};
function main(options) {
var fs = require('fs'),
path = require('path'),
walkdir = require('../lib/walkdir').walkdir,
PathFilter = require('../lib/path-filter');
// arguments
var fpath = path.resolve(options.path),
replacement = options.replacement,
query = options.query,
textColor = "",
matches = 0,
filecount = 0;
if (process.platform == "win32")
fpath = options.path.replace(/\\/g, "/").replace(/\/$/, "");
if (options.startPaths) {
if (typeof options.startPaths == "string")
options.startPaths = [options.startPaths];
options.startPaths = options.startPaths.map(function(p) {
if (p[0] == "/" && fpath.slice(-1) == "/")
p = p.substring(1);
if (p.slice(-1) === "/")
p = p.slice(0, - 1);
var fullPath = path.normalize(fpath + p);
var base = fpath;
if (process.platform == "win32") {
fullPath = fullPath.replace(/\\/g, "/");
base = base.replace(/\\/g, "/");
}
if (fullPath.lastIndexOf(base, 0) === 0) {
return p;
}
}).filter(Boolean);
// filter out nested paths
var prev = "";
options.startPaths = options.startPaths.sort().filter(function(p) {
if (prev && p[prev.length] === "/" && p.substring(0, prev.length) === prev)
return false;
prev = p;
return true;
});
}
if (process.platform == "win32" && (fpath[0] == "/" || !fpath)) {
options.startPaths = options.startPaths.map(function(p) {
return p.replace(/^\//, "");
});
fpath = fpath.substr(1);
}
if (options.color) {
var colors = require('colors'),
queryString = String(options.query);
textColor = queryString.substring(1, queryString.length - 1);
}
setInclusions();
setExclusions(fpath, options.startPaths);
// console.log(options)
function log(text) {
process.stdout.write(text + "\n");
}
// set the query up, and present a final summary; also, pump out results as they come.
// "streaming" output like this is slower (because log blocks)
// but serves a purpose when finding text
if (typeof callback != "undefined") {
var Stream = require('stream').Stream;
var stream = new Stream();
stream.readable = true;
callback(null, {stream: stream});
if (query) {
makeQuery(query, replacement);
var output = "";
walkdir(fpath, options, function(file, lines, _matches) {
stream.emit("data", file + "\n" + lines);
matches += _matches;
filecount++;
}, function() {
if (!options.ackmate)
stream.emit("data", "Found " + matches + (matches == 1 ? " match" : " matches") + " in " + filecount + (filecount == 1 ? " file " : " files "));
stream.emit("end", {count : matches, filecount: filecount});
});
}
// if we're listing, callback at the very end
else if (options.list) {
walkdir(fpath, options, function(lines) {
stream.emit("data", lines);
stream.emit("end");
});
}
}
// if we're listing, callback at the very end
else if (options.list || !query) {
walkdir(fpath, options, function(lines) {
log(lines);
});
}
else if (query) {
makeQuery(query, replacement);
walkdir(fpath, options, function(file, lines, _matches) {
if (!options.color) {
log(file);
log(lines);
}
else {
log(file.cyan);
lines = lines.grey;
lines = lines.replace(options.query, textColor.yellowBG);
log(lines);
}
matches += _matches;
filecount++;
}, function() {
if (!options.ackmate)
log("Found " + matches + (matches == 1 ? " match" : " matches") + " in " + filecount + (filecount == 1 ? " file " : " files "));
});
}
function setInclusions() {
options.inclusions = [];
var paths = (options.pathInclude || '').split(',');
var i = paths.length;
while (i--)
options.inclusions.push(paths[i].trim());
}
function setExclusions(fpath, startPaths) {
var exclusions = [options.pathToNakignore];
(startPaths || []).concat([""]).forEach(function(p) {
exclusions.push(fpath + p + "/.nakignore");
if (options.addVCSIgnores)
exclusions.push(fpath + p + "/.gitignore");
});
var combinedExclusions = exclusions.map(function(p) {
// if these ignore files don't exist, don't worry about them
try {
return fs.readFileSync(p, "utf8");
} catch (e) { /* console.log(e) */ }
return "";
}).join("\n");
if (options.ignore)
combinedExclusions += "\n" + options.ignore.replace(/,/g, "\n");
if (combinedExclusions.length) {
options.exclusions = combinedExclusions.split(/\r?\n/);
}
}
function makeQuery(query, replacement) {
var flags = "gm";
if (options.literal)
query = PathFilter.escapeRegExp(query);
if (options.ignoreCase)
flags += "i";
if (options.wordRegexp)
query = "\\b(?:" + query + ")\\b";
options.query = new RegExp(query, flags);
options.queryClean = new RegExp(query, flags.substr(1));
if (typeof replacement == "string") {
options.replacement = replacement;
}
}
}
var simplefunc = require("simplefunc");
exports.serialize = function(fn) {
return simplefunc.toJson(fn);
};
exports.deserialize = function(fn) {
return simplefunc.fromJson(fn);
};