Skip to content

Commit

Permalink
Merge pull request #502 from dmi3y/cliconfig
Browse files Browse the repository at this point in the history
Allow config file path to be passed through the CLI
  • Loading branch information
nschonni committed May 13, 2014
2 parents ea36ad5 + 0a23182 commit f844802
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 19 deletions.
54 changes: 35 additions & 19 deletions src/cli/common.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ function cli(api){
"warnings" : { "format" : "<rule[,rule]+>", "description" : "Indicate which rules to include as warnings."}, "warnings" : { "format" : "<rule[,rule]+>", "description" : "Indicate which rules to include as warnings."},
"ignore" : { "format" : "<rule[,rule]+>", "description" : "Indicate which rules to ignore completely."}, "ignore" : { "format" : "<rule[,rule]+>", "description" : "Indicate which rules to ignore completely."},
"exclude-list": { "format" : "<file|dir[,file|dir]+>", "description" : "Indicate which files/directories to exclude from being linted."}, "exclude-list": { "format" : "<file|dir[,file|dir]+>", "description" : "Indicate which files/directories to exclude from being linted."},
"config" : { "format" : "<file>", "description" : "Reads csslint options from specified file."},
"version" : { "format" : "", "description" : "Outputs the current version number."} "version" : { "format" : "", "description" : "Outputs the current version number."}
}; };


Expand Down Expand Up @@ -251,8 +252,9 @@ function cli(api){
} }




function processArguments(args, options) { function processArguments(args, extend) {
var arg = args.shift(), var arg = args.shift(),
options = extend || {},
argName, argName,
parts, parts,
files = []; files = [];
Expand Down Expand Up @@ -294,9 +296,16 @@ function cli(api){
} }
} }


function readConfigFile(options) { function readConfigFile(config) {
var data = api.readFile(api.getFullPath(".csslintrc")), var csslintrc = config || ".csslintrc",
json; data = api.readFile(api.getFullPath(csslintrc));
return data;
}

function readConfigData(config) {
var data = readConfigFile(config),
json,
options = {};
if (data) { if (data) {
if (data.charAt(0) === "{") { if (data.charAt(0) === "{") {
try { try {
Expand All @@ -309,45 +318,52 @@ function cli(api){
} }
} catch(e) {} } catch(e) {}
} }
options = processArguments(data.split(/[\s\n\r]+/m), options); options = processArguments(data.split(/[\s\n\r]+/m));
} }


return options; return options;
} }




//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Process command line // Process command line
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------


var args = api.args, var args = api.args,
argCount = args.length, argCount = args.length,
options = {}; options,
rcOptions,
cliOptions;


// first look for config file .csslintrc // Preprocess command line arguments
options = readConfigFile(options); cliOptions = processArguments(args);


// Command line arguments override config file if (cliOptions.help || argCount === 0){
options = processArguments(args, options);

if (options.help || argCount === 0){
outputHelp(); outputHelp();
api.quit(0); api.quit(0);
} }


// Validate options if (cliOptions.version){
validateOptions(options);

if (options.version){
api.print("v" + CSSLint.version); api.print("v" + CSSLint.version);
api.quit(0); api.quit(0);
} }


if (options["list-rules"]){ if (cliOptions["list-rules"]){
printRules(); printRules();
api.quit(0); api.quit(0);
} }


// Look for config file
rcOptions = readConfigData(cliOptions.config);

// Command line arguments override config file
options = CSSLint.Util.mix(rcOptions, cliOptions);

// hot fix for CSSLint.Util.mix current behavior
// https://github.com/CSSLint/csslint/issues/501
options = rcOptions;

// Validate options
validateOptions(options);

