Permalink
Browse files

add recursive options, lintify, rewrite code

  • Loading branch information...
kof committed Dec 28, 2010
1 parent b778904 commit ac4f7f55fdee6431e5c56fbd6633df48906f4313
Showing with 215 additions and 81 deletions.
  1. +53 −5 bin/cli.js
  2. +7 −8 bin/test.js
  3. +51 −40 lib/codenazi.js
  4. +1 −1 lib/linter/closure-linter.js
  5. +53 −2 readme.md
  6. +3 −0 test/fixtures/rec/jslint.js
  7. +47 −25 test/test.js
View
@@ -1,10 +1,51 @@
var join = require('path').join,
+ util = require('util'),
root = join(__dirname, '..'),
args = require(join(root, 'deps', 'argsparser')).parse(),
- codenazi = require(root),
- util = require('util');
+ codenazi = require(root);
-var start = Date.now();
+var o = codenazi.options;
+
+var help = [
+ '\nUsage: codenazi [options]',
+ 'Options:',
+ '-f, --file, --files path to the file, or directory to be validated',
+ '-d, --dir path to the directory, where all files will be validated',
+ '-c, --config path to the config file',
+ '-h, --help show this help\n'
+];
+
+for (var key in args) {
+ switch (key) {
+ case '-f':
+ case '--file':
+ case '--files':
+ /**
+ * @see codenazi.options.files
+ */
+ o.files = args[key];
+ break;
+ case '-c':
+ case '--config':
+ /**
+ * @see codenazi.options.config
+ */
+ o.config = args[key];
+ break;
+ case '-r':
+ case '--recursive':
+ /**
+ * @see codenazi.options.recursive
+ */
+ o.recursive = args[key];
+ break;
+ case '-h':
+ case '-?':
+ case '--help':
+ util.puts.apply(util, help);
+ return;
+ }
+}
/**
@@ -20,7 +61,12 @@ function colorize(str, color) {
return '\x1B[' + colors[color] + 'm' + str + '\x1B[0m';
}
-codenazi.run(args['-f'], args['-c'], function(errors) {
+var start = Date.now();
+
+/**
+ * @see codenazi.options.callback
+ */
+o.callback = function(errors) {
errors.forEach(function(err) {
util.puts(
colorize(err.file, 'red'),
@@ -37,4 +83,6 @@ codenazi.run(args['-f'], args['-c'], function(errors) {
if (errors.length === 0) {
util.puts(colorize('Successfull validated.\x1B[0m', 'green'));
}
-});
+};
+
+codenazi.run();
View
@@ -1,11 +1,10 @@
-#!/usr/bin/env node
-
-var join = require("path").join,
- root = join(__dirname, ".."),
- qunit = require("qunit");
+var join = require('path').join,
+ root = join(__dirname, '..'),
+ qunit = require('qunit');
+//qunit.options.coverage = false;
qunit.run({
- code: join(root, "lib", "codenazi.js"),
- tests: join(root, "test", "test.js")
-});
+ code: join(root, 'lib', 'codenazi.js'),
+ tests: join(root, 'test', 'test.js')
+});
View
@@ -1,84 +1,95 @@
var fs = require('fs'),
- join = require('path').join,
- o;
+ vm = require('vm'),
+ join = require('path').join;
/**
- * Options object
+ * Runner options object
* @type {Object}
* @export
*/
-o = exports.options = {
- confRoot: join(__dirname, '..', 'conf'),
+exports.options = {
+ files: [],
+ config: {},
+ callback: function() {},
+ recursive: false,
linter: {
jslint: join(__dirname, 'linter', 'jslint'),
'closure-linter': join(__dirname, 'linter', 'closure-linter')
}
};
-var readconf = (function() {
- var vm = require('vm'),
- cache = {};
+function readdir(path, r) {
+ var files = [],
+ rjs = /\.js$/;
- return function readconf(name) {
- if (!cache[name]) {
- var path = join(o.confRoot, name + '.json'),
- sandbox = {};
- // don't use JSON.parse to be able to have comments
- vm.runInNewContext('o=' + fs.readFileSync(path), sandbox, path);
- cache[name] = sandbox.o;
+ fs.readdirSync(path).forEach(function(name) {
+ var file = join(path, name);
+ if (fs.statSync(file).isDirectory()) {
+ if (r) {
+ files = files.concat(readdir(file, r));
+ }
+ } else if (rjs.test(file)) {
+ files.push(file);
}
+ });
- return cache[name];
- };
-}());
+ return files;
+}
/**
* Run all checker
- * @param {Array|String} files array or string of pathes to files or dir.
- * @param {String} confName name of configuration file.
- * @param {Function} callback function which will called after all is done.
+ * @param {Object} opts runner options: files, config, callback.
+ * @export
*/
-exports.run = function(files, confName, callback) {
- var options = readconf(confName),
+exports.run = function(opts) {
+ var o = exports.options,
+ sandbox = {},
linter,
- dir, rjs = /\.js$/,
errors = [],
done = 0,
- linters = 0;
+ linters = 0,
+ key;
+
+ if (opts) {
+ for (key in opts) {
+ o[key] = opts[key];
+ }
+ }
- if (typeof files === 'string') {
- if (fs.statSync(files).isDirectory()) {
- dir = files;
- files = [];
- fs.readdirSync(dir).forEach(function(name) {
- if (rjs.test(name)) {
- files.push(join(dir, name));
- }
- });
+ if (typeof o.files === 'string') {
+ if (fs.statSync(o.files).isDirectory()) {
+ o.files = readdir(o.files, o.recursive);
// its a file
} else {
- files = [files];
+ o.files = [o.files];
}
}
+ // its a path to the config
+ if (typeof o.config === 'string') {
+ // don't use JSON.parse to be able to have comments
+ vm.runInNewContext('o=' + fs.readFileSync(o.config), sandbox, o.config);
+ o.config = sandbox.o;
+ }
+
function lint(file) {
- require(o.linter[linter])(file, options[linter], function(err) {
+ require(o.linter[linter])(file, o.config[linter], function(err) {
if (err && err.length > 0) {
errors = errors.concat(err);
}
done++;
- if (done === files.length * linters) {
- callback(errors);
+ if (done === o.files.length * linters) {
+ o.callback(errors);
}
});
}
- Object.keys(options).forEach(function(name) {
+ Object.keys(o.config).forEach(function(name) {
linter = name;
linters++;
- files.forEach(lint);
+ o.files.forEach(lint);
});
};
@@ -37,7 +37,7 @@ module.exports = function(file, options, callback) {
// remove file name
data.shift();
data.forEach(function(str) {
- // only add errors
+ // only add errors - they start always with "Line"
if (str.substr(0, 4) !== 'Line') {
return;
}
View
@@ -1,16 +1,67 @@
## Codenazi - code quality tool for javascript.
-Codenazi doesn't implements own validators - it wrapps other available quality tools.
+Codenazi doesn't implement validators - it utilizes free available quality tools.
Javascript lang is too flexible and it becomes very hard to work in larger teams, especially if some of members are newbie on javascript.
Codenazi is highly configurable, so if you don't want to use some rules, you can create your own conf file.
+You can easily add more quality tools.
## Features
- all rules can be defined in one configuration ".json" file
- you can create many conf. files, because you might have different rules for different environments f.e. server and client.
-- use of all available checker, independent of language it is written in, if you have one more - you can add it
+- it uses all available linter, if you have one more - you can add it
- unified errors reporting format
## Currently used tools
- JSLint http://www.jslint.com/lint.html
- Closure Linter http://code.google.com/p/closure-linter
- Closure Compiler http://code.google.com/p/closure-compiler
+
+## Installation
+ npm install codenazi
+
+## Usage
+
+ $ codenazi -h print help - read there about options
+
+ var codenazi = require('codenazi');
+ codenazi.run({
+ files: "/path/to/file" // can be an array or directory
+ config: "/path/to/config.json" // can be a json object or path to conf json, see ./conf/*
+ recursive: false, // read dir recursively, default to false
+ // callback functions, which is called on complete and errors array is passed
+ // see ./bin/cli.js
+ callback: function(errors) {
+ console.log(errors);
+ },
+ });
+
+## Config file
+- You can create a config which contains all rules for every validator. See ./conf/*.json
+- *.json configs can have comments in it
+
+## Unified error format
+Errors array passed to callback contains objects in this format:
+
+ {
+ linter: "validator name",
+ file: "file name",
+ message: "error message",
+ line: "line number"
+ }
+
+## How to add more linters
+
+- put the linter into ./deps/litner-name
+- write a wrapper for it and put it into ./lib/linter/linter-name.js
+ - wrapper should implement one function:
+ module.exports = function(file, options, callback){
+
+ };
+ - wrapper should talk with validator and on complete call the callback and pass errors array in unified error format
+ - see ./lib/linter/jslint.js
+ - options for this validator in json should be named
+ {
+ "validator-name": {
+ //options
+ }
+ }
@@ -0,0 +1,3 @@
+// just one error to ensure jslint works
+// only jslint can validate undeclared globals
+test();
Oops, something went wrong.

0 comments on commit ac4f7f5

Please sign in to comment.