4
4
5
5
namespace CssLint ;
6
6
7
- use Generator ;
8
7
use RuntimeException ;
9
8
use Throwable ;
9
+ use CssLint \Formatter \FormatterInterface ;
10
+ use CssLint \Formatter \FormatterFactory ;
11
+ use Generator ;
10
12
11
13
/**
12
14
* @phpstan-import-type Errors from \CssLint\Linter
@@ -21,6 +23,10 @@ class Cli
21
23
22
24
private const RETURN_CODE_SUCCESS = 0 ;
23
25
26
+ private ?FormatterFactory $ formatterFactory = null ;
27
+
28
+ private FormatterInterface $ formatterManager ;
29
+
24
30
/**
25
31
* Entrypoint of the cli, will execute the linter according to the given arguments
26
32
* @param string[] $arguments arguments to be parsed (@see $_SERVER['argv'])
@@ -29,6 +35,15 @@ class Cli
29
35
public function run (array $ arguments ): int
30
36
{
31
37
$ cliArgs = $ this ->parseArguments ($ arguments );
38
+
39
+ try {
40
+ $ this ->formatterManager = $ this ->getFormatterFactory ()->create ($ cliArgs ->formatter );
41
+ } catch (RuntimeException $ error ) {
42
+ // report invalid formatter names via default (plain) formatter
43
+ $ this ->getFormatterFactory ()->create (null )->printFatalError (null , $ error );
44
+ return self ::RETURN_CODE_ERROR ;
45
+ }
46
+
32
47
if ($ cliArgs ->input === null || $ cliArgs ->input === '' || $ cliArgs ->input === '0 ' ) {
33
48
$ this ->printUsage ();
34
49
return self ::RETURN_CODE_SUCCESS ;
@@ -41,7 +56,7 @@ public function run(array $arguments): int
41
56
42
57
return $ this ->lintInput ($ cssLinter , $ cliArgs ->input );
43
58
} catch (Throwable $ throwable ) {
44
- $ this ->printError ( $ throwable -> getMessage () );
59
+ $ this ->formatterManager -> printFatalError ( null , $ throwable );
45
60
return self ::RETURN_CODE_ERROR ;
46
61
}
47
62
}
@@ -51,10 +66,13 @@ public function run(array $arguments): int
51
66
*/
52
67
private function printUsage (): void
53
68
{
69
+ $ availableFormatters = $ this ->getFormatterFactory ()->getAvailableFormatters ();
70
+ $ defaultFormatter = $ availableFormatters [0 ];
71
+
54
72
$ this ->printLine ('Usage: ' . PHP_EOL .
55
73
'------ ' . PHP_EOL .
56
74
PHP_EOL .
57
- ' ' . self ::SCRIPT_NAME . " [--options='{ }'] input_to_lint " . PHP_EOL .
75
+ ' ' . self ::SCRIPT_NAME . " [--options='{ }'] [--formatter=plain|json] input_to_lint " . PHP_EOL .
58
76
PHP_EOL .
59
77
'Arguments: ' . PHP_EOL .
60
78
'---------- ' . PHP_EOL .
@@ -68,6 +86,13 @@ private function printUsage(): void
68
86
' Example: --options= \'{ "constructors": {"o" : false}, "allowedIndentationChars": ["\t"] } \'' .
69
87
PHP_EOL .
70
88
PHP_EOL .
89
+ ' --formatter ' . PHP_EOL .
90
+ ' The formatter(s) to be used ' . PHP_EOL .
91
+ ' If not specified, the first available formatter will be used. ' . PHP_EOL .
92
+ ' Multiple formatters can be specified as a comma-separated list. ' . PHP_EOL .
93
+ ' Available formatters: ' . implode (', ' , $ availableFormatters ) . PHP_EOL .
94
+ ' Example: --formatter= ' . $ defaultFormatter . PHP_EOL .
95
+ PHP_EOL .
71
96
' input_to_lint ' . PHP_EOL .
72
97
' The CSS file path (absolute or relative) ' . PHP_EOL .
73
98
' a glob pattern of file(s) to be linted ' . PHP_EOL .
@@ -100,6 +125,15 @@ private function parseArguments(array $arguments): CliArgs
100
125
return new CliArgs ($ arguments );
101
126
}
102
127
128
+ private function getFormatterFactory (): FormatterFactory
129
+ {
130
+ if ($ this ->formatterFactory === null ) {
131
+ $ this ->formatterFactory = new FormatterFactory ();
132
+ }
133
+
134
+ return $ this ->formatterFactory ;
135
+ }
136
+
103
137
/**
104
138
* Retrieve the properties from the given options
105
139
* @param string $options the options to be parsed
@@ -207,7 +241,7 @@ private function lintGlob(string $glob): int
207
241
$ cssLinter = new Linter ();
208
242
$ files = glob ($ glob );
209
243
if ($ files === [] || $ files === false ) {
210
- $ this ->printError ( 'No files found for glob " ' . $ glob . ' " ' );
244
+ $ this ->formatterManager -> printFatalError ( $ glob , 'No files found for given glob pattern ' );
211
245
return self ::RETURN_CODE_ERROR ;
212
246
}
213
247
@@ -227,19 +261,17 @@ private function lintGlob(string $glob): int
227
261
*/
228
262
private function lintFile (Linter $ cssLinter , string $ filePath ): int
229
263
{
230
- $ source = "CSS file \"" . $ filePath . "\"" ;
231
- $ this ->printLine ('# Lint ' . $ source . '... ' );
232
-
264
+ $ source = "CSS file \"{$ filePath }\"" ;
265
+ $ this ->formatterManager ->startLinting ($ source );
233
266
if (!is_readable ($ filePath )) {
234
- $ this ->printError ( ' File " ' . $ filePath . ' " is not readable ' );
267
+ $ this ->formatterManager -> printFatalError ( $ source , ' File is not readable ' );
235
268
return self ::RETURN_CODE_ERROR ;
236
269
}
237
270
238
271
$ errors = $ cssLinter ->lintFile ($ filePath );
239
272
return $ this ->printLinterErrors ($ source , $ errors );
240
273
}
241
274
242
-
243
275
/**
244
276
* Performs lint on a given string
245
277
* @param Linter $cssLinter the instance of the linter
@@ -249,43 +281,29 @@ private function lintFile(Linter $cssLinter, string $filePath): int
249
281
private function lintString (Linter $ cssLinter , string $ stringValue ): int
250
282
{
251
283
$ source = 'CSS string ' ;
252
- $ this ->printLine ( ' # Lint ' . $ source . ' ... ' );
284
+ $ this ->formatterManager -> startLinting ( $ source );
253
285
$ errors = $ cssLinter ->lintString ($ stringValue );
254
286
return $ this ->printLinterErrors ($ source , $ errors );
255
287
}
256
288
257
- /**
258
- * Display an error message
259
- * @param string $error the message to be displayed
260
- */
261
- private function printError (string $ error ): void
262
- {
263
- $ this ->printLine ("\033[31m/!\ Error: " . $ error . "\033[0m " . PHP_EOL );
264
- }
265
-
266
289
/**
267
290
* Display the errors returned by the linter
268
291
* @param Generator<LintError> $errors the generated errors to be displayed
269
292
* @return int the return code related to the execution of the linter
270
293
*/
271
294
private function printLinterErrors (string $ source , Generator $ errors ): int
272
295
{
273
- $ hasErrors = false ;
296
+ $ isValid = true ;
274
297
foreach ($ errors as $ error ) {
275
- if ($ hasErrors === false ) {
276
- $ this ->printLine ("\033[31m => " . $ source . " is not valid: \033[0m " . PHP_EOL );
277
- $ hasErrors = true ;
298
+ if ($ isValid === true ) {
299
+ $ isValid = false ;
278
300
}
279
- $ this ->printLine ( "\033 [31m - " . $ error . "\033 [0m " );
301
+ $ this ->formatterManager -> printLintError ( $ source , $ error );
280
302
}
281
303
282
- if ($ hasErrors ) {
283
- $ this ->printLine ("" );
284
- return self ::RETURN_CODE_ERROR ;
285
- }
304
+ $ this ->formatterManager ->endLinting ($ source , $ isValid );
286
305
287
- $ this ->printLine ("\033[32m => " . $ source . " is valid \033[0m " . PHP_EOL );
288
- return self ::RETURN_CODE_SUCCESS ;
306
+ return $ isValid ? self ::RETURN_CODE_SUCCESS : self ::RETURN_CODE_ERROR ;
289
307
}
290
308
291
309
/**
0 commit comments