Skip to content

Commit

Permalink
Merge 8a7c43e into 0ae1dd6
Browse files Browse the repository at this point in the history
  • Loading branch information
c-pranshu committed Sep 17, 2021
2 parents 0ae1dd6 + 8a7c43e commit e7fe833
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 15 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,15 +365,15 @@ The main difference from `ls('-R', path)` is that the resulting file names
include the base directories (e.g., `lib/resources/file1` instead of just `file1`).


### grep([options,] regex_filter, file [, file ...])
### grep([options,] regex_filter, file_array)
### grep([options,] regex_filter, file [ ...file, ...directory])
### grep([options,] regex_filter, file_array,directory_array)

Available options:

+ `-v`: Invert `regex_filter` (only print non-matching lines).
+ `-l`: Print only filenames of matching files.
+ `-i`: Ignore case.

+ `-r`: recursive search
Examples:

```javascript
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
},
"dependencies": {
"execa": "^1.0.0",
"fs-readdir-recursive": "^1.1.0",
"glob": "^7.0.0",
"interpret": "^1.0.0",
"rechoir": "^0.6.2"
Expand Down
44 changes: 32 additions & 12 deletions src/grep.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
var common = require('./common');
var fs = require('fs');
var path = require('path');
var read = require('fs-readdir-recursive');


common.register('grep', _grep, {
globStart: 2, // don't glob-expand the regex
Expand All @@ -8,19 +11,20 @@ common.register('grep', _grep, {
'v': 'inverse',
'l': 'nameOnly',
'i': 'ignoreCase',
'r': 'recursive',
},
});

//@
//@ ### grep([options,] regex_filter, file [, file ...])
//@ ### grep([options,] regex_filter, file_array)
//@ ### grep([options,] regex_filter, file [ ...file, ...directory])
//@ ### grep([options,] regex_filter, file_array,directory_array)
//@
//@ Available options:
//@
//@ + `-v`: Invert `regex_filter` (only print non-matching lines).
//@ + `-l`: Print only filenames of matching files.
//@ + `-i`: Ignore case.
//@
//@ + `-r`: recursive search
//@ Examples:
//@
//@ ```javascript
Expand All @@ -31,29 +35,45 @@ common.register('grep', _grep, {
//@ Reads input string from given files and returns a
//@ [ShellString](#shellstringstr) containing all lines of the @ file that match
//@ the given `regex_filter`.
function _grep(options, regex, files) {
// Check if this is coming from a pipe
var pipe = common.readFromPipe();

if (!files && !pipe) common.error('no paths given', 2);
function getFilesInDir(directory) {
var files = read(directory);
for (var i = 0; i < files.length; i++) {
files[i] = path.join(directory, path.dirname(files[i]), path.basename(files[i]));
}
return files;
}

function _grep(options, regex, files) {
var pipe = common.readFromPipe();
if (!files && !pipe) common.error('No paths given', 2);
files = [].slice.call(arguments, 2);

if (pipe) {
files.unshift('-');
}

var grep = [];
var contents = '';
if (options.ignoreCase) {
regex = new RegExp(regex, 'i');
}
files.forEach(function (file) {

for (var i = 0; i < files.length; i++) {
var file = files[i];
if (!fs.existsSync(file) && file !== '-') {
common.error('no such file or directory: ' + file, 2, { continue: true });
common.error('no such file or directory: ' + file, 2, { silent: true });
} else if (!fs.existsSync(file) && file === '-') {
contents = pipe;
} else if (options.recursive && fs.statSync(file).isDirectory()) {
files = files.concat(getFilesInDir(file));
} else if (!options.recursive && fs.statSync(file).isDirectory()) {
common.error(file + ' Is a directory', 2, { silent: true });
return;
} else if (fs.statSync(file).isFile()) {
contents = fs.readFileSync(file, 'utf8');
}

var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8');
if (options.nameOnly) {
if (contents.match(regex)) {
grep.push(file);
Expand All @@ -67,12 +87,12 @@ function _grep(options, regex, files) {
}
});
}
});

}
if (grep.length === 0 && common.state.errorCode !== 2) {
// We didn't hit the error above, but pattern didn't match
common.error('', { silent: true });
}
return grep.join('\n') + '\n';
}

module.exports = _grep;
42 changes: 42 additions & 0 deletions test/grep.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,24 @@ test("multiple files, one doesn't exist, one doesn't match", t => {
t.is(result.code, 2);
});

test('-r option not provided, but directory is present', t => {
t.truthy(fs.existsSync('test/resources'));
t.truthy('/test/resources/a.txt');
const result = shell.grep(/oogabooga/, 'test/resources', 'test/resources/a.txt');
t.truthy(shell.error());
t.is(result.stderr, 'grep: test/resources Is a directory');
t.is(result.code, 2);
});

test('atleast one directory or file does not exist', t => {
t.truthy(fs.existsSync('test/resources'));
t.falsy(fs.existsSync('test/resources/random.txt'));
const result = shell.grep('-r', /oogabooga/, 'test/resources', 'test/resources/random.txt');
t.truthy(shell.error());
t.is(result.code, 2);
t.is(result.stderr, 'grep: no such file or directory: test/resources/random.txt');
});

//
// Valids
//
Expand Down Expand Up @@ -162,6 +180,30 @@ test('-i option', t => {
t.is(result.split('\n').length - 1, 3);
});

test('one directory provided with -r option', t => {
const result = shell.grep('-r', 'test', 'test/resources');
t.falsy(shell.error());
t.is(result.split('\n').length, 29);
});

test('multiple directories or files provided', t => {
const result = shell.grep('-r', 'test', 'test/resources', 'test/resources/a.txt', 'test/resources/file2.txt', 'test/utils/');
t.falsy(shell.error());
t.is(result.split('\n').length, 39);
});

test('directory provided in glob form', t => {
const result = shell.grep('-r', 'test', 'test/r*');
t.falsy(shell.error());
t.is(result.split('\n').length, 66);
});

test('works with array syntax', t => {
const result = shell.grep('-r', 'test', ['test/r*', 'package.json'], 'scripts');
t.falsy(shell.error());
t.is(result.split('\n').length, 72);
});

test('the pattern looks like an option', t => {
const result = shell.grep('--', '-v', 'test/resources/grep/file2');
t.falsy(shell.error());
Expand Down

0 comments on commit e7fe833

Please sign in to comment.