Comparing version 0.3.4 to 0.4.0
@@ -81,8 +81,8 @@ /*jslint stupid: true*/ | ||
} else { | ||
homeConfigs.push(path.join(home, '.jslint.conf')); | ||
homeConfigs.push(path.join(home, '.jslintrc')); | ||
homeConfigs.push(path.join(home, '.jslint.conf')); | ||
} | ||
projectConfigs = | ||
['jslintrc', '.jslintrc', 'jslint.conf', '.jslint.conf'].map(function (file) { | ||
['jslint.conf', '.jslint.conf', 'jslintrc', '.jslintrc'].map(function (file) { | ||
return path.join(process.cwd(), file); | ||
@@ -131,3 +131,2 @@ }); | ||
options = options || {}; | ||
delete options.argv; | ||
@@ -159,25 +158,31 @@ options = addDefaults(options, config); | ||
exports.getOptions = function linter_getConfig(homedir, options) { | ||
'use strict'; | ||
var config = loadConfig(homedir, options.config); | ||
return preprocessOptions(options, config); | ||
}; | ||
exports.lint = function (script, options) { | ||
'use strict'; | ||
var config = loadConfig(process.env.HOME, options.config), | ||
ok, | ||
result; | ||
options = preprocessOptions(options, config); | ||
this.options = this.options || this.getOptions(process.env.HOME, options); | ||
JSLINT = JSLINT || loadJSLint(options); | ||
return this.doLint(JSLINT, script, options); | ||
}; | ||
exports.doLint = function (JSLINT, script, options) { | ||
'use strict'; | ||
var ok, | ||
result; | ||
script = preprocessScript(script); | ||
ok = JSLINT(script, options); | ||
result = { | ||
ok: true, | ||
errors: [] | ||
}; | ||
if (!ok) { | ||
result = JSLINT.data(); | ||
result.ok = ok; | ||
} | ||
result = JSLINT.data(); | ||
result.ok = ok; | ||
result.options = options; | ||
@@ -184,0 +189,0 @@ |
var linter = require("./linter"); | ||
var reporter = require("./reporter"); | ||
var nopt = require("nopt"); | ||
var fs = require("fs"); | ||
var LintStream = require('./lintstream.js'), | ||
ReportStream = require('./reportstream.js'), | ||
JSONReportStream = require('./jsonreportstream.js'), | ||
FileOpener = require('./fileopener.js'); | ||
var glob; | ||
@@ -132,77 +137,52 @@ var con = console; | ||
function consoleReport(file, lint) { | ||
function makeReporter(parsed) { | ||
'use strict'; | ||
con.log(JSON.stringify([file, lint.errors])); | ||
} | ||
var reporter; | ||
function makeLintFile(parsed, maybeExit, reporter) { | ||
'use strict'; | ||
return function lintFile(file) { | ||
fs.readFile(file, 'utf8', function (err, data) { | ||
if (err) { | ||
con.log(err); | ||
return; | ||
} | ||
var lint = linter.lint(data, parsed); | ||
reporter(file, lint, parsed.color, parsed.terse); | ||
maybeExit(lint); | ||
}); | ||
}; | ||
} | ||
function makeReporter(parsed) { | ||
'use strict'; | ||
if (parsed.json) { | ||
return consoleReport; | ||
reporter = new JSONReportStream(parsed); | ||
} else { | ||
reporter = new ReportStream(parsed); | ||
} | ||
return reporter.report.bind(reporter); | ||
reporter.on('data', function (chunk) { | ||
if (chunk === '.') { | ||
process.stderr.write(chunk); | ||
} else { | ||
con.log(chunk); | ||
} | ||
}); | ||
return reporter; | ||
} | ||
exports.runMain = function (parsed) { | ||
exports.runMain = function (options) { | ||
'use strict'; | ||
var maybeExit, | ||
lintFile, | ||
remain = []; | ||
if (parsed.version) { | ||
exports.reportVersion(con.log, parsed); | ||
if (options.version) { | ||
exports.reportVersion(con.log, options); | ||
return; | ||
} | ||
if (!parsed.argv.remain.length) { | ||
if (!options.argv.remain.length) { | ||
die("No files specified."); | ||
} | ||
var procOptions = linter.getOptions(process.env.HOME, options), | ||
remain = globFiles(options.argv.remain, glob), | ||
fo = new FileOpener(), | ||
ls = new LintStream(procOptions), | ||
rep = makeReporter(procOptions); | ||
remain = globFiles(parsed.argv.remain, glob); | ||
fo.pipe(ls); | ||
ls.pipe(rep); | ||
// If there are no more files to be processed, exit with the value 1 | ||
// if any of the files contains any lint. | ||
maybeExit = (function () { | ||
var filesLeft = remain.length, | ||
ok = true; | ||
rep.on('finish', function () { | ||
pro.exit(rep.allOK ? 0 : 1); | ||
}); | ||
function exitWithCode() { | ||
var code = ok ? 0 : 1; | ||
pro.exit(code); | ||
} | ||
return function (lint) { | ||
filesLeft -= 1; | ||
ok = lint.ok && ok; | ||
if (filesLeft === 0) { | ||
exitWithCode(); | ||
} | ||
}; | ||
}()); | ||
lintFile = makeLintFile(parsed, maybeExit, makeReporter(parsed)); | ||
remain.forEach(lintFile); | ||
remain.forEach(function (file) { | ||
fo.write(file); | ||
}); | ||
fo.end(); | ||
}; |
/*jslint | ||
nomen: true, stupid: true | ||
*/ | ||
var con = console; | ||
var con = console, | ||
vm = require("vm"), | ||
fs = require("fs"), | ||
LintStream = require('./lintstream.js'); | ||
exports.LintStream = LintStream; | ||
exports.setConsole = function (c) { | ||
@@ -14,5 +19,3 @@ 'use strict'; | ||
var vm = require("vm"), | ||
fs = require("fs"), | ||
ctx = vm.createContext(), | ||
var ctx = vm.createContext(), | ||
f; | ||
@@ -19,0 +22,0 @@ |
(function () { | ||
'use strict'; | ||
function generator(o, f) { | ||
return function (s) { | ||
o[f](s); | ||
}; | ||
} | ||
exports.generator = generator; | ||
var color = require("./color"); | ||
var color = require("./color"), | ||
logger = { | ||
log: generator(console, 'log'), | ||
err: generator(process.stderr, 'write') | ||
}; | ||
exports.logger = { | ||
log: (console.log).bind(console), | ||
err: (process.stderr.write).bind(process.stderr) | ||
}; | ||
exports.setLogger = function (l) { | ||
logger = l; | ||
this.logger = l; | ||
}; | ||
exports.makeReporter = function (logger, colorize, terse) { | ||
return { | ||
logger: logger, | ||
colorize: colorize, | ||
terse: terse, | ||
report: function (file, lint) { | ||
return exports.report.call(this, file, lint, this.colorize, this.terse); | ||
} | ||
}; | ||
}; | ||
exports.report = function (file, lint, colorize, terse) { | ||
var line, i, len, pad, e, fileMessage; | ||
var line, pad, fileMessage, | ||
logger = this.logger; | ||
@@ -28,13 +34,8 @@ fileMessage = "\n" + (colorize ? color.bold(file) : file); | ||
if (terse) { | ||
len = lint.errors.length; | ||
for (i = 0; i < len; i += 1) { | ||
e = lint.errors[i]; | ||
if (e) { | ||
logger.log(file + ':' + e.line + ':' + e.character + ': ' + e.reason); | ||
} | ||
} | ||
lint.errors.forEach(function (e) { | ||
logger.log(file + ':' + e.line + ':' + e.character + ': ' + e.reason); | ||
}); | ||
} else { | ||
logger.log(fileMessage); | ||
len = lint.errors.length; | ||
for (i = 0; i < len; i += 1) { | ||
lint.errors.forEach(function (e, i) { | ||
pad = "#" + String(i + 1); | ||
@@ -44,11 +45,8 @@ while (pad.length < 3) { | ||
} | ||
e = lint.errors[i]; | ||
if (e) { | ||
line = ' // Line ' + e.line + ', Pos ' + e.character; | ||
line = ' // Line ' + e.line + ', Pos ' + e.character; | ||
logger.log(pad + ' ' + (colorize ? color.yellow(e.reason) : e.reason)); | ||
logger.log(' ' + (e.evidence || '').replace(/^\s+|\s+$/, "") + | ||
(colorize ? color.grey(line) : line)); | ||
} | ||
} | ||
logger.log(pad + ' ' + (colorize ? color.yellow(e.reason) : e.reason)); | ||
logger.log(' ' + (e.evidence || '').replace(/^\s+|\s+$/, "") + | ||
(colorize ? color.grey(line) : line)); | ||
}); | ||
} | ||
@@ -55,0 +53,0 @@ } else { |
@@ -8,3 +8,3 @@ { | ||
], | ||
"version": "0.3.4", | ||
"version": "0.4.0", | ||
"author": "Reid Burke <me@reidburke.com>", | ||
@@ -30,3 +30,4 @@ "contributors": [ | ||
"dependencies": { | ||
"nopt": "~1.0.0" | ||
"nopt": "~1.0.0", | ||
"readable-stream": "~1.0.0" | ||
}, | ||
@@ -43,3 +44,3 @@ "devDependencies": { | ||
"engines": { | ||
"node": ">=0.4.12" | ||
"node": ">=0.4.0" | ||
}, | ||
@@ -46,0 +47,0 @@ "files": [ |
@@ -9,9 +9,13 @@ ## node-jslint | ||
Added latest jslint, 2014-02-06. | ||
Added latest jslint, 2014-04-21. | ||
Version 0.3.1 of node-jslint supports globbing with * and ** expressions. | ||
Version 0.4.0 of node-jslint exposes a stream interface to jslint. | ||
Versions 0.2+ of node-jslint provide multiple editions of jslint to | ||
Version 0.3.4 of node-jslint supports globbing with * and ** expressions. | ||
Versions 0.2+ of node-jslint provide multiple editions of jslint to | ||
address backwards and forwards compatibility. | ||
## Use the command-line client | ||
### Use the default jslint | ||
@@ -25,3 +29,3 @@ | ||
### Use a specific edition | ||
### Use a specific edition | ||
@@ -32,10 +36,69 @@ For example, edition 2013-02-03 which shipped with node-jslint 0.1.9: | ||
## Install | ||
## Use node-jslint programmatically | ||
npm install jslint -g | ||
### Streams interface | ||
## Self-Lint | ||
As of node-jslint 0.4.0, a streams interface is exposed. You can use it in client code like this: | ||
make lint | ||
Install as a dependency: | ||
$ npm install --save jslint | ||
Pull it into your code with require: | ||
var LintStream = require('jslint').LintStream; | ||
Create and configure the stream linter: | ||
var options = { | ||
"edition": latest, | ||
"length": 100 | ||
}, | ||
l = new LintStream(options); | ||
Send files to the linter: | ||
var fileName, fileContents; | ||
l.write({file: fileName, body: fileContents}); | ||
Receive lint from the linter: | ||
l.on('data', function (chunk, encoding, callback) { | ||
// chunk is an object | ||
// chunk.file is whatever you supplied to write (see above) | ||
assert.deepEqual(chunk.file, fileName); | ||
// chunk.linted is an object holding the result from running JSLint | ||
// chunk.linted.ok is the boolean return code from JSLINT() | ||
// chunk.linted.errors is the array of errors, etc. | ||
// see JSLINT for the complete contents of the object | ||
callback(); | ||
}); | ||
You can only pass options to the LintStream when creating it. The `edition` option can be | ||
used to select different editions of JSLint. | ||
The LintStream is in object mode (objectMode: true). It expects an | ||
object with two properties: `file` and `body`. The `file` property | ||
can be used to pass metadata along with the file. The `body` property | ||
contains the file to be linted; it can be either a string or a Buffer. | ||
The LintStream emits `'data'` events containing an object with two properties. | ||
The `file` property is copied from the `file` property that is passed in. The | ||
`linted` property contains the results of running JSLINT. | ||
### Simple interface | ||
The simple interface provides an edition-aware loader. This can be used as a frontend to | ||
node-jslint's collection of editions of the JSLINT code. | ||
var node_jslint = require('jslint'), | ||
JSLINT = node_jslint.load(edition); | ||
This exposes the same loading interface used in node-jslint, so it supports the special | ||
edition names `default` and `latest` as well as date-based edition names such as `2013-08-26` | ||
## Usage examples | ||
@@ -65,3 +128,3 @@ | ||
Start with the included jslintrc.example file and customize your options | ||
Start with the included jslintrc.example file and customize your options | ||
per project or copy it to $HOME/.jslintrc to apply your setting globally | ||
@@ -68,0 +131,0 @@ |
1789446
27
47832
133
3
7
+ Addedreadable-stream@~1.0.0
+ Addedcore-util-is@1.0.3(transitive)
+ Addedisarray@0.0.1(transitive)
+ Addedreadable-stream@1.0.34(transitive)
+ Addedstring_decoder@0.10.31(transitive)