chore: update jshint and move it to an npm script (#454)

This commit is contained in:
Nate Fischer 2016-06-07 16:57:42 -07:00 committed by Ari Porad
parent 36cc243efd
commit 2e87f14c07
15 changed files with 88 additions and 87 deletions

2
.jshintignore Normal file
View File

@ -0,0 +1,2 @@
test/resources/
node_modules/

View File

@ -3,5 +3,10 @@
"sub": true,
"undef": true,
"unused": true,
"futurehostile": true,
"latedef": "nofunc",
"nocomma": true,
"nonbsp": true,
"notypeof": true,
"node": true
}
}

View File

@ -4,6 +4,7 @@ tmp/
.documentup.json
.gitignore
.jshintrc
.jshintignore
.lgtm
.travis.yml
.gitattributes

View File

@ -24,8 +24,10 @@
"homepage": "http://github.com/shelljs/shelljs",
"main": "./shell.js",
"scripts": {
"posttest": "npm run lint",
"test": "node scripts/run-tests",
"gendocs": "node scripts/generate-docs",
"lint": "jshint .",
"changelog": "bash scripts/changelog.sh"
},
"bin": {
@ -38,7 +40,7 @@
},
"devDependencies": {
"coffee-script": "^1.10.0",
"jshint": "~2.1.11"
"jshint": "^2.9.2"
},
"optionalDependencies": {},
"engines": {

View File

@ -1,35 +1,9 @@
#!/usr/bin/env node
/* globals cd, echo, exec, exit, ls, pwd, test */
/* globals cd, echo, exec, exit, ls */
require('../global');
var common = require('../src/common');
var failed = false;
//
// Lint
//
var JSHINT_BIN = 'node_modules/jshint/bin/jshint';
cd(__dirname + '/..');
if (!test('-f', JSHINT_BIN)) {
echo('JSHint not found. Run `npm install` in the root dir first.');
exit(1);
}
var jsfiles = common.expand([pwd() + '/*.js',
pwd() + '/scripts/*.js',
pwd() + '/src/*.js',
pwd() + '/test/*.js'
]).join(' ');
// Perform linting on all javascript files
if (exec(JSON.stringify(process.execPath)+' '+pwd()+'/'+JSHINT_BIN+' '+jsfiles).code !== 0) {
failed = true;
echo('*** JSHINT FAILED! (return code != 0)');
} else {
echo('All JSHint tests passed');
}
echo();
//
// Unit tests
//

View File

@ -87,7 +87,7 @@ exports.error = error;
//@
//@ Turns a regular string into a string-like object similar to what each
//@ command returns. This has special methods, like `.to()` and `.toEnd()`
var ShellString = function (stdout, stderr, code) {
function ShellString(stdout, stderr, code) {
var that;
if (stdout instanceof Array) {
that = stdout;
@ -106,7 +106,7 @@ var ShellString = function (stdout, stderr, code) {
that[cmd] = function() {return shell[cmd].apply(that.stdout, arguments);};
});
return that;
};
}
exports.ShellString = ShellString;

View File

@ -26,33 +26,35 @@ assert.throws(function () {
// Valids
//
var result;
// single file, array syntax
var result = common.expand(['resources/file1.txt']);
result = common.expand(['resources/file1.txt']);
assert.equal(shell.error(), null);
assert.deepEqual(result, ['resources/file1.txt']);
// multiple file, glob syntax, * for file name
var result = common.expand(['resources/file*.txt']);
result = common.expand(['resources/file*.txt']);
assert.equal(shell.error(), null);
assert.deepEqual(result.sort(), ['resources/file1.txt', 'resources/file2.txt'].sort());
// multiple file, glob syntax, * for directory name
var result = common.expand(['*/file*.txt']);
result = common.expand(['*/file*.txt']);
assert.equal(shell.error(), null);
assert.deepEqual(result.sort(), ['resources/file1.txt', 'resources/file2.txt'].sort());
// multiple file, glob syntax, ** for directory name
var result = common.expand(['**/file*.js']);
result = common.expand(['**/file*.js']);
assert.equal(shell.error(), null);
assert.deepEqual(result.sort(), ["resources/file1.js","resources/file2.js","resources/ls/file1.js","resources/ls/file2.js"].sort());
// broken links still expand
var result = common.expand(['resources/b*dlink']);
result = common.expand(['resources/b*dlink']);
assert.equal(shell.error(), null);
assert.deepEqual(result, ['resources/badlink']);
// common.parseOptions (normal case)
var result = common.parseOptions('-Rf', {
result = common.parseOptions('-Rf', {
'R': 'recursive',
'f': 'force',
'r': 'reverse'
@ -62,7 +64,7 @@ assert.ok(result.force === true);
assert.ok(result.reverse === false);
// common.parseOptions (with mutually-negating options)
var result = common.parseOptions('-f', {
result = common.parseOptions('-f', {
'n': 'no_force',
'f': '!no_force',
'R': 'recursive'
@ -72,7 +74,7 @@ assert.ok(result.no_force === false);
assert.ok(result.force === undefined); // this key shouldn't exist
// common.parseOptions (the last of the conflicting options should hold)
var result = common.parseOptions('-fn', {
result = common.parseOptions('-fn', {
'n': 'no_force',
'f': '!no_force',
'R': 'recursive'
@ -82,7 +84,7 @@ assert.ok(result.no_force === true);
assert.ok(result.force === undefined); // this key shouldn't exist
// common.parseOptions using an object to hold options
var result = common.parseOptions({'-v': 'some text here'}, {
result = common.parseOptions({'-v': 'some text here'}, {
'v': 'value',
'f': 'force',
'r': 'reverse'

View File

@ -12,7 +12,9 @@ shell.mkdir('tmp');
// Invalids
//
var result = shell.grep();
var result;
result = shell.grep();
assert.ok(shell.error());
assert.equal(result.code, 2);
@ -39,60 +41,60 @@ assert.equal(result.code, 2);
// Valids
//
var result = shell.grep('line', 'resources/a.txt');
result = shell.grep('line', 'resources/a.txt');
assert.equal(shell.error(), null);
assert.equal(result.split('\n').length - 1, 4);
var result = shell.grep('-v', 'line', 'resources/a.txt');
result = shell.grep('-v', 'line', 'resources/a.txt');
assert.equal(shell.error(), null);
assert.equal(result.split('\n').length - 1, 8);
var result = shell.grep('line one', 'resources/a.txt');
result = shell.grep('line one', 'resources/a.txt');
assert.equal(shell.error(), null);
assert.equal(result, 'This is line one\n');
// multiple files
var result = shell.grep(/test/, 'resources/file1.txt', 'resources/file2.txt');
result = shell.grep(/test/, 'resources/file1.txt', 'resources/file2.txt');
assert.equal(shell.error(), null);
assert.equal(result, 'test1\ntest2\n');
// multiple files, array syntax
var result = shell.grep(/test/, ['resources/file1.txt', 'resources/file2.txt']);
result = shell.grep(/test/, ['resources/file1.txt', 'resources/file2.txt']);
assert.equal(shell.error(), null);
assert.equal(result, 'test1\ntest2\n');
// multiple files, glob syntax, * for file name
var result = shell.grep(/test/, 'resources/file*.txt');
result = shell.grep(/test/, 'resources/file*.txt');
assert.equal(shell.error(), null);
assert.ok(result == 'test1\ntest2\n' || result == 'test2\ntest1\n');
// multiple files, glob syntax, * for directory name
var result = shell.grep(/test/, '*/file*.txt');
result = shell.grep(/test/, '*/file*.txt');
assert.equal(shell.error(), null);
assert.ok(result == 'test1\ntest2\n' || result == 'test2\ntest1\n');
// multiple files, glob syntax, ** for directory name
var result = shell.grep(/test/, '**/file*.js');
result = shell.grep(/test/, '**/file*.js');
assert.equal(shell.error(), null);
assert.equal(result, 'test\ntest\ntest\ntest\n');
// one file, * in regex
var result = shell.grep(/alpha*beta/, 'resources/grep/file');
result = shell.grep(/alpha*beta/, 'resources/grep/file');
assert.equal(shell.error(), null);
assert.equal(result, 'alphaaaaaaabeta\nalphbeta\n');
// one file, * in string-regex
var result = shell.grep('alpha*beta', 'resources/grep/file');
result = shell.grep('alpha*beta', 'resources/grep/file');
assert.equal(shell.error(), null);
assert.equal(result, 'alphaaaaaaabeta\nalphbeta\n');
// one file, * in regex, make sure * is not globbed
var result = shell.grep(/l*\.js/, 'resources/grep/file');
result = shell.grep(/l*\.js/, 'resources/grep/file');
assert.equal(shell.error(), null);
assert.equal(result, 'this line ends in.js\nlllllllllllllllll.js\n');
// one file, * in string-regex, make sure * is not globbed
var result = shell.grep('l*\\.js', 'resources/grep/file');
result = shell.grep('l*\\.js', 'resources/grep/file');
assert.equal(shell.error(), null);
assert.equal(result, 'this line ends in.js\nlllllllllllllllll.js\n');

View File

@ -19,7 +19,7 @@ assert.ok(!_pwd.stderr);
assert.equal(_pwd, path.resolve('.'));
shell.cd('tmp');
var _pwd = shell.pwd();
_pwd = shell.pwd();
assert.equal(_pwd.code, 0);
assert.ok(!_pwd.stderr);
assert.equal(shell.error(), null);

View File

@ -13,7 +13,10 @@ shell.mkdir('tmp');
// Invalids
//
var result = shell.rm();
var contents;
var result;
result = shell.rm();
assert.ok(shell.error());
assert.equal(result.code, 1);
assert.equal(result.stderr, 'rm: no paths given');
@ -123,7 +126,7 @@ assert.equal(fs.existsSync('tmp/.hidden'), true);
result = shell.rm('-rf', 'tmp/*');
assert.equal(shell.error(), null);
assert.equal(result.code, 0);
var contents = fs.readdirSync('tmp');
contents = fs.readdirSync('tmp');
assert.equal(contents.length, 1);
assert.equal(contents[0], '.hidden'); // shouldn't remove hiddden if no .* given
@ -139,7 +142,7 @@ assert.equal(fs.existsSync('tmp/.hidden'), true);
result = shell.rm('-rf', 'tmp/*', 'tmp/.*');
assert.equal(shell.error(), null);
assert.equal(result.code, 0);
var contents = fs.readdirSync('tmp');
contents = fs.readdirSync('tmp');
assert.equal(contents.length, 0);
// recursive dir removal - array-syntax
@ -154,7 +157,7 @@ assert.equal(fs.existsSync('tmp/.hidden'), true);
result = shell.rm('-rf', ['tmp/*', 'tmp/.*']);
assert.equal(shell.error(), null);
assert.equal(result.code, 0);
var contents = fs.readdirSync('tmp');
contents = fs.readdirSync('tmp');
assert.equal(contents.length, 0);
// removal of a read-only file (unforced)

View File

@ -8,6 +8,8 @@ shell.config.silent = true;
shell.rm('-rf', 'tmp');
shell.mkdir('tmp');
var result;
//
// Invalids
//
@ -35,7 +37,7 @@ assert.equal(result.stderr, 'sed: no such file or directory: asdfasdf');
shell.cp('-f', 'resources/file1', 'tmp/file1');
assert.equal(fs.existsSync('asdfasdf'), false); // sanity check
assert.equal(fs.existsSync('tmp/file1'), true); // sanity check
var result = shell.sed(/asdf/g, 'nada', 'tmp/file1', 'asdfasdf');
result = shell.sed(/asdf/g, 'nada', 'tmp/file1', 'asdfasdf');
assert.ok(shell.error());
assert.equal(result.code, 2);
assert.equal(result.stderr, 'sed: no such file or directory: asdfasdf');
@ -45,17 +47,17 @@ assert.equal(result.stderr, 'sed: no such file or directory: asdfasdf');
//
shell.cp('-f', 'resources/file1', 'tmp/file1');
var result = shell.sed('test1', 'hello', 'tmp/file1'); // search string
result = shell.sed('test1', 'hello', 'tmp/file1'); // search string
assert.equal(shell.error(), null);
assert.equal(result.code, 0);
assert.equal(result.toString(), 'hello');
var result = shell.sed(/test1/, 'hello', 'tmp/file1'); // search regex
result = shell.sed(/test1/, 'hello', 'tmp/file1'); // search regex
assert.equal(shell.error(), null);
assert.equal(result.code, 0);
assert.equal(result.toString(), 'hello');
var result = shell.sed(/test1/, 1234, 'tmp/file1'); // numeric replacement
result = shell.sed(/test1/, 1234, 'tmp/file1'); // numeric replacement
assert.equal(shell.error(), null);
assert.equal(result.code, 0);
assert.equal(result.toString(), '1234');
@ -63,37 +65,37 @@ assert.equal(result.toString(), '1234');
var replaceFun = function (match) {
return match.toUpperCase() + match;
};
var result = shell.sed(/test1/, replaceFun, 'tmp/file1'); // replacement function
result = shell.sed(/test1/, replaceFun, 'tmp/file1'); // replacement function
assert.equal(shell.error(), null);
assert.equal(result.code, 0);
assert.equal(result.toString(), 'TEST1test1');
var result = shell.sed('-i', /test1/, 'hello', 'tmp/file1');
result = shell.sed('-i', /test1/, 'hello', 'tmp/file1');
assert.equal(shell.error(), null);
assert.equal(result.code, 0);
assert.equal(result.toString(), 'hello');
assert.equal(shell.cat('tmp/file1').toString(), 'hello');
// make sure * in regex is not globbed
var result = shell.sed(/alpha*beta/, 'hello', 'resources/grep/file');
result = shell.sed(/alpha*beta/, 'hello', 'resources/grep/file');
assert.equal(shell.error(), null);
assert.equal(result.code, 0);
assert.equal(result.toString(), 'hello\nhowareyou\nhello\nthis line ends in.js\nlllllllllllllllll.js\n');
// make sure * in string-regex is not globbed
var result = shell.sed('alpha*beta', 'hello', 'resources/grep/file');
result = shell.sed('alpha*beta', 'hello', 'resources/grep/file');
assert.ok(!shell.error());
assert.equal(result.code, 0);
assert.equal(result.toString(), 'hello\nhowareyou\nhello\nthis line ends in.js\nlllllllllllllllll.js\n');
// make sure * in regex is not globbed
var result = shell.sed(/l*\.js/, '', 'resources/grep/file');
result = shell.sed(/l*\.js/, '', 'resources/grep/file');
assert.ok(!shell.error());
assert.equal(result.code, 0);
assert.equal(result.toString(), 'alphaaaaaaabeta\nhowareyou\nalphbeta\nthis line ends in\n\n');
// make sure * in string-regex is not globbed
var result = shell.sed('l*\\.js', '', 'resources/grep/file');
result = shell.sed('l*\\.js', '', 'resources/grep/file');
assert.ok(!shell.error());
assert.equal(result.code, 0);
assert.equal(result.toString(), 'alphaaaaaaabeta\nhowareyou\nalphbeta\nthis line ends in\n\n');
@ -102,19 +104,19 @@ shell.cp('-f', 'resources/file1', 'tmp/file1');
shell.cp('-f', 'resources/file2', 'tmp/file2');
// multiple file names
var result = shell.sed('test', 'hello', 'tmp/file1', 'tmp/file2');
result = shell.sed('test', 'hello', 'tmp/file1', 'tmp/file2');
assert.equal(shell.error(), null);
assert.equal(result.code, 0);
assert.equal(result.toString(), 'hello1\nhello2');
// array of file names (and try it out with a simple regex)
var result = shell.sed(/t.*st/, 'hello', ['tmp/file1', 'tmp/file2']);
result = shell.sed(/t.*st/, 'hello', ['tmp/file1', 'tmp/file2']);
assert.equal(shell.error(), null);
assert.equal(result.code, 0);
assert.equal(result.toString(), 'hello1\nhello2');
// multiple file names, with in-place-replacement
var result = shell.sed('-i', 'test', 'hello', ['tmp/file1', 'tmp/file2']);
result = shell.sed('-i', 'test', 'hello', ['tmp/file1', 'tmp/file2']);
assert.equal(shell.error(), null);
assert.equal(result.code, 0);
assert.equal(result.toString(), 'hello1\nhello2');
@ -125,7 +127,7 @@ assert.equal(shell.cat('tmp/file2').toString(), 'hello2');
shell.cp('resources/file*.txt', 'tmp/');
assert.equal(shell.cat('tmp/file1.txt').toString(), 'test1\n');
assert.equal(shell.cat('tmp/file2.txt').toString(), 'test2\n');
var result = shell.sed('-i', 'test', 'hello', 'tmp/file*.txt');
result = shell.sed('-i', 'test', 'hello', 'tmp/file*.txt');
assert.equal(shell.error(), null);
assert.equal(result.code, 0);
assert.equal(result.toString(), 'hello1\n\nhello2\n'); // TODO: fix sed's behavior

View File

@ -11,6 +11,8 @@ shell.rm('-rf', 'tmp');
// Valids
//
var result;
// initial values
assert.strictEqual(oldConfigSilent, false);
assert.strictEqual(shell.config.verbose, false);
@ -20,13 +22,13 @@ assert.strictEqual(shell.config.noglob, false);
shell.cp('-R', 'resources/', 'tmp');
// default behavior
var result = shell.exec(JSON.stringify(process.execPath)+' -e \"require(\'../global\'); ls(\'file_doesnt_exist\'); echo(1234);\"');
result = shell.exec(JSON.stringify(process.execPath)+' -e \"require(\'../global\'); ls(\'file_doesnt_exist\'); echo(1234);\"');
assert.equal(result.code, 0);
assert.equal(result.stdout, '1234\n');
assert.equal(result.stderr, 'ls: no such file or directory: file_doesnt_exist\n');
// set -e
var result = shell.exec(JSON.stringify(process.execPath)+' -e \"require(\'../global\'); set(\'-e\'); ls(\'file_doesnt_exist\'); echo(1234);\"');
result = shell.exec(JSON.stringify(process.execPath)+' -e \"require(\'../global\'); set(\'-e\'); ls(\'file_doesnt_exist\'); echo(1234);\"');
var nodeVersion = process.versions.node.split('.').map(function(str) { return parseInt(str, 10); });
var uncaughtErrorExitCode = (nodeVersion[0] === 0 && nodeVersion[1] < 11) ? 8 : 1;
assert.equal(result.code, uncaughtErrorExitCode);
@ -34,13 +36,13 @@ assert.equal(result.stdout, '');
assert(result.stderr.indexOf('Error: ls: no such file or directory: file_doesnt_exist') >= 0);
// set -v
var result = shell.exec(JSON.stringify(process.execPath)+' -e \"require(\'../global\'); set(\'-v\'); ls(\'file_doesnt_exist\'); echo(1234);\"');
result = shell.exec(JSON.stringify(process.execPath)+' -e \"require(\'../global\'); set(\'-v\'); ls(\'file_doesnt_exist\'); echo(1234);\"');
assert.equal(result.code, 0);
assert.equal(result.stdout, '1234\n');
assert.equal(result.stderr, 'ls file_doesnt_exist\nls: no such file or directory: file_doesnt_exist\necho 1234\n');
// set -ev
var result = shell.exec(JSON.stringify(process.execPath)+' -e \"require(\'../global\'); set(\'-ev\'); ls(\'file_doesnt_exist\'); echo(1234);\"');
result = shell.exec(JSON.stringify(process.execPath)+' -e \"require(\'../global\'); set(\'-ev\'); ls(\'file_doesnt_exist\'); echo(1234);\"');
assert.equal(result.code, uncaughtErrorExitCode);
assert.equal(result.stdout, '');
assert(result.stderr.indexOf('Error: ls: no such file or directory: file_doesnt_exist') >= 0);
@ -48,7 +50,7 @@ assert(result.stderr.indexOf('ls file_doesnt_exist\n') >= 0);
assert.equal(result.stderr.indexOf('echo 1234\n'), -1);
// set -e, set +e
var result = shell.exec(JSON.stringify(process.execPath)+' -e \"require(\'../global\'); set(\'-e\'); set(\'+e\'); ls(\'file_doesnt_exist\'); echo(1234);\"');
result = shell.exec(JSON.stringify(process.execPath)+' -e \"require(\'../global\'); set(\'-e\'); set(\'+e\'); ls(\'file_doesnt_exist\'); echo(1234);\"');
assert.equal(result.code, 0);
assert.equal(result.stdout, '1234\n');
assert.equal(result.stderr, 'ls: no such file or directory: file_doesnt_exist\n');

View File

@ -27,8 +27,10 @@ assert.ok(shell.error());
// Valids
//
var result;
shell.ShellString('hello world').to('tmp/to1').to('tmp/to2');
var result = shell.cat('tmp/to1');
result = shell.cat('tmp/to1');
assert.equal(shell.error(), null);
assert.equal(result, 'hello world');
result = shell.cat('tmp/to2');
@ -37,7 +39,7 @@ assert.equal(result, 'hello world');
// With a glob
shell.ShellString('goodbye').to('tmp/t*1');
var result = shell.cat('tmp/to1');
result = shell.cat('tmp/to1');
assert.equal(shell.error(), null);
assert.equal(result, 'goodbye');

View File

@ -25,12 +25,13 @@ assert.ok(shell.error());
// Valids
//
var result;
assert.equal(fs.existsSync('tmp/toEnd1'), false); //Check file toEnd() creates does not already exist
assert.equal(fs.existsSync('tmp/toEnd2'), false);
shell.ShellString('hello ').toEnd('tmp/toEnd1');
assert.equal(fs.existsSync('tmp/toEnd1'), true); //Check that file was created
shell.ShellString('world').toEnd('tmp/toEnd1').toEnd('tmp/toEnd2'); //Write some more to the file
var result = shell.cat('tmp/toEnd1');
result = shell.cat('tmp/toEnd1');
assert.equal(shell.error(), null);
assert.equal(result, 'hello world'); //Check that the result is what we expect
result = shell.cat('tmp/toEnd2');
@ -40,7 +41,7 @@ assert.equal(result, 'world'); //Check that the result is what we expect
// With a glob
shell.ShellString('good').to('tmp/toE*1');
shell.ShellString('bye').toEnd('tmp/toE*1');
var result = shell.cat('tmp/toEnd1');
result = shell.cat('tmp/toEnd1');
assert.equal(shell.error(), null);
assert.equal(result, 'goodbye');

View File

@ -7,6 +7,9 @@ shell.config.silent = true;
shell.rm('-rf', 'tmp');
shell.mkdir('tmp');
var oldStat;
var testFile;
// should handle args
var result = shell.touch();
assert.ok(shell.error());
@ -69,8 +72,8 @@ assert.equal(fs.statSync(testFile).mtime.getTime(), fs.statSync(testFile2).mtime
assert.equal(fs.statSync(testFile).atime.getTime(), fs.statSync(testFile2).atime.getTime());
// sets mtime
var testFile = tmpFile();
var oldStat = resetUtimes(testFile);
testFile = tmpFile();
oldStat = resetUtimes(testFile);
result = shell.touch(testFile);
assert.equal(result.code, 0);
assert(oldStat.mtime < fs.statSync(testFile).mtime);
@ -78,15 +81,15 @@ assert(oldStat.mtime < fs.statSync(testFile).mtime);
assert(oldStat.atime < fs.statSync(testFile).atime);
// does not sets mtime if told not to
var testFile = tmpFile();
var oldStat = resetUtimes(testFile);
testFile = tmpFile();
oldStat = resetUtimes(testFile);
result = shell.touch('-a', testFile);
assert.equal(result.code, 0);
assert.equal(oldStat.mtime.getTime(), fs.statSync(testFile).mtime.getTime());
// does not sets atime if told not to
var testFile = tmpFile();
var oldStat = resetUtimes(testFile);
testFile = tmpFile();
oldStat = resetUtimes(testFile);
result = shell.touch('-m', testFile);
assert.equal(result.code, 0);
assert.equal(oldStat.atime.getTime(), fs.statSync(testFile).atime.getTime());