Comparing version 1.5.9 to 1.6.0
@@ -131,2 +131,27 @@ var vowFs = require('vow-fs'); | ||
/** | ||
* Checks stdin for input | ||
* | ||
* @returns {Promise} | ||
*/ | ||
Checker.prototype.checkStdin = function() { | ||
var stdInput = []; | ||
var deferred = Vow.defer(); | ||
var _this = this; | ||
process.stdin.setEncoding('utf8'); | ||
process.stdin.on('data', function(chunk) { | ||
stdInput.push(chunk); | ||
}); | ||
process.stdin.on('end', function() { | ||
var errors = _this.checkString(stdInput.join('')); | ||
deferred.resolve(errors); | ||
}); | ||
return deferred.promise(); | ||
}; | ||
/** | ||
* Returns true if specified path is in excluded list. | ||
@@ -133,0 +158,0 @@ * |
@@ -19,3 +19,4 @@ /** | ||
var lastpath, file; | ||
var lastpath; | ||
var file; | ||
@@ -50,2 +51,3 @@ options = Object.create(options || {}); | ||
var configPath = path.resolve(directory, config); | ||
var ext; | ||
var content; | ||
@@ -56,3 +58,7 @@ | ||
if (fs.existsSync(configPath)) { | ||
if (config === '.jscsrc') { | ||
ext = path.extname(configPath); | ||
if (ext === '.js' || ext === '.json') { | ||
content = require(configPath); | ||
} else { | ||
content = JSON.parse( | ||
@@ -63,4 +69,2 @@ stripJSONComments( | ||
); | ||
} else { | ||
content = require(configPath); | ||
} | ||
@@ -67,0 +71,0 @@ |
@@ -19,3 +19,5 @@ /** | ||
module.exports = function(program) { | ||
var reporterPath, reporter, config; | ||
var reporterPath; | ||
var reporter; | ||
var config; | ||
var defer = Vow.defer(); | ||
@@ -67,3 +69,3 @@ var promise = defer.promise(); | ||
if (args.length === 0 && !program._stdin) { | ||
if (!args.length && process.stdin.isTTY) { | ||
console.error('No input files specified. Try option --help for usage information.'); | ||
@@ -110,11 +112,17 @@ defer.reject(1); | ||
if (typeof program._stdin !== 'undefined') { | ||
var errors = checker.checkString(program._stdin); | ||
reporter([errors]); | ||
// Handle usage like 'cat myfile.js | jscs' or 'jscs -'' | ||
var usedDash = args[args.length - 1] === '-'; | ||
if (!args.length || usedDash) { | ||
// So the dash doesn't register as a file | ||
if (usedDash) { args.length--; } | ||
if (!errors.isEmpty()) { | ||
defer.reject(2); | ||
} | ||
checker.checkStdin().then(function(errors) { | ||
reporter([errors]); | ||
defer.resolve(0); | ||
if (!errors.isEmpty()) { | ||
defer.reject(2); | ||
} | ||
defer.resolve(0); | ||
}); | ||
} | ||
@@ -121,0 +129,0 @@ |
@@ -30,2 +30,7 @@ var colors = require('colors'); | ||
} | ||
if (!this._file.isEnabledRule(this._currentRule, line)) { | ||
return; | ||
} | ||
this._errorList.push({ | ||
@@ -32,0 +37,0 @@ rule: this._currentRule, |
@@ -11,3 +11,3 @@ var treeIterator = require('./tree-iterator'); | ||
this._source = source; | ||
this._tree = tree; | ||
this._tree = tree || {tokens: []}; | ||
this._lines = source.split(/\r\n|\r|\n/); | ||
@@ -17,2 +17,5 @@ this._tokenIndex = null; | ||
var _this = this; | ||
this._buildTokenIndex(); | ||
this.iterate(function(node, parentNode, parentCollection) { | ||
@@ -41,2 +44,4 @@ if (node) { | ||
this._buildDisabledRuleIndex(); | ||
// Part of temporary esprima fix. | ||
@@ -56,2 +61,75 @@ function convertKeywordToIdentifierIfRequired(node) { | ||
/** | ||
* Builds an index of disabled rules by starting line for error suppression. | ||
*/ | ||
_buildDisabledRuleIndex: function() { | ||
this._disabledRuleIndex = []; | ||
var comments = this.getComments() || []; | ||
var commentRe = /(jscs\s*:\s*(en|dis)able)(.*)/; | ||
comments.forEach(function(comment) { | ||
var enabled; | ||
var parsed = commentRe.exec(comment.value.trim()); | ||
if (!parsed || parsed.index !== 0) { | ||
return; | ||
} | ||
enabled = parsed[2] === 'en'; | ||
this._addToDisabledRuleIndex(enabled, parsed[3], comment.loc.start.line); | ||
}, this); | ||
}, | ||
/** | ||
* returns whether a specific rule is disabled on the given line. | ||
* | ||
* @param {String} rule the rule name being tested | ||
* @param {Number} line the line number being tested | ||
* @returns {Boolean} true if the rule is enabled | ||
*/ | ||
isEnabledRule: function(rule, line) { | ||
var enabled = true; | ||
this._disabledRuleIndex.some(function(region) { | ||
// once the comment we're inspecting occurs after the location of the error, | ||
// no longer check for whether the state is enabled or disable | ||
if (region.line > line) { | ||
return true; | ||
} | ||
if (region.rule === rule || region.rule === '*') { | ||
enabled = region.enabled; | ||
} | ||
}, this); | ||
return enabled; | ||
}, | ||
/** | ||
* Adds rules to the disabled index given a string containing rules (or '' for all). | ||
* | ||
* @param {Boolean} enabled whether the rule is disabled or enabled on this line | ||
* @param {String} rulesStr the string containing specific rules to en/disable | ||
* @param {Number} line the line the comment appears on | ||
*/ | ||
_addToDisabledRuleIndex: function(enabled, rulesStr, line) { | ||
rulesStr = rulesStr || '*'; | ||
rulesStr.split(',').forEach(function(rule) { | ||
var ruleLength; | ||
rule = rule.trim(); | ||
if (!rule) { | ||
return; | ||
} | ||
this._disabledRuleIndex.push({ | ||
rule: rule, | ||
enabled: enabled, | ||
line: line | ||
}); | ||
}, this); | ||
}, | ||
/** | ||
* Builds token index by starting pos for futher navigation. | ||
@@ -64,2 +142,3 @@ */ | ||
tokenIndex[tokens[i].range[0]] = i; | ||
tokens[i]._tokenIndex = i; | ||
} | ||
@@ -74,8 +153,73 @@ this._tokenIndex = tokenIndex; | ||
getTokenPosByRangeStart: function(start) { | ||
if (!this._tokenIndex) { | ||
this._buildTokenIndex(); | ||
} | ||
return this._tokenIndex[start]; | ||
}, | ||
/** | ||
* Returns token using range start from the index. | ||
* | ||
* @returns {Object|undefined} | ||
*/ | ||
getTokenByRangeStart: function(start) { | ||
var tokenIndex = this._tokenIndex[start]; | ||
return tokenIndex === undefined ? undefined : this._tree.tokens[tokenIndex]; | ||
}, | ||
/** | ||
* Returns first token for the node from the AST. | ||
* | ||
* @param {Object} node | ||
* @returns {Object} | ||
*/ | ||
getFirstNodeToken: function(node) { | ||
return this.getTokenByRangeStart(node.range[0]); | ||
}, | ||
/** | ||
* Returns the first token before the given. | ||
* | ||
* @param {Object} token | ||
* @returns {Object|undefined} | ||
*/ | ||
getPrevToken: function(token) { | ||
var index = token._tokenIndex - 1; | ||
return index >= 0 ? this._tree.tokens[index] : undefined; | ||
}, | ||
/** | ||
* Returns the first token after the given. | ||
* | ||
* @param {Object} token | ||
* @returns {Object|undefined} | ||
*/ | ||
getNextToken: function(token) { | ||
var index = token._tokenIndex + 1; | ||
return index < this._tree.tokens.length ? this._tree.tokens[index] : undefined; | ||
}, | ||
/** | ||
* Returns the first token before the given which matches type (and value). | ||
* | ||
* @param {Object} token | ||
* @param {String} type | ||
* @param {String} [value] | ||
* @returns {Object|undefined} | ||
*/ | ||
findPrevToken: function(token, type, value) { | ||
var prevToken = this.getPrevToken(token); | ||
while (prevToken && prevToken.type !== type && (value === undefined ? true : prevToken.value !== value)) { | ||
prevToken = this.getPrevToken(prevToken); | ||
} | ||
return prevToken; | ||
}, | ||
/** | ||
* Returns the first token after the given which matches type (and value). | ||
* | ||
* @param {Object} token | ||
* @param {String} type | ||
* @param {String} [value] | ||
* @returns {Object|undefined} | ||
*/ | ||
findNextToken: function(token, type, value) { | ||
var nextToken = this.getNextToken(token); | ||
while (nextToken && nextToken.type !== type && (value === undefined ? true : nextToken.value !== value)) { | ||
nextToken = this.getNextToken(nextToken); | ||
} | ||
return nextToken; | ||
}, | ||
/** | ||
* Iterates through the token tree using tree iterator. | ||
@@ -141,2 +285,22 @@ * Calls passed function for every token. | ||
/** | ||
* Iterates token by value from the token array. | ||
* Calls passed function for every matched token. | ||
* | ||
* @param {String|String[]} name | ||
* @param {Function} cb | ||
*/ | ||
iterateTokenByValue: function(name, cb) { | ||
var names = (typeof name === 'string') ? [name] : name; | ||
var nameIndex = {}; | ||
names.forEach(function(type) { | ||
nameIndex[type] = true; | ||
}); | ||
this.getTokens().forEach(function(token, index, tokens) { | ||
if (nameIndex[token.value]) { | ||
cb(token, index, tokens); | ||
} | ||
}); | ||
}, | ||
/** | ||
* Returns string representing contents of the file. | ||
@@ -143,0 +307,0 @@ * |
@@ -47,5 +47,9 @@ var assert = require('assert'); | ||
var lines = this._allowComments ? commentHelper.getLinesWithCommentsRemoved(file) : file.getLines(); | ||
var line; | ||
var lines = this._allowComments ? | ||
commentHelper.getLinesWithCommentsRemoved(file) : file.getLines(); | ||
// This check should not be destructive | ||
lines = lines.slice(); | ||
if (this._allowRegex) { | ||
@@ -52,0 +56,0 @@ file.iterateTokensByType('RegularExpression', function(token) { |
@@ -63,4 +63,4 @@ var assert = require('assert'); | ||
function markChildren(node) { | ||
var childrenProperty = indentableNodes[node.type], | ||
children = node[childrenProperty]; | ||
var childrenProperty = indentableNodes[node.type]; | ||
var children = node[childrenProperty]; | ||
@@ -70,3 +70,5 @@ children.forEach(function(childNode, i) { | ||
if (childNode === null) { | ||
var leftLine, rightLine, j; | ||
var leftLine; | ||
var rightLine; | ||
var j; | ||
for (j = i - 1; j >= 0; j -= 1) { | ||
@@ -186,4 +188,4 @@ if (children[j]) { | ||
var test = node.test, | ||
endLine = test.loc.end.line - 1; | ||
var test = node.test; | ||
var endLine = test.loc.end.line - 1; | ||
@@ -190,0 +192,0 @@ if (isMultiline(test) && linesToCheck[endLine].pop !== null) { |
@@ -5,3 +5,3 @@ { | ||
"name": "jscs", | ||
"version": "1.5.9", | ||
"version": "1.6.0", | ||
"main": "lib/checker", | ||
@@ -33,17 +33,19 @@ "homepage": "https://github.com/mdevils/node-jscs", | ||
"glob": "~4.0.0", | ||
"minimatch": "~0.4.0", | ||
"strip-json-comments": "~0.1.1", | ||
"minimatch": "~1.0.0", | ||
"strip-json-comments": "~1.0.1", | ||
"vow": "~0.4.3", | ||
"vow-fs": "~0.3.1", | ||
"xmlbuilder": "~2.3.0", | ||
"supports-color": "~0.2.0" | ||
"xmlbuilder": "~2.4.0", | ||
"supports-color": "~1.1.0" | ||
}, | ||
"devDependencies": { | ||
"browserify": "~5.8.0", | ||
"browserify": "~5.10.0", | ||
"coveralls": "~2.11.1", | ||
"has-ansi": "~1.0.0", | ||
"hooker": "~0.2.3", | ||
"jshint": "~2.5.0", | ||
"mocha": "~1.20.1", | ||
"mocha": "~1.21.4", | ||
"separated-coverage": "~2.1.0", | ||
"sinon": "~1.10.0", | ||
"xml2js": "~0.4.2", | ||
"has-ansi": "~0.1.0" | ||
"xml2js": "~0.4.2" | ||
}, | ||
@@ -53,9 +55,30 @@ "bin": { | ||
}, | ||
"separated-coverage": { | ||
"common": [ | ||
"-a", | ||
"lib", | ||
"-a", | ||
"test", | ||
"-s", | ||
"lib/**/*.js", | ||
"-t", | ||
"test/**/*.js", | ||
"-S", | ||
"relative", | ||
"-O", | ||
"sources=lib", | ||
"-O", | ||
"tests=test" | ||
] | ||
}, | ||
"scripts": { | ||
"lint": "jshint . && node bin/jscs lib test bin publish", | ||
"test": "npm run lint && mocha", | ||
"coverage": "scov run -p common", | ||
"coverage-html": "scov run -p common -r html -o coverage.html", | ||
"browserify": "browserify --standalone JscsStringChecker lib/string-checker.js -o jscs-browser.js", | ||
"changelog": "git log `git describe --tags --abbrev=0`..HEAD --pretty=format:' * %s (%an)' | grep -v 'Merge pull request'", | ||
"release": "node publish/prepublish && npm publish", | ||
"postpublish": "node publish/postpublish" | ||
"postpublish": "node publish/postpublish", | ||
"travis": "npm run test && scov run -p common -r lcov -o out.lcov && cat out.lcov | coveralls" | ||
}, | ||
@@ -62,0 +85,0 @@ "files": [ |
@@ -24,4 +24,5 @@ { | ||
"disallowTrailingWhitespace": true, | ||
"disallowSpaceAfterPrefixUnaryOperators": true, | ||
"disallowMultipleVarDecl": true, | ||
"requireSpaceAfterKeywords": [ | ||
@@ -53,2 +54,5 @@ "if", | ||
}, | ||
"disallowSpacesInAnonymousFunctionExpression": { | ||
"beforeOpeningRoundBrace": true | ||
}, | ||
"disallowSpacesInsideObjectBrackets": "all", | ||
@@ -55,0 +59,0 @@ "disallowSpacesInsideArrayBrackets": "all", |
@@ -1,5 +0,8 @@ | ||
# node-jscs [![Build Status](https://travis-ci.org/mdevils/node-jscs.svg?branch=master)](https://travis-ci.org/mdevils/node-jscs) [![Dependency Status](https://david-dm.org/mdevils/node-jscs.svg?theme=shields.io)](https://david-dm.org/mdevils/node-jscs) [![devDependency Status](https://david-dm.org/mdevils/node-jscs/dev-status.svg?theme=shields.io)](https://david-dm.org/mdevils/node-jscs#info=devDependencies) | ||
# node-jscs | ||
[![Build Status](https://travis-ci.org/jscs-dev/node-jscs.svg?branch=master)](https://travis-ci.org/jscs-dev/node-jscs) [![Coverage Status](https://img.shields.io/coveralls/jscs-dev/node-jscs.svg)](https://coveralls.io/r/jscs-dev/node-jscs?branch=master) [![Dependency Status](https://david-dm.org/jscs-dev/node-jscs.svg?theme=shields.io)](https://david-dm.org/jscs-dev/node-jscs) [![devDependency Status](https://david-dm.org/jscs-dev/node-jscs/dev-status.svg?theme=shields.io)](https://david-dm.org/jscs-dev/node-jscs#info=devDependencies) | ||
JSCS — JavaScript Code Style. | ||
`jscs` is a code style checker. You can configure `jscs` for your project in detail using **over 60** validation rules, including presets from popular style guides like jQuery. | ||
@@ -22,2 +25,3 @@ | ||
* Syntastic VIM Plugin: [https://github.com/scrooloose/syntastic/.../syntax_checkers/javascript/jscs.vim/](https://github.com/scrooloose/syntastic/blob/master/syntax_checkers/javascript/jscs.vim/) | ||
* Atom plugin: https://atom.io/packages/linter-jscs | ||
* Web Essentials for Visual Studio 2013: https://github.com/madskristensen/WebEssentials2013/ | ||
@@ -79,3 +83,3 @@ | ||
### `--no-colors` | ||
*Will be removed*. Clean output without colors. | ||
Clean output without colors. | ||
@@ -163,2 +167,52 @@ ### `--help` | ||
## Error Suppression | ||
### Inline Comments | ||
You can disable and reenable rules inline with two special comments: `// jscs:disable` and `// jscs:enable`. Spacing in these comments is fairly lenient. All of the following are equivalent: | ||
```js | ||
/* jscs: enable */ | ||
// jscs: enable | ||
``` | ||
You can use them to disable rules in several ways. | ||
#### Disabling All Rules | ||
Simply using `// jscs:disable` or `// jscs:enable` will disable all rules. | ||
```js | ||
var a = b; | ||
// jscs:disable | ||
var c = d; // all errors on this line will be ignored | ||
// jscs:enable | ||
var e = f; // all errors on this line will be reported | ||
``` | ||
#### Disabling Specific Rules | ||
Including a comma separated list of rules to modify after `// jscs:disable` or `// jscs:enable` will modify only those rules. | ||
```js | ||
// jscs:disable requireCurlyBraces | ||
if (x) y(); // all errors from requireCurlyBraces on this line will be ignored | ||
// jscs:enable requireCurlyBraces | ||
if (z) a(); // all errors, including from requireCurlyBraces, on this line will be reported | ||
``` | ||
You can enable all rules after disabling a specific rule, and that rule becomes reenabled as well. | ||
```js | ||
// jscs:disable requireCurlyBraces | ||
if (x) y(); // all errors from requireCurlyBraces on this line will be ignored | ||
// jscs:enable | ||
if (z) a(); // all errors, even from requireCurlyBraces, will be reported | ||
``` | ||
You can disable multiple rules at once and progressively reeanble them. | ||
```js | ||
// jscs:disable requireCurlyBraces, requireDotNotation | ||
if (x['a']) y(); // all errors from requireCurlyBraces OR requireDotNotation on this line will be ignored | ||
// jscs:enable requireCurlyBraces | ||
if (z['a']) a(); // all errors from requireDotNotation, but not requireCurlyBraces, will be ignored | ||
// jscs:enable requireDotNotation | ||
if (z['a']) a(); // all errors will be reported | ||
``` | ||
## Rules | ||
@@ -165,0 +219,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
635212
110
15483
2884
9
16
+ Addedlodash-node@2.4.1(transitive)
+ Addedstrip-json-comments@1.0.4(transitive)
+ Addedsupports-color@1.1.0(transitive)
+ Addedxmlbuilder@2.4.6(transitive)
- Removedlodash._basebind@2.4.1(transitive)
- Removedlodash._basecreate@2.4.1(transitive)
- Removedlodash._basecreatecallback@2.4.1(transitive)
- Removedlodash._basecreatewrapper@2.4.1(transitive)
- Removedlodash._createwrapper@2.4.1(transitive)
- Removedlodash._isnative@2.4.1(transitive)
- Removedlodash._objecttypes@2.4.1(transitive)
- Removedlodash._setbinddata@2.4.1(transitive)
- Removedlodash._shimkeys@2.4.1(transitive)
- Removedlodash._slice@2.4.1(transitive)
- Removedlodash.assign@2.4.1(transitive)
- Removedlodash.bind@2.4.1(transitive)
- Removedlodash.create@2.4.1(transitive)
- Removedlodash.forown@2.4.1(transitive)
- Removedlodash.identity@2.4.1(transitive)
- Removedlodash.isarray@2.4.1(transitive)
- Removedlodash.isempty@2.4.1(transitive)
- Removedlodash.isfunction@2.4.1(transitive)
- Removedlodash.isobject@2.4.1(transitive)
- Removedlodash.keys@2.4.1(transitive)
- Removedlodash.noop@2.4.1(transitive)
- Removedlodash.support@2.4.1(transitive)
- Removedminimatch@0.4.0(transitive)
- Removedstrip-json-comments@0.1.3(transitive)
- Removedsupports-color@0.2.0(transitive)
- Removedxmlbuilder@2.3.0(transitive)
Updatedminimatch@~1.0.0
Updatedstrip-json-comments@~1.0.1
Updatedsupports-color@~1.1.0
Updatedxmlbuilder@~2.4.0