@@ -7,6 +7,7 @@ const path = require('path');
7
7
const createDebug = require ( 'debug' ) ;
8
8
const localtunnel = require ( 'localtunnel' ) ;
9
9
const kill = require ( 'tree-kill' ) ;
10
+ const shell = require ( 'shelljs' ) ;
10
11
11
12
const config = require ( './config/config' ) . settings ;
12
13
const Coverage = require ( './coverage' ) ;
@@ -175,19 +176,6 @@ function partial(func) {
175
176
} ;
176
177
}
177
178
178
- function chain ( func ) {
179
- return function curried ( ...args ) {
180
- if ( args . length >= func . length ) {
181
- return func . apply ( this , args ) ;
182
- } else {
183
- return function ( ...args2 ) {
184
- return curried . apply ( this , args2 . concat ( args ) ) ;
185
- }
186
- }
187
- } ;
188
- }
189
-
190
-
191
179
192
180
/**
193
181
* Check if job already has record, if so, update from record and finish, otherwise call tests function.
@@ -235,6 +223,42 @@ const openTunnel = async () => {
235
223
}
236
224
237
225
226
+ /**
227
+ * Lists the submodules within a Git repository. If none are found null is returned.
228
+ * @param {String } repoPath - The path of the repository
229
+ * @returns {Array } A list of submodule names, or null if none were found
230
+ */
231
+ function listSubmodules ( repoPath ) {
232
+ if ( ! shell . which ( 'git' ) ) { throw new Error ( 'Git not found on path' ) ; }
233
+ shell . pushd ( repoPath ) ;
234
+ let listModules = 'git config --file .gitmodules --get-regexp path' ;
235
+ const modules = shell . exec ( listModules )
236
+ shell . popd ( ) ;
237
+ return ( ! modules . code && modules . stdout !== '' ) ? modules . match ( / (?< = s u b m o d u l e .) [ \w - ] + / g) : [ ] ;
238
+ }
239
+
240
+
241
+ /**
242
+ * Get the corresponding repository path for a given repo. The function first checks the settings.
243
+ * If the `repos` field doesn't exist, the path in ENV is used. If the name is not a key in the
244
+ * `repos` object then we check each repo path for submodules and return the first matching
245
+ * submodule path. Otherwise returns null.
246
+ * @param {String } name - The name of the repository
247
+ * @returns {String } The repository path if found
248
+ */
249
+ function getRepoPath ( name ) {
250
+ if ( ! config . repos ) { return process . env [ 'REPO_PATH' ] ; } // Legacy, to remove
251
+ if ( config . repos [ name ] ) { return config . repos [ name ] ; } // Found path, return
252
+ const modules = listSubmodules ( process . env [ 'REPO_PATH' ] ) ;
253
+ let repoPath = process . env [ 'REPO_PATH' ] ;
254
+ if ( modules && modules . includes ( name ) ) {
255
+ // If the repo is a submodule, modify path
256
+ repoPath += ( path . sep + name ) ;
257
+ }
258
+ return repoPath ; // No modules matched, return default
259
+ }
260
+
261
+
238
262
/**
239
263
* Starts a timer with a callback to kill the job's process.
240
264
* @param {Object } job - The Job with an associated process in the data field.
@@ -263,8 +287,9 @@ function computeCoverage(job) {
263
287
return ;
264
288
}
265
289
console . log ( 'Updating coverage for job #' + job . id )
266
- let xmlPath = path . join ( config . dataPath , 'reports' , job . data . sha , 'CoverageResults.xml' )
267
- Coverage ( xmlPath , job . data . repo , job . data . sha , obj => {
290
+ const xmlPath = path . join ( config . dataPath , 'reports' , job . data . sha , 'CoverageResults.xml' )
291
+ const modules = listSubmodules ( process . env . REPO_PATH ) ;
292
+ Coverage ( xmlPath , job . data . repo , job . data . sha , modules , obj => {
268
293
// Digest and save percentage coverage
269
294
let misses = 0 , hits = 0 ;
270
295
for ( let file of obj . source_files ) {
@@ -388,7 +413,7 @@ function getBadgeData(data) {
388
413
report [ 'color' ] = 'orange' ;
389
414
// Check test isn't already on the pile
390
415
let onPile = false ;
391
- for ( let job of queue . pile ) { if ( job . id === id ) { onPile = true ; break ; } }
416
+ for ( let job of queue . pile ) { if ( job . data . sha === id ) { onPile = true ; break ; } }
392
417
if ( ! onPile ) { // Add test to queue
393
418
data [ 'skipPost' ] = true
394
419
queue . add ( data ) ;
@@ -397,7 +422,7 @@ function getBadgeData(data) {
397
422
record = Array . isArray ( record ) ? record . pop ( ) : record ; // in case of duplicates, take last
398
423
switch ( data . context ) {
399
424
case 'status' :
400
- if ( record [ 'status' ] === 'error' || ! record [ 'coverage' ] ) {
425
+ if ( record [ 'status' ] === 'error' ) {
401
426
report [ 'message' ] = 'unknown' ;
402
427
report [ 'color' ] = 'orange' ;
403
428
} else {
@@ -433,5 +458,5 @@ class APIError extends Error {
433
458
module . exports = {
434
459
ensureArray, loadTestRecords, compareCoverage, computeCoverage, getBadgeData, log, shortID,
435
460
openTunnel, APIError, queue, partial, startJobTimer, updateJobFromRecord, shortCircuit, isSHA,
436
- fullpath, strToBool, saveTestRecords
461
+ fullpath, strToBool, saveTestRecords, listSubmodules , getRepoPath
437
462
}
0 commit comments