Skip to content

Commit

Permalink
Properly handle directories as arguments (#713)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
nfischer committed May 9, 2017
1 parent 951ff22 commit a2e13b6
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 14 deletions.
2 changes: 2 additions & 0 deletions src/cat.js
Expand Up @@ -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');
Expand Down
13 changes: 10 additions & 3 deletions src/head.js
Expand Up @@ -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;
Expand Down
13 changes: 10 additions & 3 deletions src/sort.js
Expand Up @@ -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');
Expand Down
13 changes: 10 additions & 3 deletions src/tail.js
Expand Up @@ -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');
Expand Down
13 changes: 12 additions & 1 deletion src/uniq.js
Expand Up @@ -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().
Expand Down
7 changes: 7 additions & 0 deletions test/cat.js
Expand Up @@ -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
//
Expand Down
11 changes: 10 additions & 1 deletion test/head.js
Expand Up @@ -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");
});

//
Expand Down
10 changes: 9 additions & 1 deletion test/sort.js
Expand Up @@ -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
//
Expand Down
10 changes: 9 additions & 1 deletion test/tail.js
Expand Up @@ -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
//
Expand Down
25 changes: 24 additions & 1 deletion test/uniq.js
Expand Up @@ -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
//
Expand Down

0 comments on commit a2e13b6

Please sign in to comment.