Skip to content

Commit

Permalink
Merge 490f6be into 17206ac
Browse files Browse the repository at this point in the history
  • Loading branch information
pomek committed Nov 22, 2018
2 parents 17206ac + 490f6be commit 004d0a7
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 2 deletions.
41 changes: 39 additions & 2 deletions lib/commands/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ const path = require( 'upath' );
const chalk = require( 'chalk' );
const exec = require( '../utils/exec' );

module.exports = {
const command = {
/**
* @param {Object} data
* @param {String} data.packageName Name of current package to process.
* @param {Options} data.options The options object.
* @param {Repository} data.repository
* @param {Boolean} [data.doNotTryAgain=false] If set to `true`, bootstrap command won't be executed again.
* @returns {Promise}
*/
execute( data ) {
const log = require( '../utils/log' )();

const destinationPath = path.join( data.options.packages, data.repository.directory );

let promise;
Expand Down Expand Up @@ -66,6 +66,16 @@ module.exports = {
return Promise.resolve( commandOutput );
} )
.catch( error => {
if ( isRemoteHungUpError( error ) && !data.doNotTryAgain ) {
const newData = Object.assign( {}, data, {
doNotTryAgain: true
} );

return delay( 5000 ).then( () => {
return command.execute( newData );
} );
}

log.error( error );

return Promise.reject( { logs: log.all() } );
Expand All @@ -79,3 +89,30 @@ module.exports = {
console.log( chalk.cyan( `${ processedPackages.size } packages have been processed.` ) );
}
};

module.exports = command;

// See: https://github.com/cksource/mgit2/issues/87
function isRemoteHungUpError( error ) {
if ( typeof error != 'string' ) {
error = error.toString();
}

const fatalErrors = error.split( '\n' )
.filter( message => message.startsWith( 'fatal:' ) )
.map( message => message.trim() );

if ( fatalErrors.length !== 3 ) {
return false;
}

return fatalErrors[ 0 ] == 'fatal: The remote end hung up unexpectedly' &&
fatalErrors[ 1 ] == 'fatal: early EOF' &&
fatalErrors[ 2 ] == 'fatal: index-pack failed';
}

function delay( ms ) {
return new Promise( resolve => {
setTimeout( resolve, ms );
} );
}
46 changes: 46 additions & 0 deletions tests/commands/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,52 @@ describe( 'commands/bootstrap', () => {
expect( response.packages ).to.deep.equal( [ 'test-bar' ] );
} );
} );

it( 'tries to install missing packages once again if git ends with unexpected error', function() {
this.timeout( 5500 );

stubs.fs.existsSync.returns( false );

stubs.exec.onFirstCall().returns( Promise.reject( [
'exec: Cloning into \'/some/path\'...',
'remote: Enumerating objects: 6, done.',
'remote: Counting objects: 100% (6/6), done.',
'remote: Compressing objects: 100% (6/6), done.',
'packet_write_wait: Connection to 000.00.000.000 port 22: Broken pipe',
'fatal: The remote end hung up unexpectedly',
'fatal: early EOF',
'fatal: index-pack failed'
].join( '\n' ) ) );

stubs.exec.onSecondCall().returns( Promise.resolve( 'Git clone log.' ) );

return bootstrapCommand.execute( data )
.then( response => {
expect( stubs.exec.calledTwice ).to.equal( true );

const firstCommand = stubs.exec.firstCall.args[ 0 ].split( ' && ' );

// Clone the repository for the first time. It failed.
expect( firstCommand[ 0 ] )
.to.equal( 'git clone --progress "git@github.com/organization/test-package.git" "packages/test-package"' );
// Change the directory to cloned package.
expect( firstCommand[ 1 ] ).to.equal( 'cd "packages/test-package"' );
// And check out to proper branch.
expect( firstCommand[ 2 ] ).to.equal( 'git checkout --quiet master' );

const secondCommand = stubs.exec.secondCall.args[ 0 ].split( ' && ' );

// Clone the repository for the second time. It succeed.
expect( secondCommand[ 0 ] )
.to.equal( 'git clone --progress "git@github.com/organization/test-package.git" "packages/test-package"' );
// Change the directory to cloned package.
expect( secondCommand[ 1 ] ).to.equal( 'cd "packages/test-package"' );
// And check out to proper branch.
expect( secondCommand[ 2 ] ).to.equal( 'git checkout --quiet master' );

expect( response.logs.info[ 0 ] ).to.equal( 'Git clone log.' );
} );
} );
} );

describe( 'afterExecute()', () => {
Expand Down

0 comments on commit 004d0a7

Please sign in to comment.