aboutsummaryrefslogtreecommitdiff
path: root/node_modules/shelljs/src/sort.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/shelljs/src/sort.js')
-rw-r--r--node_modules/shelljs/src/sort.js91
1 files changed, 91 insertions, 0 deletions
diff --git a/node_modules/shelljs/src/sort.js b/node_modules/shelljs/src/sort.js
new file mode 100644
index 000000000..041b03772
--- /dev/null
+++ b/node_modules/shelljs/src/sort.js
@@ -0,0 +1,91 @@
+var common = require('./common');
+var fs = require('fs');
+
+common.register('sort', _sort, {
+ canReceivePipe: true,
+ cmdOptions: {
+ 'r': 'reverse',
+ 'n': 'numerical',
+ },
+});
+
+// parse out the number prefix of a line
+function parseNumber(str) {
+ var match = str.match(/^\s*(\d*)\s*(.*)$/);
+ return { num: Number(match[1]), value: match[2] };
+}
+
+// compare two strings case-insensitively, but examine case for strings that are
+// case-insensitive equivalent
+function unixCmp(a, b) {
+ var aLower = a.toLowerCase();
+ var bLower = b.toLowerCase();
+ return (aLower === bLower ?
+ -1 * a.localeCompare(b) : // unix sort treats case opposite how javascript does
+ aLower.localeCompare(bLower));
+}
+
+// compare two strings in the fashion that unix sort's -n option works
+function numericalCmp(a, b) {
+ var objA = parseNumber(a);
+ var objB = parseNumber(b);
+ if (objA.hasOwnProperty('num') && objB.hasOwnProperty('num')) {
+ return ((objA.num !== objB.num) ?
+ (objA.num - objB.num) :
+ unixCmp(objA.value, objB.value));
+ } else {
+ return unixCmp(objA.value, objB.value);
+ }
+}
+
+//@
+//@ ### sort([options,] file [, file ...])
+//@ ### sort([options,] file_array)
+//@ Available options:
+//@
+//@ + `-r`: Reverse the result of comparisons
+//@ + `-n`: Compare according to numerical value
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ sort('foo.txt', 'bar.txt');
+//@ sort('-r', 'foo.txt');
+//@ ```
+//@
+//@ Return the contents of the files, sorted line-by-line. Sorting multiple
+//@ files mixes their content, just like unix sort does.
+function _sort(options, files) {
+ // Check if this is coming from a pipe
+ var pipe = common.readFromPipe();
+
+ if (!files && !pipe) common.error('no files given');
+
+ files = [].slice.call(arguments, 1);
+
+ if (pipe) {
+ files.unshift('-');
+ }
+
+ var lines = [];
+ files.forEach(function (file) {
+ if (!fs.existsSync(file) && file !== '-') {
+ // exit upon any sort of error
+ common.error('no such file or directory: ' + file);
+ }
+
+ var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8');
+ lines = lines.concat(contents.trimRight().split(/\r*\n/));
+ });
+
+ var sorted;
+ sorted = lines.sort(options.numerical ? numericalCmp : unixCmp);
+
+ if (options.reverse) {
+ sorted = sorted.reverse();
+ }
+
+ return sorted.join('\n') + '\n';
+}
+
+module.exports = _sort;