@@ -13542,14 +13542,14 @@ const util = __webpack_require__(669);
13542
13542
const glob = __webpack_require__ ( 294 ) ;
13543
13543
const parseString = util . promisify ( xml2js . parseString ) ;
13544
13544
13545
- async function processCoverage ( path , options ) {
13546
- options = options || { skipCovered : false } ;
13547
-
13548
- if ( glob . hasMagic ( path ) ) {
13549
- const paths = await glob ( path ) ;
13550
- path = paths [ 0 ] ;
13551
- }
13552
-
13545
+ /**
13546
+ * generate the report for the given file
13547
+ *
13548
+ * @param path: string
13549
+ * @param options: object
13550
+ * @return { Promise<{total: number, line: number, files: T[], branch: number}> }
13551
+ */
13552
+ async function readCoverageFromFile ( path , options ) {
13553
13553
const xml = await fs . readFile ( path , "utf-8" ) ;
13554
13554
const { coverage } = await parseString ( xml , {
13555
13555
explicitArray : false ,
@@ -13574,6 +13574,40 @@ async function processCoverage(path, options) {
13574
13574
} ;
13575
13575
}
13576
13576
13577
+ function trimFolder ( path , positionOfFirstDiff ) {
13578
+ const lastFolder = path . lastIndexOf ( "/" ) + 1 ;
13579
+ if ( positionOfFirstDiff >= lastFolder ) {
13580
+ return path . substr ( lastFolder ) ;
13581
+ } else {
13582
+ const startOffset = Math . min ( positionOfFirstDiff - 1 , lastFolder ) ;
13583
+ const length = path . length - startOffset - lastFolder - 2 ; // remove filename
13584
+ return path . substr ( startOffset , length ) ;
13585
+ }
13586
+ }
13587
+
13588
+ /**
13589
+ *
13590
+ * @param path: string
13591
+ * @param options: { }
13592
+ * @returns {Promise<{total: number, folder: string, line: number, files: T[], branch: number}[]> }
13593
+ */
13594
+ async function processCoverage ( path , options ) {
13595
+ options = options || { skipCovered : false } ;
13596
+
13597
+ const paths = glob . hasMagic ( path ) ? await glob ( path ) : [ path ] ;
13598
+ const positionOfFirstDiff = longestCommonPrefix ( paths ) ;
13599
+ return await Promise . all (
13600
+ paths . map ( async ( path ) => {
13601
+ const report = await readCoverageFromFile ( path , options ) ;
13602
+ const folder = trimFolder ( path , positionOfFirstDiff ) ;
13603
+ return {
13604
+ ...report ,
13605
+ folder,
13606
+ } ;
13607
+ } )
13608
+ ) ;
13609
+ }
13610
+
13577
13611
function processPackages ( packages ) {
13578
13612
if ( packages . package instanceof Array ) {
13579
13613
return packages . package . map ( ( p ) => processPackage ( p ) ) . flat ( ) ;
@@ -13596,6 +13630,12 @@ function processPackage(packageObj) {
13596
13630
}
13597
13631
}
13598
13632
13633
+ /**
13634
+ * returns coverage rates
13635
+ *
13636
+ * @param element: object
13637
+ * @returns {{total: number, line: number, branch: number} }
13638
+ */
13599
13639
function calculateRates ( element ) {
13600
13640
const line = parseFloat ( element [ "line-rate" ] ) * 100 ;
13601
13641
const branch = parseFloat ( element [ "branch-rate" ] ) * 100 ;
@@ -13645,7 +13685,7 @@ function formatLines(statements, lines) {
13645
13685
const ranges = [ ] ;
13646
13686
let start = null ;
13647
13687
let linesCursor = 0 ;
13648
- let end = null ;
13688
+ let end ;
13649
13689
for ( const statement of statements ) {
13650
13690
if ( linesCursor >= lines . length ) break ;
13651
13691
@@ -13674,8 +13714,32 @@ function formatLines(statements, lines) {
13674
13714
. join ( ", " ) ;
13675
13715
}
13676
13716
13717
+ /**
13718
+ *
13719
+ * @param paths: [string]
13720
+ * @returns number
13721
+ */
13722
+ function longestCommonPrefix ( paths ) {
13723
+ let prefix = "" ;
13724
+ if ( paths === null || paths . length === 0 ) return 0 ;
13725
+
13726
+ for ( let i = 0 ; i < paths [ 0 ] . length ; i ++ ) {
13727
+ const char = paths [ 0 ] [ i ] ; // loop through all characters of the very first string.
13728
+
13729
+ for ( let j = 1 ; j < paths . length ; j ++ ) {
13730
+ // loop through all other strings in the array
13731
+ if ( paths [ j ] [ i ] !== char ) return prefix . length ;
13732
+ }
13733
+ prefix = prefix + char ;
13734
+ }
13735
+
13736
+ return prefix . length ;
13737
+ }
13738
+
13677
13739
module . exports = {
13678
13740
processCoverage,
13741
+ trimFolder,
13742
+ longestCommonPrefix,
13679
13743
} ;
13680
13744
13681
13745
@@ -15906,8 +15970,8 @@ async function action(payload) {
15906
15970
? await listChangedFiles ( pullRequestNumber )
15907
15971
: null ;
15908
15972
15909
- const report = await processCoverage ( path , { skipCovered } ) ;
15910
- const comment = markdownReport ( report , commit , {
15973
+ const reports = await processCoverage ( path , { skipCovered } ) ;
15974
+ const comment = markdownReport ( reports , commit , {
15911
15975
minimumCoverage,
15912
15976
showLine,
15913
15977
showBranch,
@@ -15920,7 +15984,7 @@ async function action(payload) {
15920
15984
await addComment ( pullRequestNumber , comment , reportName ) ;
15921
15985
}
15922
15986
15923
- function markdownReport ( report , commit , options ) {
15987
+ function markdownReport ( reports , commit , options ) {
15924
15988
const {
15925
15989
minimumCoverage = 100 ,
15926
15990
showLine = false ,
@@ -15937,74 +16001,81 @@ function markdownReport(report, commit, options) {
15937
16001
str . length > at ? str . slice ( 0 , at ) . concat ( "..." ) : str ;
15938
16002
// Setup files
15939
16003
const files = [ ] ;
15940
- for ( const file of report . files . filter (
15941
- ( file ) => filteredFiles == null || filteredFiles . includes ( file . filename )
15942
- ) ) {
15943
- const fileTotal = Math . round ( file . total ) ;
15944
- const fileLines = Math . round ( file . line ) ;
15945
- const fileBranch = Math . round ( file . branch ) ;
15946
- const fileMissing =
15947
- showMissingMaxLength > 0
15948
- ? crop ( file . missing , showMissingMaxLength )
15949
- : file . missing ;
15950
- files . push ( [
15951
- escapeMarkdown ( showClassNames ? file . name : file . filename ) ,
15952
- `\`${ fileTotal } %\`` ,
15953
- showLine ? `\`${ fileLines } %\`` : undefined ,
15954
- showBranch ? `\`${ fileBranch } %\`` : undefined ,
15955
- status ( fileTotal ) ,
15956
- showMissing ? ( fileMissing ? `\`${ fileMissing } \`` : " " ) : undefined ,
15957
- ] ) ;
15958
- }
15959
- // Construct table
15960
- /*
15961
- | File | Coverage | |
15962
- |---------------|:--------:|:------------------:|
15963
- | **All files** | `78%` | :x: |
15964
- | foo.py | `80%` | :white_check_mark: |
15965
- | bar.py | `75%` | :x: |
15966
-
15967
- _Minimum allowed coverage is `80%`_
15968
- */
15969
-
15970
- const total = Math . round ( report . total ) ;
15971
- const linesTotal = Math . round ( report . line ) ;
15972
- const branchTotal = Math . round ( report . branch ) ;
15973
- const table = [
15974
- [
15975
- "File" ,
15976
- "Coverage" ,
15977
- showLine ? "Lines" : undefined ,
15978
- showBranch ? "Branches" : undefined ,
15979
- " " ,
15980
- showMissing ? "Missing" : undefined ,
15981
- ] ,
15982
- [
15983
- "-" ,
15984
- ":-:" ,
15985
- showLine ? ":-:" : undefined ,
15986
- showBranch ? ":-:" : undefined ,
15987
- ":-:" ,
15988
- showMissing ? ":-:" : undefined ,
15989
- ] ,
15990
- [
15991
- "**All files**" ,
15992
- `\`${ total } %\`` ,
15993
- showLine ? `\`${ linesTotal } %\`` : undefined ,
15994
- showBranch ? `\`${ branchTotal } %\`` : undefined ,
15995
- status ( total ) ,
15996
- showMissing ? " " : undefined ,
15997
- ] ,
15998
- ...files ,
15999
- ]
16000
- . map ( ( row ) => {
16001
- return `| ${ row . filter ( Boolean ) . join ( " | " ) } |` ;
16002
- } )
16003
- . join ( "\n" ) ;
16004
+ let output = "" ;
16005
+ for ( const report of reports ) {
16006
+ const folder = reports . length <= 1 ? "" : ` ${ report . folder } ` ;
16007
+ for ( const file of report . files . filter (
16008
+ ( file ) => filteredFiles == null || filteredFiles . includes ( file . filename )
16009
+ ) ) {
16010
+ const fileTotal = Math . round ( file . total ) ;
16011
+ const fileLines = Math . round ( file . line ) ;
16012
+ const fileBranch = Math . round ( file . branch ) ;
16013
+ const fileMissing =
16014
+ showMissingMaxLength > 0
16015
+ ? crop ( file . missing , showMissingMaxLength )
16016
+ : file . missing ;
16017
+ files . push ( [
16018
+ escapeMarkdown ( showClassNames ? file . name : file . filename ) ,
16019
+ `\`${ fileTotal } %\`` ,
16020
+ showLine ? `\`${ fileLines } %\`` : undefined ,
16021
+ showBranch ? `\`${ fileBranch } %\`` : undefined ,
16022
+ status ( fileTotal ) ,
16023
+ showMissing ? ( fileMissing ? `\`${ fileMissing } \`` : " " ) : undefined ,
16024
+ ] ) ;
16025
+ }
16026
+
16027
+ // Construct table
16028
+ /*
16029
+ | File | Coverage | |
16030
+ |---------------|:--------:|:------------------:|
16031
+ | **All files** | `78%` | :x: |
16032
+ | foo.py | `80%` | :white_check_mark: |
16033
+ | bar.py | `75%` | :x: |
16034
+
16035
+ _Minimum allowed coverage is `80%`_
16036
+ */
16037
+
16038
+ const total = Math . round ( report . total ) ;
16039
+ const linesTotal = Math . round ( report . line ) ;
16040
+ const branchTotal = Math . round ( report . branch ) ;
16041
+ const table = [
16042
+ [
16043
+ "File" ,
16044
+ "Coverage" ,
16045
+ showLine ? "Lines" : undefined ,
16046
+ showBranch ? "Branches" : undefined ,
16047
+ " " ,
16048
+ showMissing ? "Missing" : undefined ,
16049
+ ] ,
16050
+ [
16051
+ "-" ,
16052
+ ":-:" ,
16053
+ showLine ? ":-:" : undefined ,
16054
+ showBranch ? ":-:" : undefined ,
16055
+ ":-:" ,
16056
+ showMissing ? ":-:" : undefined ,
16057
+ ] ,
16058
+ [
16059
+ "**All files**" ,
16060
+ `\`${ total } %\`` ,
16061
+ showLine ? `\`${ linesTotal } %\`` : undefined ,
16062
+ showBranch ? `\`${ branchTotal } %\`` : undefined ,
16063
+ status ( total ) ,
16064
+ showMissing ? " " : undefined ,
16065
+ ] ,
16066
+ ...files ,
16067
+ ]
16068
+ . map ( ( row ) => {
16069
+ return `| ${ row . filter ( Boolean ) . join ( " | " ) } |` ;
16070
+ } )
16071
+ . join ( "\n" ) ;
16072
+ const titleText = `<strong>${ reportName } ${ folder } </strong>` ;
16073
+ output += `${ titleText } \n\n${ table } \n\n` ;
16074
+ }
16004
16075
const minimumCoverageText = `_Minimum allowed coverage is \`${ minimumCoverage } %\`_` ;
16005
16076
const footerText = `<p align="right">${ credits } against ${ commit } </p>` ;
16006
- const titleText = `<strong> ${ reportName } </strong> ` ;
16007
- return ` ${ titleText } \n\n ${ table } \n\n ${ minimumCoverageText } \n\n ${ footerText } ` ;
16077
+ output + = `${ minimumCoverageText } \n\n ${ footerText } ` ;
16078
+ return output ;
16008
16079
}
16009
16080
16010
16081
async function addComment ( pullRequestNumber , body , reportName ) {
@@ -16066,7 +16137,7 @@ async function pullRequestInfo(payload = {}) {
16066
16137
state : "open" ,
16067
16138
} ) ;
16068
16139
pullRequestNumber = data
16069
- . filter ( ( d ) => d . head . sha == commit )
16140
+ . filter ( ( d ) => d . head . sha === commit )
16070
16141
. reduce ( ( n , d ) => d . number , "" ) ;
16071
16142
} else if ( payload . pull_request ) {
16072
16143
// try to find the PR from payload
0 commit comments