Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 35 additions & 19 deletions src/cli/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ function cli(api){
"warnings" : { "format" : "<rule[,rule]+>", "description" : "Indicate which rules to include as warnings."},
"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."},
"config" : { "format" : "<file>", "description" : "Reads csslint options from specified file."},
"version" : { "format" : "", "description" : "Outputs the current version number."}
};

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


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

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

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

return options;
}



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

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

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

// Command line arguments override config file
options = processArguments(args, options);

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

// Validate options
validateOptions(options);

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

if (options["list-rules"]){
if (cliOptions["list-rules"]){
printRules();
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));
}
68 changes: 68 additions & 0 deletions tests/cli/assets/apiStub.js
Original file line number 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 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 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);
})();