Преглед изворни кода

Added workspaceRoot option to gruntfile, added dev:status task, refractoring, tests.

Szymon Kupś пре 10 година
родитељ
комит
c5c7206355
5 измењених фајлова са 212 додато и 88 уклоњено
  1. 16 16
      dev/tasks/dev.js
  2. 0 64
      dev/tasks/test/dev.js
  3. 97 7
      dev/tasks/test/tools.js
  4. 94 0
      dev/tasks/utils/tools.js
  5. 5 1
      gruntfile.js

+ 16 - 16
dev/tasks/dev.js

@@ -8,28 +8,28 @@
 var tools = require( './utils/tools' );
 var path = require( 'path' );
 var ckeditor5Path = process.cwd();
-var json = require( path.join( ckeditor5Path, 'package.json' ) );
-var dependencies = json.dependencies;
+var workspaceAbsolutePath;
 
 module.exports = function( grunt ) {
 	grunt.registerTask( 'dev', function( target ) {
-		var pluginPath;
+		var	options = {
+			workspaceRoot: '..'
+		};
+
+		// Get workspace root from configuration.
+		options = this.options( options );
+		workspaceAbsolutePath = path.join( ckeditor5Path, options.workspaceRoot );
 
 		switch ( target ) {
+
+			// grunt dev:init
 			case 'init':
-				var ckeDependencies = tools.getCKEditorDependencies( dependencies );
-				var location = path.join( ckeditor5Path, '..' );
-
-				if ( ckeDependencies ) {
-					Object.keys( ckeDependencies ).forEach( function( name ) {
-						grunt.log.writeln( 'Clonning repository ' + ckeDependencies[ name ] + '...' );
-						tools.cloneRepository( name, ckeDependencies[ name ], location );
-
-						pluginPath = path.join( location, name );
-						grunt.log.writeln( 'Linking ' + pluginPath + ' into ' + ckeditor5Path + '...' );
-						tools.npmLink( pluginPath, ckeditor5Path, name );
-					} );
-				}
+				tools.initDevWorkspace( workspaceAbsolutePath, ckeditor5Path, grunt.log.writeln );
+				break;
+
+			// grunt dev:status
+			case 'status':
+				tools.getWorkspaceStatus( workspaceAbsolutePath, grunt.log.writeln );
 				break;
 		}
 	} );

+ 0 - 64
dev/tasks/test/dev.js

@@ -1,64 +0,0 @@
-/**
- * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-'use strict';
-/* global describe, it */
-
-var chai = require( 'chai' );
-var tools = require( '../utils/tools' );
-var sinon = require( 'sinon' );
-var path = require( 'path' );
-var expect = chai.expect;
-var dev = require( './../dev' );
-var grunt = {
-	tasks: {},
-	registerTask: function( taskName, fn ) {
-		this.tasks[ taskName ] = fn;
-	},
-	log: {
-		writeln: function() {}
-	}
-};
-
-dev( grunt );
-
-describe( 'tasks', function() {
-	describe( 'dev:init', function() {
-		it( 'should get ckeditor5- dependencies, clone repositories and link them', function() {
-			var getDepsSpy = sinon.spy( tools, 'getCKEditorDependencies' );
-			var cloneRepositoryStub = sinon.stub( tools, 'cloneRepository' );
-			var npmLinkStub = sinon.stub( tools, 'npmLink' );
-			var ckeditor5Path = process.cwd();
-			var location = path.join( ckeditor5Path, '..' );
-			var dependencies, keys;
-
-			grunt.tasks.dev( 'init' );
-
-			getDepsSpy.restore();
-			cloneRepositoryStub.restore();
-			npmLinkStub.restore();
-
-			expect( getDepsSpy.calledOnce ).to.equal( true );
-			dependencies = getDepsSpy.firstCall.returnValue;
-
-			if ( dependencies ) {
-				keys = Object.keys( dependencies );
-
-				expect( cloneRepositoryStub.callCount ).to.equal( keys.length );
-				expect( npmLinkStub.callCount ).to.equal( keys.length );
-
-				keys.forEach( function( key, i ) {
-					expect( cloneRepositoryStub.getCall( i ).args[0] ).equal( key );
-					expect( cloneRepositoryStub.getCall( i ).args[1] ).equal( dependencies[ key ] );
-					expect( cloneRepositoryStub.getCall( i ).args[2] ).equal( location );
-
-					expect( npmLinkStub.getCall( i ).args[0] ).equal( path.join( location, key ) );
-					expect( npmLinkStub.getCall( i ).args[1] ).equal( ckeditor5Path );
-					expect( npmLinkStub.getCall( i ).args[2] ).equal( key );
-				} );
-			}
-		} );
-	} );
-} );

+ 97 - 7
dev/tasks/test/tools.js

@@ -4,14 +4,25 @@
  */
 
 'use strict';
-/* global describe, it */
+/* global describe, it, beforeEach, afterEach */
 
 var chai = require( 'chai' );
 var sinon = require( 'sinon' );
 var expect = chai.expect;
 var tools = require( '../utils/tools' );
+var toRestore;
 
 describe( 'utils', function() {
+	beforeEach( function() {
+		toRestore = [];
+	} );
+
+	afterEach( function() {
+		toRestore.forEach( function( item ) {
+			item.restore();
+		} );
+	} );
+
 	describe( 'tools', function() {
 		describe( 'cloneRepository', function() {
 			it( 'should be defined', function() {
@@ -23,10 +34,9 @@ describe( 'utils', function() {
 				var name = 'test';
 				var gitHubUrl = 'ckeditor/test';
 				var destination = '/destination/dir';
+				toRestore.push( shExecStub );
 
 				tools.cloneRepository( name, gitHubUrl, destination );
-				shExecStub.restore();
-
 				expect( shExecStub.calledOnce ).to.equal( true );
 				expect( shExecStub.firstCall.args[ 0 ] ).to.equal( 'cd ' + destination + ' && git clone git@github.com:' + gitHubUrl );
 			} );
@@ -38,10 +48,9 @@ describe( 'utils', function() {
 				var branch = 'branch';
 				var gitHubUrl = url + '#' + branch;
 				var destination = '/destination/dir';
+				toRestore.push( shExecStub );
 
 				tools.cloneRepository( name, gitHubUrl, destination );
-				shExecStub.restore();
-
 				expect( shExecStub.calledOnce ).to.equal( true );
 				expect( shExecStub.firstCall.args[ 0 ] ).to.equal(
 					'cd ' + destination + ' && ' +
@@ -69,10 +78,9 @@ describe( 'utils', function() {
 					'cd ' + destination,
 					'npm link ' + pluginName
 				];
+				toRestore.push( shExecStub );
 
 				tools.npmLink( source, destination, pluginName );
-				shExecStub.restore();
-
 				expect( shExecStub.calledOnce ).to.equal( true );
 				expect( shExecStub.firstCall.args[ 0 ] ).to.equal( linkCommands.join( ' && ' ) );
 			} );
@@ -109,5 +117,87 @@ describe( 'utils', function() {
 				expect( ckeditorDependencies[ 'ckeditor5-core' ] ).to.be.a( 'string' );
 			} );
 		} );
+
+		describe( 'getCKE5Directories', function() {
+			it( 'should return only ckeditor5 directories', function() {
+				var workspacePath = '/workspace/path';
+				var getDirectoriesStub = sinon.stub( tools, 'getDirectories', function() {
+					return [ 'tools', 'ckeditor5', 'ckeditor5-core', '.bin', 'ckeditor5-plugin-image' ];
+				} );
+				toRestore.push( getDirectoriesStub );
+				var directories = tools.getCKE5Directories( workspacePath );
+
+				expect( directories.length ).equal( 3 );
+				expect( directories[ 0 ] ).equal( 'ckeditor5' );
+				expect( directories[ 1 ] ).equal( 'ckeditor5-core' );
+				expect( directories[ 2 ] ).equal( 'ckeditor5-plugin-image' );
+			} );
+		} );
+
+		describe( 'initDevWorkspace', function() {
+			it( 'should get ckeditor5- dependencies, clone repositories and link them', function() {
+				var path = require( 'path' );
+				var getDependenciesSpy = sinon.spy( tools, 'getCKEditorDependencies' );
+				var cloneRepositoryStub = sinon.stub( tools, 'cloneRepository' );
+				var npmLinkStub = sinon.stub( tools, 'npmLink' );
+				var ckeditor5Path = process.cwd();
+				var workspacePath = path.join( ckeditor5Path, '..' );
+				var dependencies, keys;
+				toRestore.push( getDependenciesSpy, cloneRepositoryStub, npmLinkStub );
+
+				tools.initDevWorkspace( workspacePath, ckeditor5Path, function() {} );
+				expect( getDependenciesSpy.calledOnce ).to.equal( true );
+				dependencies = getDependenciesSpy.firstCall.returnValue;
+
+				if ( dependencies ) {
+					keys = Object.keys( dependencies );
+
+					// All repositories were cloned.
+					expect( cloneRepositoryStub.callCount ).to.equal( keys.length );
+
+					// All repositories were linked.
+					expect( npmLinkStub.callCount ).to.equal( keys.length );
+
+					// Check clone and link parameters.
+					keys.forEach( function( key, i ) {
+						expect( cloneRepositoryStub.getCall( i ).args[0] ).equal( key );
+						expect( cloneRepositoryStub.getCall( i ).args[1] ).equal( dependencies[ key ] );
+						expect( cloneRepositoryStub.getCall( i ).args[2] ).equal( workspacePath );
+
+						expect( npmLinkStub.getCall( i ).args[0] ).equal( path.join( workspacePath, key ) );
+						expect( npmLinkStub.getCall( i ).args[1] ).equal( ckeditor5Path );
+						expect( npmLinkStub.getCall( i ).args[2] ).equal( key );
+					} );
+				}
+			} );
+		} );
+
+		describe( 'getWorkspaceStatus', function() {
+			it( 'should get all repositories status', function() {
+				var path = require( 'path' );
+				var workspacePath = '/workspace/path/';
+				var directories = [ 'ckeditor5', 'ckeditor5-core' ];
+				var log = sinon.spy();
+
+				// Stub methods for test purposes.
+				var getCKE5DirectoriesStub = sinon.stub( tools, 'getCKE5Directories', function() {
+					return directories;
+				} );
+				var getGitStatusStub = sinon.stub( tools, 'getGitStatus', function() {
+					return 'status';
+				} );
+				toRestore.push( getCKE5DirectoriesStub, getGitStatusStub );
+
+				tools.getWorkspaceStatus( workspacePath, log );
+				expect( getCKE5DirectoriesStub.calledOnce ).equal( true );
+				expect( log.callCount ).equal( directories.length );
+				expect( getGitStatusStub.callCount ).equal( directories.length );
+
+				// Check if status was called for proper directory.
+				for ( var i = 0; i < getGitStatusStub.callCount; i++ ) {
+					expect( getGitStatusStub.getCall( i ).args[0] ).equals( path.join( workspacePath, directories[ i ] ) );
+				}
+			} );
+		} );
 	} );
 } );

+ 94 - 0
dev/tasks/utils/tools.js

@@ -4,6 +4,7 @@ var dirtyFiles,
 	ignoreList;
 
 var repositoryRegExp = /^(ckeditor\/[^#]+)(?:#)?(.*)/;
+var directoryRegExp = /^ckeditor5/;
 
 module.exports = {
 	/**
@@ -211,5 +212,98 @@ module.exports = {
 		}
 
 		return result;
+	},
+
+	/**
+	 * Returns array with all directories under specified path.
+	 *
+	 * @param {String} path
+	 * @returns {Array}
+	 */
+	getDirectories: function( path ) {
+		var fs = require( 'fs' );
+		var pth = require( 'path' );
+
+		return fs.readdirSync( path ).filter( function( item ) {
+			return fs.statSync( pth.join( path, item ) ).isDirectory();
+		} );
+	},
+
+	/**
+	 * Returns all directories under specified path that match 'ckeditor5' pattern.
+	 *
+	 * @param {String} path
+	 * @returns {Array}
+	 */
+	getCKE5Directories: function( path ) {
+		return module.exports.getDirectories( path ).filter( function( dir ) {
+			return directoryRegExp.test( dir );
+		} );
+	},
+
+	/**
+	 * Returns git status --porcelain -sb executed under specified path.
+	 *
+	 * @param {String} path Path where git status will be executed.
+	 * @returns {String|null}
+	 */
+	getGitStatus: function( path ) {
+		var exec = module.exports.shExec;
+
+		try {
+			return exec( 'cd ' + path + ' && git status --porcelain -sb' ).trim();
+		} catch ( e ) {	}
+
+		return null;
+	},
+
+	/**
+	 * Initializes development workspace. Takes CKEditor5 dependencies, clones them and npm links to the main CKEditor5
+	 * repository.
+	 *
+	 * @param {String} workspacePath Absolute path to the workspace where all repositories will be cloned.
+	 * @param {String} ckeditor5Path Absolute path to the CKEditor5 repository where all dependencies will be linked.
+	 * @param {Function} log Log function used to report progress.
+	 */
+	initDevWorkspace: function( workspacePath, ckeditor5Path, log ) {
+		var tools = module.exports;
+		var path = require( 'path' );
+		var packageJSON = require( path.join( ckeditor5Path, 'package.json' ) );
+		var pluginPath;
+
+		// Get only CKEditor dependencies.
+		var dependencies = tools.getCKEditorDependencies( packageJSON.dependencies );
+
+		if ( dependencies ) {
+			Object.keys( dependencies ).forEach( function( name ) {
+				log( 'Clonning repository ' + dependencies[ name ] + '...' );
+				tools.cloneRepository( name, dependencies[ name ], workspacePath );
+
+				pluginPath = path.join( workspacePath, name );
+				log( 'Linking ' + pluginPath + ' into ' + ckeditor5Path + '...' );
+				tools.npmLink( pluginPath, ckeditor5Path, name );
+			} );
+		}
+	},
+
+	/**
+	 * Returns git status from all CKEditor repositories from workspace.
+	 *
+	 * @param {String} workspacePath Absolute path to the workspace containing repositories.
+	 * @param {Function} log Log function used to output status information.
+	 */
+	getWorkspaceStatus: function( workspacePath, log ) {
+		var tools = module.exports;
+		var path = require( 'path' );
+		var directories = tools.getCKE5Directories( workspacePath );
+
+		directories.forEach( function( directory ) {
+			var location = path.join( workspacePath, directory );
+			var data = tools.getGitStatus( location );
+
+			if ( data ) {
+				log( '\x1b[1m' , '\x1b[36m', directory, '\x1b[0m\n', data );
+			}
+		} );
 	}
 };

+ 5 - 1
gruntfile.js

@@ -28,7 +28,11 @@ module.exports = function( grunt ) {
 			}
 		},
 
-		dev: {}
+		dev: {
+			options: {
+				workspaceRoot: '..'
+			}
+		}
 	} );
 
 	// Finally load the tasks.