@@ -70,7 +70,11 @@ function extractThresholdBreaches(output: string): string[] {
7070 . slice ( 0 , 10 ) ;
7171}
7272
73- function extractSummary ( output : string ) : { averageCcn : number ; functionCount : number } | null {
73+ function extractSummary ( output : string ) : {
74+ averageCcn : number ;
75+ maxCcn : number ;
76+ functionCount : number ;
77+ } | null {
7478 const lines = output
7579 . split ( / \r ? \n / )
7680 . map ( ( line ) => line . trim ( ) )
@@ -89,7 +93,7 @@ function extractSummary(output: string): { averageCcn: number; functionCount: nu
8993 const avgCcn = Number ( numericParts [ 2 ] ) ;
9094 const functionCount = Number ( numericParts [ 4 ] ) ;
9195 if ( Number . isFinite ( avgCcn ) && Number . isFinite ( functionCount ) ) {
92- return { averageCcn : avgCcn , functionCount } ;
96+ return { averageCcn : avgCcn , maxCcn : avgCcn , functionCount } ;
9397 }
9498 }
9599 }
@@ -99,6 +103,7 @@ function extractSummary(output: string): { averageCcn: number; functionCount: nu
99103
100104function extractAverageFromFunctionRows ( output : string ) : {
101105 averageCcn : number ;
106+ maxCcn : number ;
102107 functionCount : number ;
103108} | null {
104109 const lines = output . split ( / \r ? \n / ) ;
@@ -125,16 +130,19 @@ function extractAverageFromFunctionRows(output: string): {
125130 }
126131
127132 const total = ccnValues . reduce ( ( sum , value ) => sum + value , 0 ) ;
133+ const maxCcn = Math . max ( ...ccnValues ) ;
128134 return {
129135 averageCcn : total / ccnValues . length ,
136+ maxCcn,
130137 functionCount : ccnValues . length ,
131138 } ;
132139}
133140
134141export async function checkComplexity (
135142 owner : string ,
136143 repo : string ,
137- threshold : number
144+ averageThreshold : number ,
145+ maxCcnThreshold : number
138146) : Promise < CheckResult > {
139147 const lizard = await detectLizardCommand ( ) ;
140148
@@ -183,7 +191,8 @@ export async function checkComplexity(
183191 } ;
184192 }
185193
186- const thresholdText = String ( Math . max ( 1 , Math . round ( threshold ) ) ) ;
194+ const averageThresholdText = String ( Math . max ( 1 , Math . round ( averageThreshold ) ) ) ;
195+ const maxCcnThresholdText = String ( Math . max ( 1 , Math . round ( maxCcnThreshold ) ) ) ;
187196 const args = [
188197 ...lizard . argsPrefix ,
189198 "-x" ,
@@ -256,46 +265,62 @@ export async function checkComplexity(
256265 }
257266
258267 const averageCcn = summary . averageCcn ;
268+ const maxCcn = summary . maxCcn ;
269+
270+ const passesAverage = averageCcn <= Number ( averageThresholdText ) ;
271+ const passesMax = maxCcn <= Number ( maxCcnThresholdText ) ;
259272
260- if ( averageCcn <= Number ( thresholdText ) ) {
273+ if ( passesAverage && passesMax ) {
261274 return {
262275 id : "complexity" ,
263276 title : "Cyclomatic complexity (Lizard)" ,
264277 description :
265278 "The repository should be analyzed with Lizard to track cyclomatic complexity across supported languages." ,
266279 status : "pass" ,
267280 message :
268- `Lizard analysis executed successfully. Average cyclomatic complexity is ${ averageCcn . toFixed (
281+ `Lizard analysis executed successfully. AvgCCN ${ averageCcn . toFixed (
269282 2
270- ) } , within threshold ${ thresholdText } .`,
283+ ) } <= ${ averageThresholdText } and MaxCCN ${ maxCcn . toFixed (
284+ 2
285+ ) } <= ${ maxCcnThresholdText } .`,
271286 evidence : [
272287 `Analyzer: ${ lizard . command } ${ lizard . argsPrefix . join ( " " ) } ` . trim ( ) ,
273288 ...( analysis . code !== 0
274289 ? [ `Lizard returned non-zero exit code ${ analysis . code } , but summary metrics were parsed.` ]
275290 : [ ] ) ,
276- `Average CCN: ${ averageCcn . toFixed ( 2 ) } (threshold: ${ thresholdText } )` ,
291+ `Average CCN: ${ averageCcn . toFixed ( 2 ) } (threshold: ${ averageThresholdText } )` ,
292+ `Max CCN: ${ maxCcn . toFixed ( 2 ) } (threshold: ${ maxCcnThresholdText } )` ,
277293 ...evidence ,
278294 ] . slice ( 0 , 10 ) ,
279295 referenceUrl : "https://github.com/terryyin/lizard" ,
280296 } ;
281297 }
282298
299+ const exceeded : string [ ] = [ ] ;
300+ if ( ! passesAverage ) {
301+ exceeded . push (
302+ `AvgCCN ${ averageCcn . toFixed ( 2 ) } > ${ averageThresholdText } `
303+ ) ;
304+ }
305+ if ( ! passesMax ) {
306+ exceeded . push ( `MaxCCN ${ maxCcn . toFixed ( 2 ) } > ${ maxCcnThresholdText } ` ) ;
307+ }
308+
283309 return {
284310 id : "complexity" ,
285311 title : "Cyclomatic complexity (Lizard)" ,
286312 description :
287313 "The repository should be analyzed with Lizard to track cyclomatic complexity across supported languages." ,
288314 status : "fail" ,
289315 message :
290- `Lizard analysis ran. Average cyclomatic complexity is ${ averageCcn . toFixed (
291- 2
292- ) } , above threshold ${ thresholdText } .`,
316+ `Lizard analysis ran. Threshold exceeded: ${ exceeded . join ( "; " ) } .` ,
293317 evidence : [
294318 `Analyzer: ${ lizard . command } ${ lizard . argsPrefix . join ( " " ) } ` . trim ( ) ,
295319 ...( analysis . code !== 0
296320 ? [ `Lizard returned non-zero exit code ${ analysis . code } , but summary metrics were parsed.` ]
297321 : [ ] ) ,
298- `Average CCN: ${ averageCcn . toFixed ( 2 ) } (threshold: ${ thresholdText } )` ,
322+ `Average CCN: ${ averageCcn . toFixed ( 2 ) } (threshold: ${ averageThresholdText } )` ,
323+ `Max CCN: ${ maxCcn . toFixed ( 2 ) } (threshold: ${ maxCcnThresholdText } )` ,
299324 ...( evidence . length > 0 ? evidence : [ "See lizard output for details." ] ) ,
300325 ] . slice ( 0 , 10 ) ,
301326 referenceUrl : "https://github.com/terryyin/lizard" ,
0 commit comments