Skip to content

Commit

Permalink
Merge pull request #38 from cksource/t/27
Browse files Browse the repository at this point in the history
Feature: Introduced "save-hashes" command for saving hashes of the packages. Resolves: #27.
  • Loading branch information
Reinmar authored Jan 31, 2017
2 parents 5223baf + 7b42bfd commit 17e6c67
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 10 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,17 @@ mgit exec 'echo `pwd`'
# /home/mgit/packages/organization/repository-2
```


### save-hashes

Saves hashes of packages in `mgit.json`. It allows to easily fix project to a specific state.

Example:

```bash
mgit save-hashes
```

## Projects using mgit2

* [CKEditor 5](https://github.com/ckeditor/ckeditor5)
7 changes: 4 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ const cli = meow( `
$ mgit [command]
Commands:
bootstrap Install packages (i.e. clone dependent repositories).
exec Exec shell command in each package.
update Update packages to the latest versions (i.e. pull changes).
bootstrap Installs packages (i.e. clone dependent repositories).
exec Executes shell command in each package.
update Updates packages to the latest versions (i.e. pull changes).
save-hashes Saves hashes of packages in mgit.json. It allows to easily fix project to a specific state.
Options:
--recursive Whether to install dependencies recursively.
Expand Down
6 changes: 3 additions & 3 deletions lib/commands/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ module.exports = {
.then( ( output ) => {
log.info( output );

const response = {
const commandOutput = {
logs: log.all()
};

Expand All @@ -57,10 +57,10 @@ module.exports = {
packages = packages.concat( Object.keys( packageJson.devDependencies ) );
}

response.packages = packages;
commandOutput.packages = packages;
}

resolve( response );
resolve( commandOutput );
} )
.catch( ( error ) => {
log.error( error );
Expand Down
72 changes: 72 additions & 0 deletions lib/commands/savehashes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md.
*/

'use strict';

const path = require( 'path' );
const updateJsonFile = require( '../utils/updatejsonfile' );

module.exports = {
/**
* @param {Object} data
* @param {String} data.packageName Name of current package to process.
* @returns {Promise}
*/
execute( data ) {
const log = require( '../utils/log' )();
const execCommand = require( './exec' );

return new Promise( ( resolve, reject ) => {
execCommand.execute( getExecData( 'git rev-parse HEAD' ) )
.then( ( execResponse ) => {
const commitHash = execResponse.logs.info[ 0 ];

const commandResponse = {
packageName: data.packageName,
commit: commitHash
};

log.info( `Commit: ${ commitHash }.` );

resolve( {
response: commandResponse,
logs: log.all()
} );
} )
.catch( ( error ) => {
log.error( error );

reject( { logs: log.all() } );
} );
} );

function getExecData( command ) {
return Object.assign( {}, data, {
parameters: [ command ]
} );
}
},

/**
* Saves collected hashes to configuration file.
*
* @param {Set} processedPackages Collection of processed packages.
* @param {Set} commandResponses Results of executed command for each package.
*/
afterExecute( processedPackages, commandResponses ) {
const cwd = require( '../utils/getcwd.js' )();
const mgitJsonPath = path.join( cwd, 'mgit.json' );

updateJsonFile( mgitJsonPath, ( json ) => {
for ( const response of commandResponses.values() ) {
const repository = json.dependencies[ response.packageName ].split( '#' )[ 0 ];

json.dependencies[ response.packageName ] = `${ repository }#${ response.commit }`;
}

return json;
} );
}
};
10 changes: 9 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ module.exports = function( parameters, options ) {

const resolver = require( options.resolverPath );

// Remove all dashes from command name.
parameters[ 0 ] = parameters[ 0 ].replace( /-/g, '' );

const commandPath = path.join( __dirname, 'commands', parameters[ 0 ] );
const command = require( commandPath );

Expand All @@ -30,6 +33,7 @@ module.exports = function( parameters, options ) {
}

const processedPackages = new Set();
const commandResponses = new Set();
const packageNames = Object.keys( options.dependencies );

let allPackagesNumber = packageNames.length;
Expand Down Expand Up @@ -69,6 +73,10 @@ module.exports = function( parameters, options ) {
} );
}

if ( returnedData.response ) {
commandResponses.add( returnedData.response );
}

if ( returnedData.logs ) {
logDisplay( packageName, returnedData.logs, {
current: donePackagesNumber,
Expand All @@ -93,7 +101,7 @@ module.exports = function( parameters, options ) {
return forkPool.killAll()
.then( () => {
if ( typeof command.afterExecute === 'function' ) {
command.afterExecute( processedPackages );
command.afterExecute( processedPackages, commandResponses );
}

const endTime = process.hrtime( startTime );
Expand Down
2 changes: 0 additions & 2 deletions lib/utils/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

'use strict';

/**
*/
module.exports = function log() {
const logs = new Map( [
[ 'info', [] ],
Expand Down
22 changes: 22 additions & 0 deletions lib/utils/updatejsonfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md.
*/

'use strict';

const fs = require( 'fs' );

/**
* Updates JSON file under specified path.
* @param {String} path Path to file on disk.
* @param {Function} updateFunction Function that will be called with parsed JSON object. It should return
* modified JSON object to save.
*/
module.exports = function updateJsonFile( path, updateFunction ) {
const contents = fs.readFileSync( path, 'utf-8' );
let json = JSON.parse( contents );
json = updateFunction( json );

fs.writeFileSync( path, JSON.stringify( json, null, 2 ) + '\n', 'utf-8' );
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"gulp": "^3.9.1",
"guppy-pre-commit": "^0.4.0",
"istanbul": "^0.4.5",
"mocha": "^3.2.0"
"mocha": "^3.2.0",
"sinon": "^1.17.7"
},
"repository": {
"type": "git",
Expand Down
43 changes: 43 additions & 0 deletions tests/utils/updatejsonfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md.
*/

/* jshint mocha:true */

'use strict';

const updateJsonFile = require( '../../lib/utils/updatejsonfile' );
const expect = require( 'chai' ).expect;
const sinon = require( 'sinon' );

describe( 'utils', () => {
let sandbox;

beforeEach( () => {
sandbox = sinon.sandbox.create();
} );

afterEach( () => {
sandbox.restore();
} );
describe( 'updateJsonFile()', () => {
it( 'should read, update and save JSON file', () => {
const path = 'path/to/file.json';
const fs = require( 'fs' );
const readFileStub = sandbox.stub( fs, 'readFileSync', () => '{}' );
const modifiedJSON = { modified: true };
const writeFileStub = sandbox.stub( fs, 'writeFileSync' );

updateJsonFile( path, () => {
return modifiedJSON;
} );

expect( readFileStub.calledOnce ).to.equal( true );
expect( readFileStub.firstCall.args[ 0 ] ).to.equal( path );
expect( writeFileStub.calledOnce ).to.equal( true );
expect( writeFileStub.firstCall.args[ 0 ] ).to.equal( path );
expect( writeFileStub.firstCall.args[ 1 ] ).to.equal( JSON.stringify( modifiedJSON, null, 2 ) + '\n' );
} );
} );
} );

0 comments on commit 17e6c67

Please sign in to comment.