@@ -8,7 +8,7 @@ function cli(api){
88 //-------------------------------------------------------------------------
99 // Helper functions
1010 //-------------------------------------------------------------------------
11-
11+
1212 /**
1313 * Returns an array of messages for a particular type.
1414 * @param messages {Array} Array of CSS Lint messages.
@@ -18,7 +18,7 @@ function cli(api){
1818 function pluckByType ( messages , type ) {
1919 return messages . filter ( function ( message ) {
2020 return message . type === type ;
21- } ) ;
21+ } ) ;
2222 }
2323
2424 /**
@@ -29,24 +29,24 @@ function cli(api){
2929 function gatherRules ( options , ruleset ) {
3030 var warnings = options . rules || options . warnings ,
3131 errors = options . errors ;
32-
32+
3333 if ( warnings ) {
3434 ruleset = ruleset || { } ;
3535 warnings . split ( "," ) . forEach ( function ( value ) {
3636 ruleset [ value ] = 1 ;
3737 } ) ;
3838 }
39-
39+
4040 if ( errors ) {
4141 ruleset = ruleset || { } ;
4242 errors . split ( "," ) . forEach ( function ( value ) {
4343 ruleset [ value ] = 2 ;
4444 } ) ;
4545 }
46-
46+
4747 return ruleset ;
4848 }
49-
49+
5050 /**
5151 * Filters out rules using the ignore command line option.
5252 * @param options {Object} the CLI options
@@ -55,17 +55,51 @@ function cli(api){
5555 function filterRules ( options ) {
5656 var ignore = options . ignore ,
5757 ruleset = null ;
58-
58+
5959 if ( ignore ) {
6060 ruleset = CSSLint . getRuleset ( ) ;
6161 ignore . split ( "," ) . forEach ( function ( value ) {
6262 delete ruleset [ value ] ;
63- } ) ;
63+ } ) ;
6464 }
65-
65+
6666 return ruleset ;
6767 }
6868
69+
70+ /**
71+ * Filters out files using the exclude-list command line option.
72+ * @param files {Array} the list of files to check for exclusions
73+ * @param options {Object} the CLI options
74+ * @return {Array } A list of files
75+ */
76+ function filterFiles ( files , options ) {
77+ var excludeList = options [ "exclude-list" ] ,
78+ excludeFiles = [ ] ,
79+ filesToLint = files ;
80+
81+
82+ if ( excludeList ) {
83+ // Build up the exclude list, expanding any directory exclusions that were passed in
84+ excludeList . split ( "," ) . forEach ( function ( value ) {
85+ if ( api . isDirectory ( value ) ) {
86+ excludeFiles = excludeFiles . concat ( api . getFiles ( value ) ) ;
87+ } else {
88+ excludeFiles . push ( value ) ;
89+ }
90+ } ) ;
91+
92+ // Remove the excluded files from the list of files to lint
93+ excludeFiles . forEach ( function ( value ) {
94+ if ( filesToLint . indexOf ( value ) > - 1 ) {
95+ filesToLint . splice ( filesToLint . indexOf ( value ) , 1 ) ;
96+ }
97+ } ) ;
98+ }
99+
100+ return filesToLint ;
101+ }
102+
69103 /**
70104 * Outputs all available rules to the CLI.
71105 * @return {void }
@@ -107,12 +141,12 @@ function cli(api){
107141 if ( output ) {
108142 api . print ( output ) ;
109143 }
110-
144+
111145 if ( messages . length > 0 && pluckByType ( messages , "error" ) . length > 0 ) {
112146 exitCode = 1 ;
113147 }
114148 }
115-
149+
116150 return exitCode ;
117151 }
118152
@@ -126,14 +160,15 @@ function cli(api){
126160 "\nUsage: csslint-rhino.js [options]* [file|dir]*" ,
127161 " " ,
128162 "Global Options" ,
129- " --help Displays this information." ,
130- " --format=<format> Indicate which format to use for output." ,
131- " --list-rules Outputs all of the rules available." ,
132- " --quiet Only output when errors are present." ,
133- " --errors=<rule[,rule]+> Indicate which rules to include as errors." ,
134- " --warnings=<rule[,rule]+> Indicate which rules to include as warnings." ,
135- " --ignore=<rule,[,rule]+> Indicate which rules to ignore completely." ,
136- " --version Outputs the current version number."
163+ " --help Displays this information." ,
164+ " --format=<format> Indicate which format to use for output." ,
165+ " --list-rules Outputs all of the rules available." ,
166+ " --quiet Only output when errors are present." ,
167+ " --errors=<rule[,rule]+> Indicate which rules to include as errors." ,
168+ " --warnings=<rule[,rule]+> Indicate which rules to include as warnings." ,
169+ " --ignore=<rule[,rule]+> Indicate which rules to ignore completely." ,
170+ " --exclude-list=<file|dir[,file|dir]+> Indicate which files/directories to exclude from being linted." ,
171+ " --version Outputs the current version number."
137172 ] . join ( "\n" ) + "\n" ) ;
138173 }
139174
@@ -143,56 +178,58 @@ function cli(api){
143178 * @param options {Object} options object
144179 * @return {Number } exit code
145180 */
146- function processFiles ( files , options ) {
181+ function processFiles ( fileArray , options ) {
147182 var exitCode = 0 ,
148183 formatId = options . format || "text" ,
149184 formatter ,
185+ files = filterFiles ( fileArray , options ) ,
150186 output ;
151-
187+
152188 if ( ! files . length ) {
153189 api . print ( "csslint: No files specified." ) ;
154190 exitCode = 1 ;
155191 } else {
156192 if ( ! CSSLint . hasFormat ( formatId ) ) {
157193 api . print ( "csslint: Unknown format '" + formatId + "'. Cannot proceed." ) ;
158- exitCode = 1 ;
194+ exitCode = 1 ;
159195 } else {
160196 formatter = CSSLint . getFormatter ( formatId ) ;
161-
197+
162198 output = formatter . startFormat ( ) ;
163199 if ( output ) {
164200 api . print ( output ) ;
165201 }
166202
203+
167204 files . forEach ( function ( file ) {
168205 if ( exitCode === 0 ) {
169206 exitCode = processFile ( file , options ) ;
170207 } else {
171208 processFile ( file , options ) ;
172209 }
173210 } ) ;
174-
211+
175212 output = formatter . endFormat ( ) ;
176213 if ( output ) {
177214 api . print ( output ) ;
178215 }
179216 }
180217 }
181218 return exitCode ;
182- }
183-
184-
219+ }
220+
221+
185222 function processArguments ( args , options ) {
186223 var arg = args . shift ( ) ,
187224 argName ,
188225 parts ,
189226 files = [ ] ;
190-
227+
191228 while ( arg ) {
192229 if ( arg . indexOf ( "--" ) === 0 ) {
193230 argName = arg . substring ( 2 ) ;
194231 options [ argName ] = true ;
195-
232+
196233 if ( argName . indexOf ( "=" ) > - 1 ) {
197234 parts = argName . split ( "=" ) ;
198235 options [ parts [ 0 ] ] = parts [ 1 ] ;
@@ -201,7 +238,7 @@ function cli(api){
201238 }
202239
203240 } else {
204-
241+
205242 //see if it's a directory or a file
206243 if ( api . isDirectory ( arg ) ) {
207244 files = files . concat ( api . getFiles ( arg ) ) ;
@@ -211,24 +248,24 @@ function cli(api){
211248 }
212249 arg = args . shift ( ) ;
213250 }
214-
251+
215252 options . files = files ;
216253 return options ;
217254 }
218-
255+
219256 function readConfigFile ( options ) {
220257 var data = api . readFile ( api . getFullPath ( ".csslintrc" ) ) ;
221- if ( data ) {
258+ if ( data ) {
222259 options = processArguments ( data . split ( / [ \s \n \r ] + / m) , options ) ;
223260 api . print ( "ignore = " + options . ignore ) ;
224261 api . print ( "errors = " + options . errors ) ;
225262 api . print ( "warnings = " + options . warnings ) ;
226263 }
227-
264+
228265 return options ;
229266 }
230-
231-
267+
268+
232269
233270 //-----------------------------------------------------------------------------
234271 // Process command line
@@ -237,10 +274,10 @@ function cli(api){
237274 var args = api . args ,
238275 argCount = args . length ,
239276 options = { } ;
240-
277+
241278 // first look for config file .csslintrc
242- options = readConfigFile ( options ) ;
243-
279+ options = readConfigFile ( options ) ;
280+
244281 // Command line arguments override config file
245282 options = processArguments ( args , options ) ;
246283
0 commit comments