@@ -35,7 +35,9 @@ component extends="commandbox.system.BaseCommand" excludeFromHelp=false {
3535 " engines" ,
3636 " includeScanners" ,
3737 " configFile" ,
38- " goals"
38+ " goals" ,
39+ " json" ,
40+ " forceLocal"
3941 ];
4042
4143 /**
@@ -63,6 +65,8 @@ component extends="commandbox.system.BaseCommand" excludeFromHelp=false {
6365 * @configFile.hint A path to a .fixinator.json file to use
6466 * @goals.hint A list of goals for scanning [compatibility,security], default: security
6567 * @goals.optionsUDF goalsComplete
68+ * @json.hint When true outputs results to the console as JSON
69+ * @forceLocal.hint When true requires that the scan run locally with enterprise version
6670 **/
6771 function run (
6872 string path = " ." ,
@@ -84,7 +88,9 @@ component extends="commandbox.system.BaseCommand" excludeFromHelp=false {
8488 string engines = " " ,
8589 string includeScanners = " " ,
8690 string configFile = " " ,
87- string goals = " security"
91+ string goals = " security" ,
92+ boolean json = false ,
93+ boolean forceLocal = false
8894 ) {
8995 var fileInfo = " " ;
9096 var severityLevel = 1 ;
@@ -94,6 +100,9 @@ component extends="commandbox.system.BaseCommand" excludeFromHelp=false {
94100 var paths = [];
95101 var isEnterprise = false ;
96102 var arg = " " ;
103+ if (arguments .json ) {
104+ arguments .verbose = false ;
105+ }
97106 if (arguments .verbose ) {
98107 // arguments.listScanners = true;
99108
@@ -121,6 +130,18 @@ component extends="commandbox.system.BaseCommand" excludeFromHelp=false {
121130 isEnterprise = true ;
122131 } catch (any entErr ) {
123132 // not using enterprise version
133+ if (! arguments .forceLocal ) {
134+ rethrow ;
135+ }
136+ }
137+
138+ if (arguments .forceLocal ) {
139+ fixinatorClient .setForceLocal (true );
140+ if (! isEnterprise ) {
141+ error (" Enterprise version was not loaded and forceLocal was specified" );
142+ setExitCode (1 );
143+ return ;
144+ }
124145 }
125146
126147 // validate arguments
@@ -201,7 +222,7 @@ component extends="commandbox.system.BaseCommand" excludeFromHelp=false {
201222 fixinatorClient .setAPIURL (configService .getSetting (" modules.fixinator.api_url" , " UNDEFINED" ));
202223 }
203224
204- if (! fixinatorClient .hasFixinatorEnterpriseInstance () && fixinatorClient .isCloudAPIURL () && configService .getSetting (" modules.fixinator.accept_policy" , " UNDEFINED" ) == " UNDEFINED" ) {
225+ if (! fixinatorClient .hasFixinatorEnterpriseInstance () && fixinatorClient .isCloudAPIURL () && configService .getSetting (" modules.fixinator.accept_policy" , " UNDEFINED" ) == " UNDEFINED" && ! arguments . json ) {
205226 print .line ();
206227 print .line (" Fixinator will send source code to: " & fixinatorClient .getAPIURL ());
207228 print .line (" for scanning. The code is kept in RAM during scanning and is not persisted." );
@@ -264,8 +285,10 @@ component extends="commandbox.system.BaseCommand" excludeFromHelp=false {
264285
265286 if (arguments .debug ) {
266287 fixinatorClient .setDebugMode (true );
267- print .greenLine (" ✓ DEBUG MODE ENABLED: #fixinatorClient .isDebugModeEnabled () #" );
268- print .greenLine (" ↳ #expandPath (" {lucee-web}/logs/fixinator-client-debug.log" ) #" );
288+ if (arguments .verbose ) {
289+ print .greenLine (" ✓ DEBUG MODE ENABLED: #fixinatorClient .isDebugModeEnabled () #" );
290+ print .greenLine (" ↳ #expandPath (" {lucee-web}/logs/fixinator-client-debug.log" ) #" );
291+ }
269292 }
270293
271294
@@ -278,7 +301,7 @@ component extends="commandbox.system.BaseCommand" excludeFromHelp=false {
278301 try {
279302 if (arguments .gitLastCommit && arguments .verbose ) {
280303 print .yellowLine (" Scanning only files changed in the last git commit." );
281- } else {
304+ } else if ( arguments . verbose ) {
282305 print .yellowLine (" Scanning only files changed since the last git commit." );
283306 }
284307 arguments .path = fileSystemUtil .resolvePath ( arguments .path );
@@ -371,7 +394,7 @@ component extends="commandbox.system.BaseCommand" excludeFromHelp=false {
371394
372395 if (! listFindNoCase (" warn,low,medium,high" , arguments .severity )) {
373396 if (arguments .severity ! = " default" ) {
374- print . redLine (" Invalid minimum severity level, use: warn,low,medium,high" );
397+ error (" Invalid minimum severity level, use: warn,low,medium,high" );
375398 return ;
376399 }
377400 } else {
@@ -380,7 +403,7 @@ component extends="commandbox.system.BaseCommand" excludeFromHelp=false {
380403
381404 if (! listFindNoCase (" none,low,medium,high" , arguments .confidence )) {
382405 if (arguments .confidence ! = " default" ) {
383- print . redLine (" Invalid minimum confidence level, use: none,low,medium,high" );
406+ error (" Invalid minimum confidence level, use: none,low,medium,high" );
384407 return ;
385408 }
386409
@@ -410,22 +433,22 @@ component extends="commandbox.system.BaseCommand" excludeFromHelp=false {
410433 if (len (arguments .configFile )) {
411434 arguments .configFile = fileSystemUtil .resolvePath ( arguments .configFile );
412435 if (! fileExists (arguments .configFile )) {
413- print . boldRedLine (" Sorry: configFile was not found: #arguments .configFile #" );
436+ error (" Sorry: configFile was not found: #arguments .configFile #" );
414437 return ;
415438 } else {
416439 config .configFile = arguments .configFile ;
417440 }
418441 }
419442
420443 if (! fileExists (arguments .path ) && ! directoryExists (arguments .path ) && ! arrayLen (paths )) {
421- print . boldRedLine (" Sorry: #arguments .path # is not a file or directory." );
444+ error (" Sorry: #arguments .path # is not a file or directory." );
422445 return ;
423446 }
424447
425448 fileInfo = getFileInfo (arguments .path );
426449
427450 if (! fileInfo .canRead ) {
428- print . boldRedLine (" Sorry: No read permission for source path" );
451+ error (" Sorry: No read permission for source path" );
429452 return ;
430453 }
431454
@@ -534,6 +557,15 @@ component extends="commandbox.system.BaseCommand" excludeFromHelp=false {
534557 }
535558 }
536559
560+ if (arguments .json ) {
561+ print .line (serializeJSON (local .results ));
562+ if (arrayLen (local .results .results ) > 0 ) {
563+ if (arguments .failOnIssues ) {
564+ setExitCode ( 1 );
565+ }
566+ }
567+ return ;
568+ }
537569
538570 if (arrayLen (local .results .results ) == 0 && arrayLen (local .results .warnings ) == 0 ) {
539571 print .line ().boldGreenLine (" 0 Issues Found" );
0 commit comments