api.quit(processFiles(options.files,options)); api.quit(processFiles(options.files,options));
} }
68 changes: 68 additions & 0 deletions tests/cli/assets/apiStub.js
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,68 @@
/*jshint node:true*/
"use strict";
var
stub = {
logbook: function (log) {
this.logs.push(log);
},
readLogs: function () {
return this.logs.slice();
},

getFullPath: function (path) {
return path;
},
getFiles: function (dir) {
var
filesobj = this.fakedFs[dir],
fileix,
out = [];
for (fileix in filesobj) {
if ( filesobj.hasOwnProperty(fileix) && /\.css$/.test(fileix) ) {
out.push(dir + "/" + fileix);
}
}
return out;
},
readFile: function (path) {
var
spath = path.split("/"),
spathLen = spath.length,
i,
out = this.fakedFs;

for (i = 0; i < spathLen; i += 1) {
out = out[spath[i]];
}

return out;
},
isDirectory: function (checkit) {
var
result = this.fakedFs[checkit];
return typeof result === "object";
},
print: function (msg) {
this.logbook(msg);
},
quit: function (signal) {
this.logbook(signal);
}
};

module.exports = function (setup) {
var
api,
setix;

api = Object.create(stub);

for (setix in setup) {
if (setup.hasOwnProperty(setix)) {
api[setix] = setup[setix];
}
}

api.logs = [];
return api;
};
67 changes: 67 additions & 0 deletions tests/cli/assets/data.js
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,67 @@
/*jshint node:true*/
module.exports = {
"suites": {
"config csslintrc override": {
"args": [
"--config=.rc1",
"dir"
],
"expecting": [
"csslint: No errors in dir/a.css.",
"csslint: No errors in dir/b.css.",
0
]
},
"straight linting": {
"args": [
"dir"
],
"expecting": [
"csslint: There is 1 problem in dir/a.css.",
"csslint: There is 1 problem in dir/b.css.",
0
]
},
"mix of cli options": {
"args": [
"--config=.rc1",
"--ignore=important",
"dir"
],
"expecting": [
"csslint: No errors in dir/a.css.",
"csslint: There is 1 problem in dir/b.css.",
0
]
},
"more mixes of cli options": {
"args": [
"--config=.rc1",
"--errors=important",
"dir"
],
"expecting": [
"csslint: There is 1 problem in dir/a.css.",
"csslint: No errors in dir/b.css.",
1
]
},
"version": {
"args": [
"--version"
],
"expecting": [
"v@VERSION@",
0
]
}
},

"fakedFs": {
".rc1": "--ignore=important,ids",
"dir": {
"a.css": ".a {color: red!important;}",
"b.css": "#a {color: red;}"
},
}
};
73 changes: 73 additions & 0 deletions tests/cli/cli-common.js
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,73 @@
/*jshint loopfunc:true, node:true */
"use strict";
function include(path, sandbox) {
var
vm = require("vm"),
fs = require("fs"),
file;

file = fs.readFileSync(path);
vm.runInNewContext(file, sandbox);
}



(function(){

var Assert = YUITest.Assert,
suite = new YUITest.TestSuite("General Tests for CLI"),
apiStub = require("./tests/cli/assets/apiStub.js"),
data = require("./tests/cli/assets/data.js"),
suites = data.suites,
suiteix,
sandbox = {
CSSLint: CSSLint
};

include(__dirname + "/src/cli/common.js", sandbox); /* expose sandbox.cli */

for (suiteix in suites) {
if (suites.hasOwnProperty(suiteix)) {
(function (suiteix) {

suite.add(new YUITest.TestCase({

name: "Test " + suiteix,

"Outcome logs should match expected": function (){
var
it = suites[suiteix],
expecting = it.expecting,
expectingLen = expecting.length,
outcome,
api,
exp,
out,
i = 0;

data.args = it.args.slice();
api = apiStub(data);
sandbox.cli(api);
outcome = api.readLogs();

for (i; i < expectingLen; i += 1) {
exp = expecting[i];
out = outcome[i];

if ( typeof out === "string") {
out = /^.*/.exec(out.trim())[0];
}
if ( exp !== out ) {
Assert.fail("Expecting: " + exp + " Got: " + out);
}
}
Assert.pass();

}
}));
})(suiteix);
}
}

YUITest.TestRunner.add(suite);
})();

0 comments on commit f844802

Please sign in to comment.