Permalink
Browse files

Switching from jslint to jshint as the default linter for shifter

  • Loading branch information...
1 parent 849162a commit 5645d71f1cb16597094687db75ee08305d6e75ed @davglass davglass committed Oct 1, 2012
Showing with 92 additions and 40 deletions.
  1. +8 −1 README.md
  2. +1 −1 lib/args.js
  3. +1 −1 lib/help.js
  4. +60 −18 lib/module.js
  5. +19 −0 lib/tasks/jshint.js
  6. +3 −3 package.json
  7. +0 −16 tests/args.js
View
@@ -5,6 +5,14 @@ The purpose of this project is to replace YUI's use of our old ant [Builder](htt
We have out grown our old builder, so it was time to build a new one!
+Linting
+-------
+
+As of `0.1.0`, [JSHint](http://jshint.com/) is the default lint tool used by `shifter`. We maintain a
+list of our lint preferences in the [yui-lint](https://github.com/yui/yui-lint) project. `shifter` will
+default to our rules unless `--lint config` is passed. Then it will search up the file tree and attempt
+to load your custom `.jshintrc` file.
+
Documentation
-------------
@@ -34,7 +42,6 @@ More detail can be found in the [documentation](http://yui.github.com/shifter/)
-v/--version show version
-h/--help show this stuff
-m/--modules <module> limit the modules to build (array: -m foo -m bar)
- --lint [preferred|defaults|strict] (preferred is the default) lint mode: https://github.com/yui/yui-lint
--strict add "use strict" to module wrapper
--walk Walk the current directory and shift all builds. (cd yui3/src && shifter --walk)
-m/--modules also supported here for filtering
View
@@ -21,7 +21,7 @@ var nopt = require('nopt'),
jsstamp: Boolean,
list: Boolean,
config: require('path'),
- lint: [ 'defaults', 'strict', 'preferred', false ]
+ lint: [ 'config', false ]
},
shorts = {
"c": ["--config"],
View
@@ -51,7 +51,7 @@ if (args.help) {
console.log(' -v/--version show version');
console.log(' -h/--help show this stuff');
console.log(' -m/--modules [module] limit the modules to build (array: -m foo -m bar)');
- console.log(' --lint [preferred|defaults|strict] (preferred is the default) lint mode: https://github.com/yui/yui-lint');
+ console.log(' --lint [config] default mode or look for .jshintrc in path: https://github.com/yui/yui-lint');
console.log(' --strict add "use strict" to module wrapper');
console.log(' -c/--config [file] specify a config file name');
console.log(' --ant parse the ant files and create a build.json but do not build');
View
@@ -1,4 +1,3 @@
-/*jslint stupid: true, regexp: true, nomen: true */
/*
Copyright (c) 2012, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
@@ -65,7 +64,7 @@ var Stack = require('./stack').Stack,
_execFile = require('child_process').execFile,
rimraf = require('rimraf'),
ncp = require('ncp').ncp,
- jslintConfig = {},
+ jshintConfig = {},
lintFail = false,
lintSTDError = false,
cacheBuild = false,
@@ -98,25 +97,63 @@ var Stack = require('./stack').Stack,
}
}
},
+ find = function(dir, file, cb) {
+ var files = fs.readdirSync(dir),
+ found = files.some(function(f) {
+ if (f === file) {
+ cb(null, path.join(dir, f));
+ return true;
+ }
+ }),
+ next = path.join(dir, '../');
+
+ if (!found) {
+ if (dir === next) {
+ cb(true);
+ return;
+ }
+ find(next, file, cb);
+ }
+ },
+ parseJSHintConfig = function (file) {
+ var str = fs.readFileSync(file, 'utf8');
+ //Borrowed from jshint
+ str = str.replace(/\/\*(?:(?!\*\/)[\s\S])*\*\//g, '');
+ str = str.replace(/\/\/[^\n\r]*/g, ''); //everything after "//"
+
+ return JSON.parse(str);
+ },
+ fetchJSHintConfig = function () {
+ var json = null;
+ find(process.cwd(), '.jshintrc', function (err, file) {
+ if (file) {
+ log.info('loading jshint config from: ' + file);
+ json = parseJSHintConfig(file);
+ }
+ });
+ return json;
+ },
setJSLint = function () {
var i;
- jslintConfig = {
+ jshintConfig = {
config: {},
callback: function (linted) {
- var messages = linted.jslint || [],
+ var messages = lint.filter(linted.jshint) || [],
counter = 0,
fn = 'log';
if (lintSTDError) {
fn = 'error';
}
+
if (messages.length) {
log.err(linted.name + ' contains ' + messages.length + ' lint errors');
messages.forEach(function (item) {
if (item && item.reason) {
counter = counter + 1;
console[fn](' #' + counter + ': ' + log.color(item.reason, 'yellow'));
if (item.evidence) {
- console[fn](' ' + String(item.evidence).trim() + log.color(' // line ' + item.line + ', pos ' + item.character, 'white'));
+ console[fn](' ' + String(item.evidence).trim() +
+ log.color(' // line ' + item.line + ', pos ' + item.character, 'white'));
}
}
});
@@ -128,9 +165,12 @@ var Stack = require('./stack').Stack,
};
for (i in defaultLint) {
if (defaultLint.hasOwnProperty(i)) {
- jslintConfig.config[i] = defaultLint[i];
+ jshintConfig.config[i] = defaultLint[i];
}
}
+ if (strictMode) {
+ jshintConfig.config.strict = true;
+ }
},
resolve = function (items, dir) {
var i = [];
@@ -164,7 +204,6 @@ var Stack = require('./stack').Stack,
},
buildDir = path.join(process.cwd(), '../../build'),
loggerRegex = /^.*?(?:logger|Y.log).*?(?:;|\).*;|(?:\r?\n.*?)*?\).*;).*;?.*?\r?\n/mg,
- metaData = {},
exists = fs.existsSync || path.existsSync;
@@ -208,7 +247,7 @@ var buildCSS = function (mod, name, callback) {
.cssmin()
.check()
.write(path.join(buildDir, name, name + '-min.css'))
- .run(function (err, result) {
+ .run(function (err) {
if (err) {
if (/file has not changed/.test(err)) {
log.warn(name + ': ' + err);
@@ -229,7 +268,6 @@ var buildJS = function (mod, name, callback) {
logger: log,
registry: registry
}),
- bail = false,
modName = mod.name || name,
fileName = mod.basefilename || name,
replacers = [],
@@ -262,7 +300,7 @@ var buildJS = function (mod, name, callback) {
queue.replace(replacers);
}
if (defaultLint) {
- queue.jslint(jslintConfig);
+ queue.jshint(jshintConfig);
}
queue.md5check({
@@ -326,7 +364,7 @@ var buildCoverage = function (mod, name, callback) {
.check()
.log('writing coverage file to ' + fileName + '/' + fileName + '-coverage.js')
.write(path.join(buildDir, fileName, fileName + '-coverage.js'))
- .run(function (err, result) {
+ .run(function (err) {
if (err) {
log.err('coverage: ' + err);
}
@@ -385,7 +423,7 @@ var buildLang = function (mod, name, callback) {
queue[compressorFn](compressorConfig)
.check()
.write(path.join(buildDir, name, 'lang', fileName))
- .run(stack.add(function (err, result) {
+ .run(stack.add(function (err) {
if (err) {
log.err('lang: ' + err);
} else {
@@ -573,10 +611,14 @@ var build = function (mod, name, options, callback) {
if (options.lint === false) {
defaultLint = options.lint;
- log.warn('skipping jslint, you better be linting your stuff with something!');
+ log.warn('skipping jshint, you better be linting your stuff with something!');
} else {
- defaultLint = lint[options.lint];
- log.info('using ' + options.lint + ' jslint setting');
+ if (options.lint === 'config') {
+ defaultLint = fetchJSHintConfig();
+ }
+ if (!defaultLint) {
+ defaultLint = lint.preferred;
+ }
setJSLint();
}
@@ -598,7 +640,7 @@ var build = function (mod, name, options, callback) {
mod.stamp = options.jsstamp;
if (mod.jsfiles) {
- exports.js(mod, name, stack.add(function (err, result) {
+ exports.js(mod, name, stack.add(function (err) {
if (err) {
log.warn('skipping coverage file build due to previous build error');
} else {
@@ -738,7 +780,7 @@ var _rollup = function (mod, name, options, callback) {
}
if (defaultLint) {
- queue.jslint(jslintConfig);
+ queue.jshint(jshintConfig);
}
queue.log('linting done, writing ' + path.join(fileName, fileName + '.js'))
@@ -750,7 +792,7 @@ var _rollup = function (mod, name, options, callback) {
.check()
.log('compressing done, writing ' + path.join(fileName, fileName + '-min.js'))
.write(path.join(buildDir, fileName, fileName + '-min.js'))
- .run(function (err, result) {
+ .run(function (err) {
if (err) {
log.error(name + ' rollup: ' + err);
}
View
@@ -0,0 +1,19 @@
+var jshint = require('jshint').JSHINT;
+
+exports.jshint = function (options, blob, done) {
+ options = options || {};
+
+ var source = blob.result,
+ config = options.config,
+ callback = options.callback,
+ result = jshint(source, config),
+ errors = null,
+ linted = null;
+
+ if (!result) {
+ errors = jshint.errors;
+ }
+
+ linted = errors ? new blob.constructor(blob, { jshint: errors }) : blob;
+ done(callback ? callback(linted) : null, linted);
+};
View
@@ -11,8 +11,8 @@
"nopt": "*",
"yuitest-coverage": ">=0.0.5",
"yuicompressor": "2.4.7",
- "yui-lint": "*",
- "jslint": "*",
+ "yui-lint": "~0.1.0",
+ "jshint": "~0.9.0",
"uglify-js": "~1.3.3",
"cssmin": "~0.3.0",
"watch": "*",
@@ -33,7 +33,7 @@
"shifter": "./bin/shifter"
},
"scripts": {
- "pretest": "jslint --node --sloppy ./lib/*.js ./lib/*/*.js",
+ "pretest": "jshint --config ./node_modules/yui-lint/jshint.json ./lib/*.js ./lib/*/*.js",
"test": "vows --spec ./tests/*.js"
},
"preferGlobal": "true",
View
@@ -87,14 +87,6 @@ var tests = {
assert.equal(topic.fail, true);
}
},
- 'should parse --lint defaults': {
- topic: function() {
- return args.parse(['', '', '--lint', 'defaults']);
- },
- 'should parse defaults': function(topic) {
- assert.equal(topic.lint, 'defaults');
- }
- },
'should parse --lint preferred': {
topic: function() {
return args.parse(['', '', '--lint', 'preferred']);
@@ -103,14 +95,6 @@ var tests = {
assert.equal(topic.lint, 'preferred');
}
},
- 'should parse --lint strict': {
- topic: function() {
- return args.parse(['', '', '--lint', 'strict']);
- },
- 'should parse defaults': function(topic) {
- assert.equal(topic.lint, 'strict');
- }
- },
'should parse --lint foobar as preferred': {
topic: function() {
return args.parse(['', '', '--lint', 'foobar']);

0 comments on commit 5645d71

Please sign in to comment.