22
33'use strict' ;
44
5+ const {
6+ parsePRFromURL
7+ } = require ( '../lib/links' ) ;
8+
59const {
610 JobParser,
711 parseJobFromURL,
@@ -12,7 +16,7 @@ const {
1216
1317const {
1418 PRBuild, BenchmarkRun, CommitBuild, listBuilds
15- // , jobCache
19+ , jobCache
1620} = require ( '../lib/ci/ci_result_parser' ) ;
1721const clipboardy = require ( 'clipboardy' ) ;
1822const { writeJson } = require ( '../lib/file' ) ;
@@ -22,10 +26,12 @@ const auth = require('../lib/auth');
2226const Request = require ( '../lib/request' ) ;
2327const CLI = require ( '../lib/cli' ) ;
2428const yargs = require ( 'yargs' ) ;
29+ const _ = require ( 'lodash' ) ;
30+ const chalk = require ( 'chalk' ) ;
2531
2632// This is used for testing
2733// Default cache dir is ${ncu-source-dir}/.ncu/cache
28- // jobCache.enable();
34+ jobCache . enable ( ) ;
2935
3036// eslint-disable-next-line no-unused-vars
3137const argv = yargs
@@ -151,9 +157,7 @@ async function runQueue(queue, cli, request, argv) {
151157 dataToCopy += build . formatAsMarkdown ( ) ;
152158 }
153159
154- if ( argv . json ) {
155- dataToJson = dataToJson . concat ( build . formatAsJson ( ) ) ;
156- }
160+ dataToJson = dataToJson . concat ( build . formatAsJson ( ) ) ;
157161 }
158162
159163 if ( argv . copy ) {
@@ -167,6 +171,8 @@ async function runQueue(queue, cli, request, argv) {
167171 cli . separator ( '' ) ;
168172 cli . log ( `Written JSON to ${ argv . json } ` ) ;
169173 }
174+
175+ return dataToJson ;
170176}
171177
172178function pad ( any , length ) {
@@ -193,6 +199,55 @@ function displayHealth(builds, cli) {
193199 cli . log ( result ) ;
194200}
195201
202+ function getHighlight ( f ) {
203+ return f . reason . split ( '\n' ) [ f . highlight ]
204+ . replace ( / n o t o k \d + / , '' )
205+ . replace (
206+ / ' J N L P 4 - c o n n e c t c o n n e c t i o n f r o m .+ ?' / , 'JNLP4-connect connection from ...'
207+ )
208+ . replace ( / F A T A L : C o u l d n o t c h e c k o u t \w + / , 'FATAL: Could not checkout ...' ) ;
209+ }
210+
211+ function aggregateFailures ( cli , failures ) {
212+ const grouped = _ . chain ( failures )
213+ . groupBy ( getHighlight )
214+ . toPairs ( )
215+ . sortBy ( )
216+ . value ( ) ;
217+ let results = [ ] ;
218+ for ( const item of grouped ) {
219+ const [ key , failures ] = item ;
220+ const cleaned = _ . chain ( failures )
221+ . uniqBy ( 'source' )
222+ . sortBy ( ( f ) => parseJobFromURL ( f . upstream ) . jobid )
223+ . value ( ) ;
224+ results . push ( [ key , failures , cleaned ] ) ;
225+ } ;
226+
227+ results = _ . sortBy ( results , r => 0 - ( r [ 2 ] . length ) ) ;
228+
229+ cli . separator ( chalk . bold ( 'Stats' ) ) ;
230+ for ( const item of results ) {
231+ const [ key , failures , cleaned ] = item ;
232+ const machines = _ . uniq ( failures . map ( f => f . builtOn ) ) . join ( ', ' ) ;
233+ cli . table ( 'Reason' , key ) ;
234+ cli . table ( 'Type' , failures [ 0 ] . type ) ;
235+ const prs = cleaned
236+ . map ( f => {
237+ const parsed = parsePRFromURL ( f . source ) ;
238+ return parsed ? `#${ parsed . prid } ` : f . source ;
239+ } )
240+ . join ( ', ' ) ;
241+ cli . table ( 'Failed PR' , `${ cleaned . length } (${ prs } )` ) ;
242+ cli . table ( 'Appeared' , machines ) ;
243+ if ( cleaned . length > 1 ) {
244+ cli . table ( 'First CI' , `${ cleaned [ 0 ] . upstream } ` ) ;
245+ }
246+ cli . table ( 'Last CI' , `${ cleaned [ cleaned . length - 1 ] . upstream } ` ) ;
247+ cli . separator ( ) ;
248+ }
249+ }
250+
196251async function main ( command , argv ) {
197252 const cli = new CLI ( ) ;
198253 const credentials = await auth ( {
@@ -248,7 +303,10 @@ async function main(command, argv) {
248303 }
249304
250305 if ( queue . length > 0 ) {
251- await runQueue ( queue , cli , request , argv ) ;
306+ const data = await runQueue ( queue , cli , request , argv ) ;
307+ if ( command === 'walk' && argv . stats ) {
308+ aggregateFailures ( cli , data ) ;
309+ }
252310 }
253311}
254312
0 commit comments