Skip to content

Commit

Permalink
add cli
Browse files Browse the repository at this point in the history
  • Loading branch information
yaniswang committed Apr 5, 2013
1 parent 7b44d37 commit f907b1b
Show file tree
Hide file tree
Showing 10 changed files with 309 additions and 44 deletions.
1 change: 1 addition & 0 deletions CHANGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ add:

1. add rule: csslint
2. add rule: jshint
3. add cli

fix:

Expand Down
5 changes: 4 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ module.exports = function(grunt) {
},
replace: {
htmlhint: {
files: { 'lib/htmlhint.js':'lib/htmlhint.js'},
files: {
'lib/htmlhint.js':'lib/htmlhint.js',
'bin/htmlhint':'src/cli.js'
},
options: {
prefix: '@',
variables: {
Expand Down
4 changes: 2 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
TODO
==================

1. nodejs cli
2. grunt plugin
1. grunt plugin
2. w3c rule
146 changes: 146 additions & 0 deletions bin/htmlhint
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#!/usr/bin/env node

var program = require('commander'),
fs = require('fs'),
path = require('path'),
HTMLHint = require("../index").HTMLHint;

require('colors');

function map(val) {
var objMap = {};
val.split(',').forEach(function(item){
var arrItem = item.split(/\s*=\s*/);
objMap[arrItem[0]] = arrItem[1]?arrItem[1]:true;
});
return objMap;
}

program.on('--help', function(){
console.log(' Examples:');
console.log('');
console.log(' htmlhint -l');
console.log(' htmlhint -r tag-pair,id-class-value=underline test.html');
console.log(' htmlhint -c .htmlhintrc test.html');
console.log('');
});

program
.version('0.9.2')
.usage('[options] <file ...>')
.option('-l, --list', 'show all of the rules available.')
.option('-c, --config <file>', 'custom configuration file.')
.option('-r, --rules <ruleid, ruleid=value ...>', 'set all of the rules available.', map)
.parse(process.argv);

if(program.list){
listRules();
quit(0);
}

var arrAllFiles = getAllFiles(program.args);

var ruleset = program.rules;
if(ruleset === undefined){
ruleset = getConfig(program.config);
}

quit(processFiles(arrAllFiles, ruleset));

function listRules(){
var rules = HTMLHint.rules,
rule;
console.log('\r\nAll rules:');
console.log('======================================');
for (var id in rules){
rule = rules[id];
console.log('\r\n'+rule.id+' :');
console.log(' '+rule.description);
}
}

function getConfig(configFile){
if(configFile === undefined){
configFile = '.htmlhintrc';
}
if(fs.existsSync(configFile)){
var config = fs.readFileSync(configFile, 'utf-8'),
ruleset;
try{
ruleset = JSON.parse(config);
}
catch(e){}
return ruleset;
}
}

function getAllFiles(arrTargets){
var arrAllFiles = [];
if(arrTargets.length > 0){
for(var i=0,l=arrTargets.length;i<l;i++){
getFiles(arrTargets[i], arrAllFiles);
}
}
else{
getFiles(process.cwd(), arrAllFiles);
}
return arrAllFiles;
}

function getFiles(filepath, arrFiles){
if(fs.existsSync(filepath) === false){
return;
}
filepath = path.resolve(process.cwd(), filepath);
var stat = fs.statSync(filepath);
if(stat.isFile() && /\.html?$/i.test(filepath)){
arrFiles.push(filepath);
}
else if(stat.isDirectory()){
fs.readdirSync(filepath).forEach(function(filename){
getFiles(filepath + '/' + filename, arrFiles);
});
}
}

function processFiles(arrFiles, ruleset){
var exitcode = 0,
allHintCount = 0;
arrFiles.forEach(function(filepath){
var hintCount = hintFile(filepath, ruleset);
if(hintCount > 0){
exitcode = 1;
allHintCount += hintCount;
}
});
if(allHintCount > 0){
console.log('\r\n%d problems.'.red, allHintCount);
}
else{
console.log('No problem.'.green);
}
return exitcode;
}

function hintFile(filepath, ruleset){
var html = fs.readFileSync(filepath, 'utf-8');
var messages = HTMLHint.verify(html, ruleset);
if(messages.length > 0){
console.log(filepath+':');
messages.forEach(function(hint){
console.log('\tline %d, col %d: %s', hint.line, hint.col, hint.message[hint.type === 'error'?'red':'yellow']);
});
console.log('');
}
return messages.length;
}

function quit(code){
if ((!process.stdout.flush || !process.stdout.flush()) && (parseFloat(process.versions.node) < 0.5)) {
process.once("drain", function () {
process.exit(code || 0);
});
} else {
process.exit(code || 0);
}
}
34 changes: 0 additions & 34 deletions bin/htmlhint.js

This file was deleted.

2 changes: 1 addition & 1 deletion coverage.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/htmlhint.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"main": "./index",
"dependencies": {
"commander": "~1.1.1",
"colors": "~0.6.0-1",
"jshint": "~1.1.0",
"csslint": "~0.9.10"
},
Expand Down
146 changes: 146 additions & 0 deletions src/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#!/usr/bin/env node

var program = require('commander'),
fs = require('fs'),
path = require('path'),
HTMLHint = require("../index").HTMLHint;

require('colors');

function map(val) {
var objMap = {};
val.split(',').forEach(function(item){
var arrItem = item.split(/\s*=\s*/);
objMap[arrItem[0]] = arrItem[1]?arrItem[1]:true;
});
return objMap;
}

program.on('--help', function(){
console.log(' Examples:');
console.log('');
console.log(' htmlhint -l');
console.log(' htmlhint -r tag-pair,id-class-value=underline test.html');
console.log(' htmlhint -c .htmlhintrc test.html');
console.log('');
});

program
.version('@VERSION')
.usage('[options] <file ...>')
.option('-l, --list', 'show all of the rules available.')
.option('-c, --config <file>', 'custom configuration file.')
.option('-r, --rules <ruleid, ruleid=value ...>', 'set all of the rules available.', map)
.parse(process.argv);

if(program.list){
listRules();
quit(0);
}

var arrAllFiles = getAllFiles(program.args);

var ruleset = program.rules;
if(ruleset === undefined){
ruleset = getConfig(program.config);
}

quit(processFiles(arrAllFiles, ruleset));

function listRules(){
var rules = HTMLHint.rules,
rule;
console.log('\r\nAll rules:');
console.log('======================================');
for (var id in rules){
rule = rules[id];
console.log('\r\n'+rule.id+' :');
console.log(' '+rule.description);
}
}

function getConfig(configFile){
if(configFile === undefined){
configFile = '.htmlhintrc';
}
if(fs.existsSync(configFile)){
var config = fs.readFileSync(configFile, 'utf-8'),
ruleset;
try{
ruleset = JSON.parse(config);
}
catch(e){}
return ruleset;
}
}

function getAllFiles(arrTargets){
var arrAllFiles = [];
if(arrTargets.length > 0){
for(var i=0,l=arrTargets.length;i<l;i++){
getFiles(arrTargets[i], arrAllFiles);
}
}
else{
getFiles(process.cwd(), arrAllFiles);
}
return arrAllFiles;
}

function getFiles(filepath, arrFiles){
if(fs.existsSync(filepath) === false){
return;
}
filepath = path.resolve(process.cwd(), filepath);
var stat = fs.statSync(filepath);
if(stat.isFile() && /\.html?$/i.test(filepath)){
arrFiles.push(filepath);
}
else if(stat.isDirectory()){
fs.readdirSync(filepath).forEach(function(filename){
getFiles(filepath + '/' + filename, arrFiles);
});
}
}

function processFiles(arrFiles, ruleset){
var exitcode = 0,
allHintCount = 0;
arrFiles.forEach(function(filepath){
var hintCount = hintFile(filepath, ruleset);
if(hintCount > 0){
exitcode = 1;
allHintCount += hintCount;
}
});
if(allHintCount > 0){
console.log('\r\n%d problems.'.red, allHintCount);
}
else{
console.log('No problem.'.green);
}
return exitcode;
}

function hintFile(filepath, ruleset){
var html = fs.readFileSync(filepath, 'utf-8');
var messages = HTMLHint.verify(html, ruleset);
if(messages.length > 0){
console.log(filepath+':');
messages.forEach(function(hint){
console.log('\tline %d, col %d: %s', hint.line, hint.col, hint.message[hint.type === 'error'?'red':'yellow']);
});
console.log('');
}
return messages.length;
}

function quit(code){
if ((!process.stdout.flush || !process.stdout.flush()) && (parseFloat(process.versions.node) < 0.5)) {
process.once("drain", function () {
process.exit(code || 0);
});
} else {
process.exit(code || 0);
}
}
Loading

0 comments on commit f907b1b

Please sign in to comment.