Properly handle directories as arguments (#713)

* fix(cat): do not cat directories

Fixes #707

* fix(head): do not let head() read directories

Also fixes a typo

* fix(sort): do not sort directories

Also fixes a typo

* fix(tail): do not let tail() read directories

Also fixes a typo

* fix(uniq): do not let uniq() read directories

We also had a test which called sort() instead of uniq(), so we never
actually tested the missing-file case. This fixes that as well.

This also throws an error for using a directory as output.

* fix(pipe): fix breakages with piped commands
This commit is contained in:
Nate Fischer 2017-05-08 22:57:58 -07:00 committed by GitHub
parent 951ff22671
commit a2e13b62dc
10 changed files with 103 additions and 14 deletions

View File

@ -30,6 +30,8 @@ function _cat(options, files) {
files.forEach(function (file) {
if (!fs.existsSync(file)) {
common.error('no such file or directory: ' + file);
} else if (fs.statSync(file).isDirectory()) {
common.error(file + ': Is a directory');
}
cat += fs.readFileSync(file, 'utf8');

View File

@ -72,9 +72,16 @@ function _head(options, files) {
var shouldAppendNewline = false;
files.forEach(function (file) {
if (!fs.existsSync(file) && file !== '-') {
common.error('no such file or directory: ' + file, { continue: true });
return;
if (file !== '-') {
if (!fs.existsSync(file)) {
common.error('no such file or directory: ' + file, { continue: true });
return;
} else if (fs.statSync(file).isDirectory()) {
common.error("error reading '" + file + "': Is a directory", {
continue: true,
});
return;
}
}
var contents;

View File

@ -69,9 +69,16 @@ function _sort(options, files) {
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);
if (file !== '-') {
if (!fs.existsSync(file)) {
common.error('no such file or directory: ' + file, { continue: true });
return;
} else if (fs.statSync(file).isDirectory()) {
common.error('read failed: ' + file + ': Is a directory', {
continue: true,
});
return;
}
}
var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8');

View File

@ -46,9 +46,16 @@ function _tail(options, files) {
var shouldAppendNewline = false;
files.forEach(function (file) {
if (!fs.existsSync(file) && file !== '-') {
common.error('no such file or directory: ' + file, { continue: true });
return;
if (file !== '-') {
if (!fs.existsSync(file)) {
common.error('no such file or directory: ' + file, { continue: true });
return;
} else if (fs.statSync(file).isDirectory()) {
common.error("error reading '" + file + "': Is a directory", {
continue: true,
});
return;
}
}
var contents = file === '-' ? pipe : fs.readFileSync(file, 'utf8');

View File

@ -40,7 +40,18 @@ function _uniq(options, input, output) {
// Check if this is coming from a pipe
var pipe = common.readFromPipe();
if (!input && !pipe) common.error('no input given');
if (!pipe) {
if (!input) common.error('no input given');
if (!fs.existsSync(input)) {
common.error(input + ': No such file or directory');
} else if (fs.statSync(input).isDirectory()) {
common.error("error reading '" + input + "'");
}
}
if (output && fs.existsSync(output) && fs.statSync(output).isDirectory()) {
common.error(output + ': Is a directory');
}
var lines = (input ? fs.readFileSync(input, 'utf8') : pipe).
trimRight().

View File

@ -25,6 +25,13 @@ test('nonexistent file', t => {
t.is(result.stderr, 'cat: no such file or directory: /asdfasdf');
});
test('directory', t => {
const result = shell.cat('resources/cat');
t.truthy(shell.error());
t.is(result.code, 1);
t.is(result.stderr, 'cat: resources/cat: Is a directory');
});
//
// Valids
//

View File

@ -18,9 +18,18 @@ test('no args', t => {
test('file does not exist', t => {
t.falsy(fs.existsSync('/asdfasdf')); // sanity check
const result = shell.head('/adsfasdf'); // file does not exist
const result = shell.head('/asdfasdf'); // file does not exist
t.truthy(shell.error());
t.is(result.code, 1);
t.is(result.stderr, 'head: no such file or directory: /asdfasdf');
});
test('directory', t => {
t.truthy(fs.statSync('resources/').isDirectory()); // sanity check
const result = shell.head('resources/');
t.truthy(shell.error());
t.is(result.code, 1);
t.is(result.stderr, "head: error reading 'resources/': Is a directory");
});
//

View File

@ -25,11 +25,19 @@ test('no args', t => {
test('file does not exist', t => {
t.falsy(fs.existsSync('/asdfasdf')); // sanity check
const result = shell.sort('/adsfasdf');
const result = shell.sort('/asdfasdf');
t.truthy(shell.error());
t.truthy(result.code);
});
test('directory', t => {
t.truthy(fs.statSync('resources/').isDirectory()); // sanity check
const result = shell.sort('resources/');
t.truthy(shell.error());
t.is(result.code, 1);
t.is(result.stderr, 'sort: read failed: resources/: Is a directory');
});
//
// Valids
//

View File

@ -18,11 +18,19 @@ test('no args', t => {
test('file does not exist', t => {
t.falsy(fs.existsSync('/asdfasdf')); // sanity check
const result = shell.tail('/adsfasdf');
const result = shell.tail('/asdfasdf');
t.truthy(shell.error());
t.is(result.code, 1);
});
test('directory', t => {
t.truthy(fs.statSync('resources/').isDirectory()); // sanity check
const result = shell.tail('resources/');
t.truthy(shell.error());
t.is(result.code, 1);
t.is(result.stderr, "tail: error reading 'resources/': Is a directory");
});
//
// Valids
//

View File

@ -18,11 +18,34 @@ test('no args', t => {
test('file does not exist', t => {
t.falsy(fs.existsSync('/asdfasdf')); // sanity check
const result = shell.sort('/adsfasdf');
const result = shell.uniq('/asdfasdf');
t.truthy(shell.error());
t.truthy(result.code);
});
test('directory', t => {
t.truthy(fs.statSync('resources/').isDirectory()); // sanity check
const result = shell.uniq('resources/');
t.truthy(shell.error());
t.is(result.code, 1);
t.is(result.stderr, "uniq: error reading 'resources/'");
});
test('output directory', t => {
t.truthy(fs.statSync('resources/').isDirectory()); // sanity check
const result = shell.uniq('resources/file1.txt', 'resources/');
t.truthy(shell.error());
t.is(result.code, 1);
t.is(result.stderr, 'uniq: resources/: Is a directory');
});
test('file does not exist with output directory', t => {
t.falsy(fs.existsSync('/asdfasdf')); // sanity check
const result = shell.uniq('/asdfasdf', 'resources/');
t.is(result.code, 1);
t.truthy(shell.error());
});
//
// Valids
//