@@ -8,6 +8,7 @@ import chalk from "chalk-template";
88import { Parser } from "./parser.js" ;
99import axios from "axios" ;
1010import path from "path" ;
11+ import prettyHrtime from "pretty-hrtime" ;
1112import semver from "semver" ;
1213import { RE2JS } from "re2js" ;
1314
@@ -61,7 +62,7 @@ export class ParserIncludes {
6162 ) ;
6263 let includeDatas : any [ ] = [ ] ;
6364 const promises = [ ] ;
64- const { stateDir, cwd, fetchIncludes, gitData, expandVariables} = opts ;
65+ const { stateDir, cwd, fetchIncludes, gitData, expandVariables, writeStreams } = opts ;
6566 // cache the parsed component, because parseIncludeComponent is expensive and we would call it twice otherwise
6667 const componentParseCache = new Map < number , ParsedComponent > ( ) ;
6768
@@ -79,20 +80,20 @@ export class ParserIncludes {
7980 }
8081 if ( value [ "file" ] ) {
8182 for ( const fileValue of Array . isArray ( value [ "file" ] ) ? value [ "file" ] : [ value [ "file" ] ] ) {
82- promises . push ( this . downloadIncludeProjectFile ( cwd , stateDir , value [ "project" ] , value [ "ref" ] || "HEAD" , fileValue , gitData , fetchIncludes ) ) ;
83+ promises . push ( this . downloadIncludeProjectFile ( opts , value [ "project" ] , value [ "ref" ] || "HEAD" , fileValue ) ) ;
8384 }
8485 } else if ( value [ "template" ] ) {
8586 const { project, ref, file, domain} = this . covertTemplateToProjectFile ( value [ "template" ] ) ;
8687 const url = `https://${ domain } /${ project } /-/raw/${ ref } /${ file } ` ;
87- promises . push ( this . downloadIncludeRemote ( cwd , stateDir , url , fetchIncludes ) ) ;
88+ promises . push ( this . downloadIncludeRemote ( cwd , stateDir , url , fetchIncludes , writeStreams ) ) ;
8889 } else if ( value [ "remote" ] ) {
89- promises . push ( this . downloadIncludeRemote ( cwd , stateDir , value [ "remote" ] , fetchIncludes ) ) ;
90+ promises . push ( this . downloadIncludeRemote ( cwd , stateDir , value [ "remote" ] , fetchIncludes , writeStreams ) ) ;
9091 } else if ( value [ "component" ] ) {
9192 const component = this . parseIncludeComponent ( value [ "component" ] , gitData ) ;
9293 componentParseCache . set ( index , component ) ;
9394 if ( ! component . isLocal )
9495 {
95- promises . push ( this . downloadIncludeComponent ( cwd , stateDir , component . projectPath , component . ref , component . name , gitData , fetchIncludes ) ) ;
96+ promises . push ( this . downloadIncludeComponent ( opts , component . projectPath , component . ref , component . name ) ) ;
9697 }
9798 }
9899
@@ -281,28 +282,32 @@ export class ParserIncludes {
281282 return updatedIncludes ;
282283 }
283284
284- static async downloadIncludeRemote ( cwd : string , stateDir : string , url : string , fetchIncludes : boolean ) : Promise < void > {
285+ static async downloadIncludeRemote ( cwd : string , stateDir : string , url : string , fetchIncludes : boolean , writeStreams : WriteStreams ) : Promise < void > {
285286 const fsUrl = Utils . fsUrl ( url ) ;
286287 try {
287288 const target = `${ cwd } /${ stateDir } /includes/${ fsUrl } ` ;
288289 if ( await fs . pathExists ( target ) && ! fetchIncludes ) return ;
290+ const time = process . hrtime ( ) ;
289291 const res = await axios . get ( url , {
290292 headers : { "User-Agent" : "gitlab-ci-local" } ,
291293 ...Utils . getAxiosProxyConfig ( ) ,
292294 } ) ;
293295 await fs . outputFile ( target , res . data ) ;
296+ writeStreams . stderr ( chalk `{grey downloaded ${ url } in ${ prettyHrtime ( process . hrtime ( time ) ) } }\n` ) ;
294297 } catch ( e ) {
295298 throw new AssertionError ( { message : `Remote include could not be fetched ${ url } \n${ e } ` } ) ;
296299 }
297300 }
298301
299- static async downloadIncludeProjectFile ( cwd : string , stateDir : string , project : string , ref : string , file : string , gitData : GitData , fetchIncludes : boolean ) : Promise < void > {
302+ static async downloadIncludeProjectFile ( opts : ParserIncludesInitOptions , project : string , ref : string , file : string ) : Promise < void > {
303+ const { cwd, stateDir, gitData, fetchIncludes, writeStreams} = opts ;
300304 const remote = gitData . remote ;
301305 const normalizedFile = file . replace ( / ^ \/ + / , "" ) ;
302306 let tmpDir = null ;
303307 try {
304308 const target = `${ stateDir } /includes/${ remote . host } /${ project } /${ ref } ` ;
305309 if ( await fs . pathExists ( `${ cwd } /${ target } /${ normalizedFile } ` ) && ! fetchIncludes ) return ;
310+ const time = process . hrtime ( ) ;
306311
307312 if ( remote . schema . startsWith ( "http" ) ) {
308313 const ext = "tmp-" + Math . random ( ) ;
@@ -323,6 +328,7 @@ export class ParserIncludes {
323328 await fs . mkdirp ( `${ cwd } /${ target } ` ) ;
324329 await Utils . bash ( `set -eou pipefail; git archive --remote=ssh://git@${ remote . host } :${ remote . port } /${ project } .git ${ ref } ${ normalizedFile } | tar -f - -xC ${ target } /` , cwd ) ;
325330 }
331+ writeStreams . stderr ( chalk `{grey downloaded ${ project } ${ ref } ${ normalizedFile } in ${ prettyHrtime ( process . hrtime ( time ) ) } }\n` ) ;
326332 } catch ( e ) {
327333 throw new AssertionError ( { message : `Project include could not be fetched { project: ${ project } , ref: ${ ref } , file: ${ normalizedFile } }\n${ e } ` } ) ;
328334 } finally {
@@ -333,14 +339,16 @@ export class ParserIncludes {
333339 }
334340 }
335341
336- static async downloadIncludeComponent ( cwd : string , stateDir : string , project : string , ref : string , componentName : string , gitData : GitData , fetchIncludes : boolean ) : Promise < void > {
342+ static async downloadIncludeComponent ( opts : ParserIncludesInitOptions , project : string , ref : string , componentName : string ) : Promise < void > {
343+ const { cwd, stateDir, gitData, fetchIncludes, writeStreams} = opts ;
337344 const remote = gitData . remote ;
338345 const files = [ `${ componentName } .yml` , `${ componentName } /template.yml` ] ;
339346 let tmpDir = null ;
340347 try {
341348 const target = `${ stateDir } /includes/${ remote . host } /${ project } /${ ref } ` ;
342349
343350 if ( ! fetchIncludes && ( await fs . pathExists ( `${ cwd } /${ target } /${ files [ 0 ] } ` ) || await fs . pathExists ( `${ cwd } /${ target } /${ files [ 1 ] } ` ) ) ) return ;
351+ const time = process . hrtime ( ) ;
344352
345353 if ( remote . schema . startsWith ( "http" ) ) {
346354 const ext = "tmp-" + Math . random ( ) ;
@@ -367,6 +375,7 @@ export class ParserIncludes {
367375 await fs . mkdirp ( `${ cwd } /${ target } ` ) ;
368376 await Utils . bash ( `set -eou pipefail; git archive --remote=ssh://git@${ remote . host } :${ remote . port } /${ project } .git ${ ref } ${ componentWildcard } | tar -f - -xC ${ target } /` , cwd ) ;
369377 }
378+ writeStreams . stderr ( chalk `{grey downloaded ${ project } ${ ref } ${ componentName } in ${ prettyHrtime ( process . hrtime ( time ) ) } }\n` ) ;
370379 } catch ( e ) {
371380 throw new AssertionError ( { message : `Component include could not be fetched { project: ${ project } , ref: ${ ref } , file: ${ files } }\n${ e } ` } ) ;
372381 } finally {
0 commit comments