@@ -53,36 +53,23 @@ if (repoURLMatch?.groups == null) {
53
53
}
54
54
const { githubOrg, githubRepo } = repoURLMatch . groups ;
55
55
56
- getChangeLog ( )
57
- . then ( ( changelog ) => process . stdout . write ( changelog ) )
58
- . catch ( ( error ) => {
59
- console . error ( error ) ;
60
- process . exit ( 1 ) ;
61
- } ) ;
56
+ process . stdout . write ( await genChangeLog ( ) ) ;
62
57
63
- function getChangeLog ( ) : Promise < string > {
58
+ async function genChangeLog ( ) : Promise < string > {
64
59
const { version } = packageJSON ;
65
60
66
61
let tag : string | null = null ;
67
62
let commitsList = git ( ) . revList ( '--reverse' , `v${ version } ..` ) ;
68
- if ( commitsList === '' ) {
63
+ if ( commitsList . length === 0 ) {
69
64
const parentPackageJSON = git ( ) . catFile ( 'blob' , 'HEAD~1:package.json' ) ;
70
65
const parentVersion = JSON . parse ( parentPackageJSON ) . version ;
71
66
commitsList = git ( ) . revList ( '--reverse' , `v${ parentVersion } ..HEAD~1` ) ;
72
67
tag = `v${ version } ` ;
73
68
}
74
69
70
+ const allPRs = await getPRsInfo ( commitsList ) ;
75
71
const date = git ( ) . log ( '-1' , '--format=%cd' , '--date=short' ) ;
76
- return getCommitsInfo ( commitsList . split ( '\n' ) )
77
- . then ( ( commitsInfo ) => getPRsInfo ( commitsInfoToPRs ( commitsInfo ) ) )
78
- . then ( ( prsInfo ) => genChangeLog ( tag , date , prsInfo ) ) ;
79
- }
80
72
81
- function genChangeLog (
82
- tag : string | null ,
83
- date : string ,
84
- allPRs : ReadonlyArray < PRInfo > ,
85
- ) : string {
86
73
const byLabel : { [ label : string ] : Array < PRInfo > } = { } ;
87
74
const committersByLogin : { [ login : string ] : AuthorInfo } = { } ;
88
75
@@ -181,9 +168,9 @@ interface CommitInfo {
181
168
} ;
182
169
}
183
170
184
- async function batchCommitInfo (
171
+ async function batchCommitToPR (
185
172
commits : ReadonlyArray < string > ,
186
- ) : Promise < Array < CommitInfo > > {
173
+ ) : Promise < ReadonlyArray < number > > {
187
174
let commitsSubQuery = '' ;
188
175
for ( const oid of commits ) {
189
176
commitsSubQuery += `
@@ -212,11 +199,12 @@ async function batchCommitInfo(
212
199
}
213
200
` ) ;
214
201
215
- const commitsInfo = [ ] ;
202
+ const prNumbers = [ ] ;
216
203
for ( const oid of commits ) {
217
- commitsInfo . push ( response . repository [ 'commit_' + oid ] ) ;
204
+ const commitInfo : CommitInfo = response . repository [ 'commit_' + oid ] ;
205
+ prNumbers . push ( commitInfoToPR ( commitInfo ) ) ;
218
206
}
219
- return commitsInfo ;
207
+ return prNumbers ;
220
208
}
221
209
222
210
interface AuthorInfo {
@@ -237,7 +225,9 @@ interface PRInfo {
237
225
} ;
238
226
}
239
227
240
- async function batchPRInfo ( prNumbers : Array < number > ) : Promise < Array < PRInfo > > {
228
+ async function batchPRInfo (
229
+ prNumbers : ReadonlyArray < number > ,
230
+ ) : Promise < Array < PRInfo > > {
241
231
let prsSubQuery = '' ;
242
232
for ( const number of prNumbers ) {
243
233
prsSubQuery += `
@@ -276,56 +266,47 @@ async function batchPRInfo(prNumbers: Array<number>): Promise<Array<PRInfo>> {
276
266
return prsInfo ;
277
267
}
278
268
279
- function commitsInfoToPRs ( commits : ReadonlyArray < CommitInfo > ) : Array < number > {
280
- const prNumbers = new Set < number > ( ) ;
281
- for ( const commit of commits ) {
282
- const associatedPRs = commit . associatedPullRequests . nodes . filter (
283
- ( pr ) => pr . repository . nameWithOwner === `${ githubOrg } /${ githubRepo } ` ,
284
- ) ;
285
- if ( associatedPRs . length === 0 ) {
286
- const match = / \( # (?< prNumber > [ 0 - 9 ] + ) \) $ / m. exec ( commit . message ) ;
287
- if ( match ?. groups ?. prNumber != null ) {
288
- prNumbers . add ( parseInt ( match . groups . prNumber , 10 ) ) ;
289
- continue ;
290
- }
291
- throw new Error (
292
- `Commit ${ commit . oid } has no associated PR: ${ commit . message } ` ,
293
- ) ;
294
- }
295
- if ( associatedPRs . length > 1 ) {
296
- throw new Error (
297
- `Commit ${ commit . oid } is associated with multiple PRs: ${ commit . message } ` ,
298
- ) ;
269
+ function commitInfoToPR ( commit : CommitInfo ) : number {
270
+ const associatedPRs = commit . associatedPullRequests . nodes . filter (
271
+ ( pr ) => pr . repository . nameWithOwner === `${ githubOrg } /${ githubRepo } ` ,
272
+ ) ;
273
+ if ( associatedPRs . length === 0 ) {
274
+ const match = / \( # (?< prNumber > [ 0 - 9 ] + ) \) $ / m. exec ( commit . message ) ;
275
+ if ( match ?. groups ?. prNumber != null ) {
276
+ return parseInt ( match . groups . prNumber , 10 ) ;
299
277
}
300
-
301
- prNumbers . add ( associatedPRs [ 0 ] . number ) ;
278
+ throw new Error (
279
+ `Commit ${ commit . oid } has no associated PR: ${ commit . message } ` ,
280
+ ) ;
281
+ }
282
+ if ( associatedPRs . length > 1 ) {
283
+ throw new Error (
284
+ `Commit ${ commit . oid } is associated with multiple PRs: ${ commit . message } ` ,
285
+ ) ;
302
286
}
303
287
304
- return [ ... prNumbers . values ( ) ] ;
288
+ return associatedPRs [ 0 ] . number ;
305
289
}
306
290
307
291
async function getPRsInfo (
308
- prNumbers : ReadonlyArray < number > ,
309
- ) : Promise < Array < PRInfo > > {
310
- // Split pr into batches of 50 to prevent timeouts
311
- const prInfoPromises = [ ] ;
312
- for ( let i = 0 ; i < prNumbers . length ; i += 50 ) {
313
- const batch = prNumbers . slice ( i , i + 50 ) ;
314
- prInfoPromises . push ( batchPRInfo ( batch ) ) ;
315
- }
292
+ commits : ReadonlyArray < string > ,
293
+ ) : Promise < ReadonlyArray < PRInfo > > {
294
+ let prNumbers = await splitBatches ( commits , batchCommitToPR ) ;
295
+ prNumbers = Array . from ( new Set ( prNumbers ) ) ; // Remove duplicates
316
296
317
- return ( await Promise . all ( prInfoPromises ) ) . flat ( ) ;
297
+ return splitBatches ( prNumbers , batchPRInfo ) ;
318
298
}
319
299
320
- async function getCommitsInfo (
321
- commits : ReadonlyArray < string > ,
322
- ) : Promise < Array < CommitInfo > > {
323
- // Split commits into batches of 50 to prevent timeouts
324
- const commitInfoPromises = [ ] ;
325
- for ( let i = 0 ; i < commits . length ; i += 50 ) {
326
- const batch = commits . slice ( i , i + 50 ) ;
327
- commitInfoPromises . push ( batchCommitInfo ( batch ) ) ;
300
+ // Split commits into batches of 50 to prevent timeouts
301
+ async function splitBatches < I , R > (
302
+ array : ReadonlyArray < I > ,
303
+ batchFn : ( array : ReadonlyArray < I > ) => Promise < ReadonlyArray < R > > ,
304
+ ) : Promise < ReadonlyArray < R > > {
305
+ const promises = [ ] ;
306
+ for ( let i = 0 ; i < array . length ; i += 50 ) {
307
+ const batchItems = array . slice ( i , i + 50 ) ;
308
+ promises . push ( batchFn ( batchItems ) ) ;
328
309
}
329
310
330
- return ( await Promise . all ( commitInfoPromises ) ) . flat ( ) ;
311
+ return ( await Promise . all ( promises ) ) . flat ( ) ;
331
312
}
0 commit comments