UNPKG

grasp

Version:

JavaScript structural search, replace, and refactor

480 lines (479 loc) 16 kB
// Generated by LiveScript 1.5.0 (function(){ var path, squery, equery, async, minimatch, flowParser, ref$, min, sortWith, lines, chars, split, join, map, Obj, format, formatResult, formatName, formatCount, replace, parseOptions, generateHelp, generateHelpForOption, help, _console, version, run, getQueryEngine, slice$ = [].slice, toString$ = {}.toString; path = require('path'); squery = require('grasp-squery'); equery = require('grasp-equery'); async = require('async'); minimatch = require('minimatch'); flowParser = require('flow-parser'); ref$ = require('prelude-ls'), min = ref$.min, sortWith = ref$.sortWith, lines = ref$.lines, chars = ref$.chars, split = ref$.split, join = ref$.join, map = ref$.map, Obj = ref$.Obj; format = require('./format'), formatResult = format.formatResult, formatName = format.formatName, formatCount = format.formatCount; replace = require('./replace').replace; ref$ = require('./options'), parseOptions = ref$.parse, generateHelp = ref$.generateHelp, generateHelpForOption = ref$.generateHelpForOption; help = require('./help'); _console = console; version = require('../package.json').version; run = function(arg$){ var ref$, args, error, ref1$, callback, exit, data, stdin, fs, textFormat, input, console, options, positional, debug, e, versionString, getHelp, helpString, queryEngine, parser, parserOptions, that, selector, targets, targetsLen, replacement, isDir, color, bold, textFormatFuncs, resultsData, resultsFormat, callCallback, out, parsedSelector, resultsSortFunc, search, processResults, getToMap, end, exts, testExt, exclude, testExclude, targetPaths, searchTarget, cwd, this$ = this; ref$ = arg$ != null ? arg$ : {}, args = ref$.args, error = (ref1$ = ref$.error) != null ? ref1$ : function(it){ throw new Error(it); }, callback = (ref1$ = ref$.callback) != null ? ref1$ : function(){}, exit = (ref1$ = ref$.exit) != null ? ref1$ : function(){}, data = (ref1$ = ref$.data) != null ? ref1$ : false, stdin = ref$.stdin, fs = (ref1$ = ref$.fs) != null ? ref1$ : require('fs'), textFormat = (ref1$ = ref$.textFormat) != null ? ref1$ : require('cli-color'), input = ref$.input, console = (ref1$ = ref$.console) != null ? ref1$ : _console; if (args == null) { error('Error: Must specify arguments.'); exit(2); return; } try { options = parseOptions(args), positional = options._, debug = options.debug; } catch (e$) { e = e$; error(e.message); exit(2); return; } if (debug) { console.time('everything'); console.log('options:'); console.log(options); } if (options.version) { versionString = "grasp v" + version; callback(versionString); exit(0, versionString); return; } getHelp = function(positional){ positional == null && (positional = []); return help(generateHelp, generateHelpForOption, positional, { version: version }); }; if (options.help) { helpString = getHelp(positional); callback(helpString); exit(0, helpString); return; } queryEngine = options.engine != null ? require(options.engine) : options.squery ? squery : options.equery ? equery : squery; ref$ = (function(){ switch (options.parser[0]) { case 'flow-parser': return [flowParser, options.parser[1]]; default: return [require(options.parser[0]), options.parser[1]]; } }()), parser = ref$[0], parserOptions = ref$[1]; options.context == null && (options.context = (ref$ = options.NUM) != null ? ref$ : 0); options.beforeContext == null && (options.beforeContext = options.context); options.afterContext == null && (options.afterContext = options.context); if ((that = options.file) != null) { try { selector = fs.readFileSync(that, 'utf8'); } catch (e$) { e = e$; error("Error: No such file '" + options.file + "'."); exit(2); return; } targets = positional; } else { selector = positional[0]; targets = slice$.call(positional, 1); } if (!targets.length) { targets = options.recursive ? ['.'] : ['-']; } targetsLen = targets.length; if ((that = options.replace) != null) { replacement = that; } if (that = options.replaceFunc) { replacement = that; } else if (that = options.replaceFile) { try { replacement = fs.readFileSync(that, 'utf8').replace(/([\s\S]*)\n$/, '$1'); } catch (e$) { e = e$; error("Error: No such file '" + options.replaceFile + "'."); exit(2); return; } } if (selector == null) { error('Error: No selector specified.'); helpString = getHelp(); callback(helpString); exit(2, helpString); return; } if ((that = options.filename) != null) { options.displayFilename = that; } else if (targetsLen > 1) { options.displayFilename = true; } else { try { isDir = targets[0] === '-' ? false : fs.lstatSync(targets[0]).isDirectory(); if (isDir && !options.recursive) { console.warn("'" + targets[0] + "' is a directory. Use '-r, --recursive' to recursively search directories."); } options.displayFilename = isDir; } catch (e$) { e = e$; error("Error: No such file or directory '" + targets[0] + "'."); exit(2); return; } } color = Obj.map(function(it){ if (options.color) { return it; } else { return function(it){ return it + ""; }; } }, { green: textFormat.green, cyan: textFormat.cyan, magenta: textFormat.magenta, red: textFormat.red }); bold = options.bold ? textFormat.bold : function(it){ return it + ""; }; textFormatFuncs = { color: color, bold: bold }; resultsData = []; resultsFormat = 'default'; callCallback = !options.quiet && !options.json && !options.to && !options.inPlace; out = function(it){ resultsData.push(it); if (callCallback) { callback(it); } }; if (debug) { console.time('parse-selector'); } parsedSelector = queryEngine.parse(selector); if (debug) { console.timeEnd('parse-selector'); console.log('parsed-selector:'); console.log(JSON.stringify(parsedSelector, null, 2)); } resultsSortFunc = function(a, b){ var aStart, bStart, lineDiff; aStart = a.loc.start; bStart = b.loc.start; lineDiff = aStart.line - bStart.line; if (lineDiff === 0) { return aStart.column - bStart.column; } else { return lineDiff; } }; search = function(name, input){ var cleanInput, parsedInput, e, results, resultsLen, count, that, sortedResults, slicedResults, replaced, inputLines, inputLinesLength, i$, len$, result; if (debug) { console.time("search-total:" + name); } cleanInput = input.replace(/^#!.*\n/, ''); try { if (debug) { console.time("parse-input:" + name); } parsedInput = parser.parse(cleanInput, parserOptions); if (debug) { console.timeEnd("parse-input:" + name); } if (options.printAst) { console.log(JSON.stringify(parsedInput, null, 2)); } } catch (e$) { e = e$; throw new Error("Error: Could not parse JavaScript from '" + name + "'. " + e.message); } if (debug) { console.time("query:" + name); } results = queryEngine.queryParsed(parsedSelector, parsedInput); if (debug) { console.timeEnd("query:" + name); } resultsLen = results.length; count = (that = options.maxCount) != null ? min(that, resultsLen) : resultsLen; sortedResults = sortWith(resultsSortFunc, results); slicedResults = slice$.call(sortedResults, 0, count); if (replacement != null) { try { replaced = replace(replacement, cleanInput, slicedResults, queryEngine); if (options.to || options.inPlace) { resultsFormat = 'pairs'; out([name, replaced]); } else { out(replaced); } } catch (e$) { e = e$; console.error(name + ": Error during replacement. " + e.message + "."); } } else if (options.count) { if (options.displayFilename) { if (options.json || data) { resultsFormat = 'pairs'; out([name, count]); } else { out(formatCount(color, count, name)); } } else { out(options.json || data ? count : formatCount(color, count)); } } else if (options.filesWithoutMatch || options.filesWithMatches) { if (options.filesWithMatches && count || options.filesWithoutMatch && !count) { out(options.json || data ? name : formatName(color, name)); } } else { if (options.json || data) { if (options.displayFilename) { resultsFormat = 'pairs'; out([name, slicedResults]); } else { resultsFormat = 'lists'; out(slicedResults); } } else { inputLines = lines(cleanInput); inputLinesLength = cleanInput.length; for (i$ = 0, len$ = slicedResults.length; i$ < len$; ++i$) { result = slicedResults[i$]; out(formatResult(name, inputLines, inputLinesLength, textFormatFuncs, options, result)); } } } if (debug) { console.timeEnd("search-total:" + name); } }; processResults = function(){ if (resultsData.length) { if (resultsFormat === 'pairs') { return Obj.pairsToObj(resultsData); } else if (resultsFormat === 'lists') { if (targetsLen === 1) { return resultsData[0]; } else { return resultsData; } } else { return resultsData; } } else { return []; } }; getToMap = function(inputPaths){ var mapping, i$, len$, inputPath; if (options.inPlace) { return Obj.listsToObj(inputPaths, inputPaths); } else if (toString$.call(options.to).slice(8, -1) === 'Object') { return options.to; } else { mapping = {}; for (i$ = 0, len$ = inputPaths.length; i$ < len$; ++i$) { inputPath = inputPaths[i$]; mapping[inputPath] = options.to.replace(/%/, path.basename(inputPath, path.extname(inputPath))); } return mapping; } }; end = function(inputPaths){ var exitCode, processedResults, toMap, inputPath, contents, targetPath, jsonString; exitCode = resultsData.length ? 0 : 1; processedResults = processResults(); if (replacement && options.to || options.inPlace) { toMap = getToMap(inputPaths); for (inputPath in processedResults) { contents = processedResults[inputPath]; targetPath = toMap[inputPath]; if (targetPath === '-') { callback(contents); } else { if (targetPath) { fs.writeFileSync(targetPath, contents); } } } } else if (options.json) { jsonString = JSON.stringify(processedResults); callback(jsonString); } if (debug) { console.timeEnd('everything'); } return exit(exitCode, options.json ? jsonString : processedResults); }; exts = options.extensions; testExt = exts.length === 0 || exts.length === 1 && exts[0] === '.' ? function(){ return true; } : function(it){ return it.match(RegExp('\\.(?:' + exts.join('|') + ')$')); }; exclude = options.exclude; testExclude = !exclude || exclude.length === 0 ? function(){ return true; } : function(file, basePath, upPath){ var filePath; filePath = path.relative(basePath, path.join(upPath, file)); return exclude.every(function(excludePattern){ return !minimatch(filePath, excludePattern, options.minimatchOptions); }); }; targetPaths = []; searchTarget = function(basePath, upPath){ return function(target, done){ var output, targetPath, stat, fileContents, displayPath, e, this$ = this; try { if (target === '-') { if (!stdin) { throw new Error('Error: stdin not defined.'); } targetPaths.push('-'); output = ''; stdin.setEncoding('utf-8'); stdin.on('data', (function(it){ return output += it; })); stdin.on('end', function(){ var e; try { search('(standard input)', output); } catch (e$) { e = e$; console.error(e.message); } return done(); }); stdin.resume(); } else { targetPath = path.resolve(upPath, target); stat = fs.lstatSync(targetPath); if (stat.isDirectory() && options.recursive) { async.eachSeries(fs.readdirSync(targetPath), searchTarget(basePath, targetPath), function(){ return async.setImmediate(function(){ return done(); }); }); } else if (stat.isFile() && testExt(target) && testExclude(target, basePath, upPath)) { fileContents = fs.readFileSync(targetPath, 'utf8'); displayPath = path.relative(basePath, targetPath); targetPaths.push(displayPath); search(displayPath, fileContents); done(); } else { done(); } } } catch (e$) { e = e$; console.error(e.message); done(); } }; }; if (input) { search('(input)', input); return end(['-']); } else { cwd = process.cwd(); async.eachSeries(targets, searchTarget(cwd, cwd), function(){ return end(targetPaths); }); } }; getQueryEngine = function(it){ return { squery: 'grasp-squery', equery: 'grasp-equery' }[it] || it; }; run.VERSION = version; run.search = curry$(function(engine, selector, input){ return run({ args: { _: [selector], engine: getQueryEngine(engine) }, input: input, data: true, exit: function(arg$, results){ return results; } }); }); run.replace = curry$(function(engine, selector, replacement, input){ var args; args = { _: [selector], engine: getQueryEngine(engine) }; if (toString$.call(replacement).slice(8, -1) === 'Function') { args.replaceFunc = replacement; } else { args.replace = replacement; } return run({ args: args, input: input, exit: function(arg$, results){ return results[0]; } }); }); module.exports = run; function curry$(f, bound){ var context, _curry = function(args) { return f.length > 1 ? function(){ var params = args ? args.concat() : []; context = bound ? context || this : this; return params.push.apply(params, arguments) < f.length && arguments.length ? _curry.call(context, params) : f.apply(context, params); } : f; }; return _curry(); } }).call(this);