22
33'use strict' ;
44
5- const {
6- parsePRFromURL
7- } = require ( '../lib/links' ) ;
8-
95const {
106 JobParser,
117 parseJobFromURL,
@@ -15,7 +11,7 @@ const {
1511} = require ( '../lib/ci/ci_type_parser' ) ;
1612
1713const {
18- PRBuild, BenchmarkRun, CommitBuild, listBuilds
14+ PRBuild, BenchmarkRun, CommitBuild, listBuilds, FailureAggregator
1915 // , jobCache
2016} = require ( '../lib/ci/ci_result_parser' ) ;
2117const clipboardy = require ( 'clipboardy' ) ;
@@ -26,8 +22,6 @@ const auth = require('../lib/auth');
2622const Request = require ( '../lib/request' ) ;
2723const CLI = require ( '../lib/cli' ) ;
2824const yargs = require ( 'yargs' ) ;
29- const _ = require ( 'lodash' ) ;
30- const chalk = require ( 'chalk' ) ;
3125
3226// This is used for testing
3327// Default cache dir is ${ncu-source-dir}/.ncu/cache
@@ -49,12 +43,20 @@ const argv = yargs
4943 } )
5044 . command ( {
5145 command : 'walk <type>' ,
52- desc : 'Walk the CI and store the failures' ,
46+ desc : 'Walk the CI and display the failures' ,
5347 builder : ( yargs ) => {
5448 yargs
5549 . positional ( 'type' , {
5650 describe : 'type of CI' ,
5751 choices : [ 'commit' , 'pr' ]
52+ } )
53+ . option ( 'stats' , {
54+ default : false ,
55+ describe : 'Aggregate the results'
56+ } )
57+ . option ( 'limit' , {
58+ default : 99 ,
59+ describe : 'Maximum number of CIs to get data from'
5860 } ) ;
5961 } ,
6062 handler
@@ -160,19 +162,10 @@ async function runQueue(queue, cli, request, argv) {
160162 dataToJson = dataToJson . concat ( build . formatAsJson ( ) ) ;
161163 }
162164
163- if ( argv . copy ) {
164- clipboardy . writeSync ( dataToCopy ) ;
165- cli . separator ( '' ) ;
166- cli . log ( `Written markdown to clipboard` ) ;
167- }
168-
169- if ( argv . json ) {
170- writeJson ( argv . json , dataToJson ) ;
171- cli . separator ( '' ) ;
172- cli . log ( `Written JSON to ${ argv . json } ` ) ;
173- }
174-
175- return dataToJson ;
165+ return {
166+ json : dataToJson ,
167+ copy : dataToCopy
168+ } ;
176169}
177170
178171function pad ( any , length ) {
@@ -199,55 +192,6 @@ function displayHealth(builds, cli) {
199192 cli . log ( result ) ;
200193}
201194
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-
251195async function main ( command , argv ) {
252196 const cli = new CLI ( ) ;
253197 const credentials = await auth ( {
@@ -267,7 +211,7 @@ async function main(command, argv) {
267211 const type = commandToType [ argv . type ] ;
268212 const builds = await listBuilds ( cli , request , type ) ;
269213 if ( command === 'walk' ) {
270- for ( const build of builds . failed ) {
214+ for ( const build of builds . failed . slice ( 0 , argv . limit ) ) {
271215 queue . push ( build ) ;
272216 }
273217 } else {
@@ -304,8 +248,29 @@ async function main(command, argv) {
304248
305249 if ( queue . length > 0 ) {
306250 const data = await runQueue ( queue , cli , request , argv ) ;
251+
307252 if ( command === 'walk' && argv . stats ) {
308- aggregateFailures ( cli , data ) ;
253+ const aggregator = new FailureAggregator ( cli , data . json ) ;
254+ data . json = aggregator . aggregate ( ) ;
255+ cli . log ( '' ) ;
256+ cli . separator ( 'Stats' ) ;
257+ cli . log ( '' ) ;
258+ aggregator . display ( ) ;
259+ if ( argv . copy ) {
260+ data . copy = aggregator . formatAsMarkdown ( ) ;
261+ }
262+ }
263+
264+ if ( argv . copy ) {
265+ clipboardy . writeSync ( data . copy ) ;
266+ cli . separator ( '' ) ;
267+ cli . log ( `Written markdown to clipboard` ) ;
268+ }
269+
270+ if ( argv . json ) {
271+ writeJson ( argv . json , data . json ) ;
272+ cli . separator ( '' ) ;
273+ cli . log ( `Written JSON to ${ argv . json } ` ) ;
309274 }
310275 }
311276}
0 commit comments