Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #502 from dmi3y/cliconfig

Allow config file path to be passed through the CLI
  • Loading branch information...
commit f8448025544dc3cb021ed2b713350e86a4175a1d 2 parents ea36ad5 + 0a23182
@nschonni nschonni authored
View
54 src/cli/common.js
@@ -17,6 +17,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."}
};
@@ -251,8 +252,9 @@ function cli(api){
}
- function processArguments(args, options) {
+ function processArguments(args, extend) {
var arg = args.shift(),
+ options = extend || {},
argName,
parts,
files = [];
@@ -294,9 +296,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 {
@@ -309,45 +318,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));
}
View
68 tests/cli/assets/apiStub.js
@@ -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;
+};
View
67 tests/cli/assets/data.js
@@ -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;}"
+ },
+ }
+};
View
73 tests/cli/cli-common.js
@@ -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);
+})();
Please sign in to comment.
Something went wrong with that request. Please try again.