ソースを参照

Moved ckeditor5 specific directory function to new module. Updated modules depending on those functions. Updated tests.

Maksymilian Barnaś 9 年 前
コミット
7a34b8b186

+ 2 - 2
dev/tasks/dev/tasks/init.js

@@ -5,7 +5,7 @@
 
 'use strict';
 
-const tools = require( '../../../utils/tools' );
+const ckeditor5Dirs = require( '../../../utils/ckeditor5-dirs' );
 const log = require( '../../../utils/log' );
 
 /**
@@ -19,7 +19,7 @@ const log = require( '../../../utils/log' );
  */
 module.exports = ( installTask, ckeditor5Path, packageJSON, workspaceRoot ) => {
 	// Get all CKEditor dependencies from package.json.
-	const dependencies = tools.getCKEditorDependencies( packageJSON.dependencies );
+	const dependencies = ckeditor5Dirs.getCKEditorDependencies( packageJSON.dependencies );
 
 	if ( dependencies ) {
 		for ( let dependency in dependencies ) {

+ 3 - 2
dev/tasks/dev/tasks/relink.js

@@ -5,6 +5,7 @@
 
 'use strict';
 
+const ckeditor5Dirs = require( '../../../utils/ckeditor5-dirs' );
 const tools = require( '../../../utils/tools' );
 const path = require( 'path' );
 const log = require( '../../../utils/log' );
@@ -22,10 +23,10 @@ module.exports = ( ckeditor5Path, packageJSON, workspaceRoot ) => {
 	const workspaceAbsolutePath = path.join( ckeditor5Path, workspaceRoot );
 
 	// Get all CKEditor dependencies from package.json.
-	const dependencies = tools.getCKEditorDependencies( packageJSON.dependencies );
+	const dependencies = ckeditor5Dirs.getCKEditorDependencies( packageJSON.dependencies );
 
 	if ( dependencies ) {
-		const directories = tools.getCKE5Directories( workspaceAbsolutePath );
+		const directories = ckeditor5Dirs.getCKE5Directories( workspaceAbsolutePath );
 
 		if ( directories.length ) {
 			for ( let dependency in dependencies ) {

+ 3 - 3
dev/tasks/dev/tasks/status.js

@@ -5,7 +5,7 @@
 
 'use strict';
 
-const tools = require( '../../../utils/tools' );
+const ckeditor5Dirs = require( '../../../utils/ckeditor5-dirs' );
 const git = require( '../../../utils/git' );
 const path = require( 'path' );
 const log = require( '../../../utils/log' );
@@ -23,10 +23,10 @@ module.exports = ( ckeditor5Path, packageJSON, workspaceRoot ) => {
 	const workspaceAbsolutePath = path.join( ckeditor5Path, workspaceRoot );
 
 	// Get all CKEditor dependencies from package.json.
-	const dependencies = tools.getCKEditorDependencies( packageJSON.dependencies );
+	const dependencies = ckeditor5Dirs.getCKEditorDependencies( packageJSON.dependencies );
 
 	if ( dependencies ) {
-		const directories = tools.getCKE5Directories( workspaceAbsolutePath );
+		const directories = ckeditor5Dirs.getCKE5Directories( workspaceAbsolutePath );
 
 		if ( directories.length ) {
 			for ( let dependency in dependencies ) {

+ 4 - 3
dev/tasks/dev/tasks/update.js

@@ -6,6 +6,7 @@
 'use strict';
 
 const tools = require( '../../../utils/tools' );
+const ckeditor5Dirs = require( '../../../utils/ckeditor5-dirs' );
 const git = require( '../../../utils/git' );
 const path = require( 'path' );
 const log = require( '../../../utils/log' );
@@ -38,10 +39,10 @@ module.exports = ( installTask, ckeditor5Path, packageJSON, workspaceRoot, runNp
 	git.fetchAll( ckeditor5Path );
 
 	// Get all CKEditor dependencies from package.json.
-	const dependencies = tools.getCKEditorDependencies( packageJSON.dependencies );
+	const dependencies = ckeditor5Dirs.getCKEditorDependencies( packageJSON.dependencies );
 
 	if ( dependencies ) {
-		const directories = tools.getCKE5Directories( workspaceAbsolutePath );
+		const directories = ckeditor5Dirs.getCKE5Directories( workspaceAbsolutePath );
 
 		for ( let dependency in dependencies ) {
 			const repositoryURL = dependencies[ dependency ];
@@ -86,7 +87,7 @@ module.exports = ( installTask, ckeditor5Path, packageJSON, workspaceRoot, runNp
 
 	// Remove symlinks not used in this configuration.
 	const nodeModulesPath = path.join( ckeditor5Path, 'node_modules' );
-	const symlinks = tools.getCKE5Symlinks( nodeModulesPath );
+	const symlinks = ckeditor5Dirs.getCKE5Symlinks( nodeModulesPath );
 	symlinks
 		.filter( dir => typeof dependencies[ dir ] == 'undefined' )
 		.forEach( dir => {

+ 2 - 34
dev/tasks/exec/tasks.js

@@ -10,8 +10,7 @@ const minimist = require( 'minimist' );
 const path = require( 'path' );
 const merge = require( 'merge-stream' );
 const log = require( '../../utils/log' );
-const tools = require( '../../utils/tools' );
-const git = require( '../../utils/git' );
+const ckeditor5Dirs = require( '../../utils/ckeditor5-dirs' );
 
 /**
  * Run task over ckeditor5 repositories.
@@ -72,7 +71,7 @@ function execute( execTask, ckeditor5Path, packageJSON, workspaceRoot, parameter
 	const mergedStream = merge();
 	const specificRepository = parameters.repository;
 
-	let devDirectories = getCKE5DevDirectories( workspacePath, packageJSON, ckeditor5Path );
+	let devDirectories = ckeditor5Dirs.getCKE5DevDirectories( workspacePath, packageJSON, ckeditor5Path );
 
 	if ( specificRepository ) {
 		devDirectories = devDirectories.filter( ( dir ) => {
@@ -91,34 +90,3 @@ function execute( execTask, ckeditor5Path, packageJSON, workspaceRoot, parameter
 
 	return mergedStream;
 }
-
-/**
- * Returns array with information about ckeditor5-* directories/repositories.
- *
- * @param {String} workspacePath Absolute path to workspace.
- * @param {Object} packageJSON Contents of ckeditor5 repo package.json file.
- * @param {String} ckeditor5Path Absolute path to ckeditor5 root directory.
- * @returns {Array.<Object>}
- */
-function getCKE5DevDirectories( workspacePath, packageJSON, ckeditor5Path ) {
-	const directories = tools.getCKE5Directories( workspacePath );
-	const dependencies = tools.getCKEditorDependencies( packageJSON.dependencies );
-
-	let devDirectories = [];
-
-	for ( let dependency in dependencies ) {
-		const repositoryURL = dependencies[ dependency ];
-		const urlInfo = git.parseRepositoryUrl( repositoryURL );
-		const repositoryPath = path.join( ckeditor5Path, 'node_modules', dependency );
-
-		// Check if repository's directory already exists.
-		if ( directories.indexOf( urlInfo.name ) > -1 ) {
-			devDirectories.push( {
-				repositoryPath,
-				repositoryURL
-			} );
-		}
-	}
-
-	return devDirectories;
-}

+ 86 - 0
dev/tests/dev/ckeditor5-dirs.js

@@ -0,0 +1,86 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* global describe, it, beforeEach, afterEach */
+
+'use strict';
+
+const chai = require( 'chai' );
+const sinon = require( 'sinon' );
+const expect = chai.expect;
+const ckeditor5Dirs = require( '../../utils/ckeditor5-dirs' );
+const tools = require( '../../utils/tools' );
+let sandbox;
+
+describe( 'utils', () => {
+	beforeEach( () => {
+		sandbox = sinon.sandbox.create();
+	} );
+
+	afterEach( () => {
+		sandbox.restore();
+	} );
+
+	describe( 'ckeditor5dirs', () => {
+		describe( 'getCKEditorDependencies', () => {
+			it( 'should be defined', () => expect( ckeditor5Dirs.getCKEditorDependencies ).to.be.a( 'function' ) );
+
+			it( 'should return null if no CKEditor5 repository is found', () => {
+				const dependencies = {
+					'plugin1': '',
+					'plugin2': '',
+					'plugin3': ''
+				};
+				expect( ckeditor5Dirs.getCKEditorDependencies( dependencies ) ).to.equal( null );
+				expect( ckeditor5Dirs.getCKEditorDependencies() ).to.equal( null );
+			} );
+
+			it( 'should return only ckeditor5- dependencies', () => {
+				const dependencies = {
+					'plugin1': '',
+					'ckeditor5-plugin-image': 'ckeditor/ckeditor5-plugin-image',
+					'plugin2': '',
+					'ckeditor5-core': 'ckeditor/ckeditor5-core'
+				};
+				const ckeditorDependencies = ckeditor5Dirs.getCKEditorDependencies( dependencies );
+
+				expect( ckeditorDependencies ).to.be.an( 'object' );
+				expect( ckeditorDependencies.plugin1 ).to.be.a( 'undefined' );
+				expect( ckeditorDependencies.plugin2 ).to.be.a( 'undefined' );
+				expect( ckeditorDependencies[ 'ckeditor5-plugin-image' ] ).to.be.a( 'string' );
+				expect( ckeditorDependencies[ 'ckeditor5-core' ] ).to.be.a( 'string' );
+			} );
+		} );
+
+		describe( 'getCKE5Directories', () => {
+			it( 'should be defined', () => expect( ckeditor5Dirs.getCKE5Directories ).to.be.a( 'function' ) );
+
+			it( 'should return only ckeditor5 directories', () => {
+				const workspacePath = '/workspace/path';
+				const sourceDirectories = [ 'tools', 'ckeditor5', 'ckeditor5-core', '.bin', 'ckeditor5-plugin-image' ];
+				sandbox.stub( tools, 'getDirectories', () => sourceDirectories );
+				const directories = ckeditor5Dirs.getCKE5Directories( workspacePath );
+
+				expect( directories.length ).equal( 2 );
+				expect( directories[ 0 ] ).equal( 'ckeditor5-core' );
+				expect( directories[ 1 ] ).equal( 'ckeditor5-plugin-image' );
+			} );
+		} );
+
+		describe( 'getCKE5Symlinks', () => {
+			it( 'should return CKE5 symlinks from provided path', () => {
+				const fs = require( 'fs' );
+				const path = 'path/to/dir';
+				sandbox.stub( fs, 'readdirSync' ).returns( [ 'ckeditor5-core', 'ckeditor5-image', 'other-dependency' ] );
+				sandbox.stub( tools, 'isSymlink' ).returns( true );
+
+				const symlinks = ckeditor5Dirs.getCKE5Symlinks( path );
+				expect( symlinks.length ).to.equal( 2 );
+				expect( symlinks[ 0 ] ).to.equal( 'ckeditor5-core' );
+				expect( symlinks[ 1 ] ).to.equal( 'ckeditor5-image' );
+			} );
+		} );
+	} );
+} );

+ 3 - 3
dev/tests/dev/init.js

@@ -8,7 +8,7 @@
 'use strict';
 
 const sinon = require( 'sinon' );
-const tools = require( '../../utils/tools' );
+const ckeditor5Dirs = require( '../../utils/ckeditor5-dirs' );
 
 describe( 'dev-init', () => {
 	const initTask = require( '../../tasks/dev/tasks/init' );
@@ -16,7 +16,7 @@ describe( 'dev-init', () => {
 	const workspaceRoot = '..';
 
 	it( 'should get all ckedtior5- dependencies and execute dev-install on them', () => {
-		const getDependenciesSpy = sinon.spy( tools, 'getCKEditorDependencies' );
+		const getDependenciesSpy = sinon.spy( ckeditor5Dirs, 'getCKEditorDependencies' );
 		const installSpy = sinon.spy();
 		const JSON = {
 			dependencies: {
@@ -39,7 +39,7 @@ describe( 'dev-init', () => {
 	} );
 
 	it( 'should not call dev-install if no ckedtior5- dependencies', () => {
-		const getDependenciesSpy = sinon.spy( tools, 'getCKEditorDependencies' );
+		const getDependenciesSpy = sinon.spy( ckeditor5Dirs, 'getCKEditorDependencies' );
 		const installSpy = sinon.spy();
 		const JSON = {
 			dependencies: {}

+ 9 - 8
dev/tests/dev/relink.js

@@ -9,6 +9,7 @@
 
 const sinon = require( 'sinon' );
 const tools = require( '../../utils/tools' );
+const ckeditor5Dirs = require( '../../utils/ckeditor5-dirs' );
 const path = require( 'path' );
 
 describe( 'dev-relink', () => {
@@ -20,8 +21,8 @@ describe( 'dev-relink', () => {
 
 	it( 'should link dev repositories', () => {
 		const dirs = [ 'ckeditor5-core', 'ckeditor5-devtest' ];
-		const getDependenciesSpy = sinon.spy( tools, 'getCKEditorDependencies' );
-		const getDirectoriesStub = sinon.stub( tools, 'getCKE5Directories' ).returns( dirs );
+		const getDependenciesSpy = sinon.spy( ckeditor5Dirs, 'getCKEditorDependencies' );
+		const getDirectoriesStub = sinon.stub( ckeditor5Dirs, 'getCKE5Directories' ).returns( dirs );
 		const linkStub = sinon.stub( tools, 'linkDirectories' );
 		const json = {
 			dependencies: {
@@ -43,8 +44,8 @@ describe( 'dev-relink', () => {
 	} );
 
 	it( 'should not link when no dependencies are found', () => {
-		const getDependenciesSpy = sinon.spy( tools, 'getCKEditorDependencies' );
-		const getDirectoriesStub = sinon.stub( tools, 'getCKE5Directories' );
+		const getDependenciesSpy = sinon.spy( ckeditor5Dirs, 'getCKEditorDependencies' );
+		const getDirectoriesStub = sinon.stub( ckeditor5Dirs, 'getCKE5Directories' );
 		const linkStub = sinon.stub( tools, 'linkDirectories' );
 		const json = {
 			dependencies: {
@@ -62,8 +63,8 @@ describe( 'dev-relink', () => {
 	} );
 
 	it( 'should not link when no plugins in dev mode', () => {
-		const getDependenciesSpy = sinon.spy( tools, 'getCKEditorDependencies' );
-		const getDirectoriesStub = sinon.stub( tools, 'getCKE5Directories' ).returns( [] );
+		const getDependenciesSpy = sinon.spy( ckeditor5Dirs, 'getCKEditorDependencies' );
+		const getDirectoriesStub = sinon.stub( ckeditor5Dirs, 'getCKE5Directories' ).returns( [] );
 		const linkStub = sinon.stub( tools, 'linkDirectories' );
 		const json = {
 			dependencies: {
@@ -83,8 +84,8 @@ describe( 'dev-relink', () => {
 
 	it( 'should write error message when linking is unsuccessful', () => {
 		const dirs = [ 'ckeditor5-core' ];
-		const getDependenciesSpy = sinon.spy( tools, 'getCKEditorDependencies' );
-		const getDirectoriesStub = sinon.stub( tools, 'getCKE5Directories' ).returns( dirs );
+		const getDependenciesSpy = sinon.spy( ckeditor5Dirs, 'getCKEditorDependencies' );
+		const getDirectoriesStub = sinon.stub( ckeditor5Dirs, 'getCKE5Directories' ).returns( dirs );
 		const error = new Error( 'Error message.' );
 		const linkStub = sinon.stub( tools, 'linkDirectories' ).throws( error );
 		const json = {

+ 9 - 9
dev/tests/dev/status.js

@@ -8,7 +8,7 @@
 'use strict';
 
 const sinon = require( 'sinon' );
-const tools = require( '../../utils/tools' );
+const ckeditor5Dirs = require( '../../utils/ckeditor5-dirs' );
 const git = require( '../../utils/git' );
 const path = require( 'path' );
 const chai = require( 'chai' );
@@ -23,8 +23,8 @@ describe( 'dev-status', () => {
 
 	it( 'should show status of dev repositories', () => {
 		const dirs = [ 'ckeditor5-core', 'ckeditor5-devtest' ];
-		const getDependenciesSpy = sinon.spy( tools, 'getCKEditorDependencies' );
-		const getDirectoriesStub = sinon.stub( tools, 'getCKE5Directories' ).returns( dirs );
+		const getDependenciesSpy = sinon.spy( ckeditor5Dirs, 'getCKEditorDependencies' );
+		const getDirectoriesStub = sinon.stub( ckeditor5Dirs, 'getCKE5Directories' ).returns( dirs );
 		const statusStub = sinon.stub( git, 'getStatus' );
 		const json = {
 			dependencies: {
@@ -46,8 +46,8 @@ describe( 'dev-status', () => {
 	} );
 
 	it( 'should not get status when no dependencies are found', () => {
-		const getDependenciesSpy = sinon.spy( tools, 'getCKEditorDependencies' );
-		const getDirectoriesStub = sinon.stub( tools, 'getCKE5Directories' );
+		const getDependenciesSpy = sinon.spy( ckeditor5Dirs, 'getCKEditorDependencies' );
+		const getDirectoriesStub = sinon.stub( ckeditor5Dirs, 'getCKE5Directories' );
 		const statusStub = sinon.stub( git, 'getStatus' );
 		const json = {
 			dependencies: {
@@ -65,8 +65,8 @@ describe( 'dev-status', () => {
 	} );
 
 	it( 'should not get status when no plugins in dev mode', () => {
-		const getDependenciesSpy = sinon.spy( tools, 'getCKEditorDependencies' );
-		const getDirectoriesStub = sinon.stub( tools, 'getCKE5Directories' ).returns( [] );
+		const getDependenciesSpy = sinon.spy( ckeditor5Dirs, 'getCKEditorDependencies' );
+		const getDirectoriesStub = sinon.stub( ckeditor5Dirs, 'getCKE5Directories' ).returns( [] );
 		const statusStub = sinon.stub( git, 'getStatus' );
 		const json = {
 			dependencies: {
@@ -86,8 +86,8 @@ describe( 'dev-status', () => {
 
 	it( 'should write error message when getStatus is unsuccessful', () => {
 		const dirs = [ 'ckeditor5-core' ];
-		const getDependenciesSpy = sinon.spy( tools, 'getCKEditorDependencies' );
-		const getDirectoriesStub = sinon.stub( tools, 'getCKE5Directories' ).returns( dirs );
+		const getDependenciesSpy = sinon.spy( ckeditor5Dirs, 'getCKEditorDependencies' );
+		const getDirectoriesStub = sinon.stub( ckeditor5Dirs, 'getCKE5Directories' ).returns( dirs );
 		const error = new Error( 'Error message.' );
 		const statusStub = sinon.stub( git, 'getStatus' ).throws( error );
 		const json = {

+ 0 - 59
dev/tests/dev/tools.js

@@ -147,36 +147,6 @@ describe( 'utils', () => {
 			} );
 		} );
 
-		describe( 'getCKEditorDependencies', () => {
-			it( 'should be defined', () => expect( tools.getCKEditorDependencies ).to.be.a( 'function' ) );
-
-			it( 'should return null if no CKEditor5 repository is found', () => {
-				const dependencies = {
-					'plugin1': '',
-					'plugin2': '',
-					'plugin3': ''
-				};
-				expect( tools.getCKEditorDependencies( dependencies ) ).to.equal( null );
-				expect( tools.getCKEditorDependencies() ).to.equal( null );
-			} );
-
-			it( 'should return only ckeditor5- dependencies', () => {
-				const dependencies = {
-					'plugin1': '',
-					'ckeditor5-plugin-image': 'ckeditor/ckeditor5-plugin-image',
-					'plugin2': '',
-					'ckeditor5-core': 'ckeditor/ckeditor5-core'
-				};
-				const ckeditorDependencies = tools.getCKEditorDependencies( dependencies );
-
-				expect( ckeditorDependencies ).to.be.an( 'object' );
-				expect( ckeditorDependencies.plugin1 ).to.be.a( 'undefined' );
-				expect( ckeditorDependencies.plugin2 ).to.be.a( 'undefined' );
-				expect( ckeditorDependencies[ 'ckeditor5-plugin-image' ] ).to.be.a( 'string' );
-				expect( ckeditorDependencies[ 'ckeditor5-core' ] ).to.be.a( 'string' );
-			} );
-		} );
-
 		describe( 'getDirectories', () => {
 			it( 'should be defined', () => expect( tools.getDirectories ).to.be.a( 'function' ) );
 
@@ -297,21 +267,6 @@ describe( 'utils', () => {
 			} );
 		} );
 
-		describe( 'getCKE5Directories', () => {
-			it( 'should be defined', () => expect( tools.getCKE5Directories ).to.be.a( 'function' ) );
-
-			it( 'should return only ckeditor5 directories', () => {
-				const workspacePath = '/workspace/path';
-				const sourceDirectories = [ 'tools', 'ckeditor5', 'ckeditor5-core', '.bin', 'ckeditor5-plugin-image' ];
-				sandbox.stub( tools, 'getDirectories', () => sourceDirectories );
-				const directories = tools.getCKE5Directories( workspacePath );
-
-				expect( directories.length ).equal( 2 );
-				expect( directories[ 0 ] ).equal( 'ckeditor5-core' );
-				expect( directories[ 1 ] ).equal( 'ckeditor5-plugin-image' );
-			} );
-		} );
-
 		describe( 'updateJSONFile', () => {
 			it( 'should be defined', () => expect( tools.updateJSONFile ).to.be.a( 'function' ) );
 			it( 'should read, update and save JSON file', () => {
@@ -498,20 +453,6 @@ describe( 'utils', () => {
 			} );
 		} );
 
-		describe( 'getCKE5Symlinks', () => {
-			it( 'should return CKE5 symlinks from provided path', () => {
-				const fs = require( 'fs' );
-				const path = 'path/to/dir';
-				sandbox.stub( fs, 'readdirSync' ).returns( [ 'ckeditor5-core', 'ckeditor5-image', 'other-dependency' ] );
-				sandbox.stub( tools, 'isSymlink' ).returns( true );
-
-				const symlinks = tools.getCKE5Symlinks( path );
-				expect( symlinks.length ).to.equal( 2 );
-				expect( symlinks[ 0 ] ).to.equal( 'ckeditor5-core' );
-				expect( symlinks[ 1 ] ).to.equal( 'ckeditor5-image' );
-			} );
-		} );
-
 		describe( 'removeSymlink', () => {
 			it( 'should unlink provided symlink', () => {
 				const fs = require( 'fs' );

+ 13 - 12
dev/tests/dev/update.js

@@ -9,6 +9,7 @@
 
 const sinon = require( 'sinon' );
 const tools = require( '../../utils/tools' );
+const ckeditor5Dirs = require( '../../utils/ckeditor5-dirs' );
 const git = require( '../../utils/git' );
 const path = require( 'path' );
 const chai = require( 'chai' );
@@ -23,7 +24,7 @@ describe( 'dev-update', () => {
 	const spies = {};
 
 	beforeEach( () => {
-		spies.getDependencies = sinon.spy( tools, 'getCKEditorDependencies' );
+		spies.getDependencies = sinon.spy( ckeditor5Dirs, 'getCKEditorDependencies' );
 		spies.checkout = sinon.stub( git, 'checkout' );
 		spies.pull = sinon.stub( git, 'pull' );
 		spies.fetchAll = sinon.stub( git, 'fetchAll' );
@@ -39,8 +40,8 @@ describe( 'dev-update', () => {
 	it( 'should update dev repositories', () => {
 		const dirs = [ 'ckeditor5-core', 'ckeditor5-devtest' ];
 		const installTask = sinon.spy();
-		spies.getDirectories = sinon.stub( tools, 'getCKE5Directories' ).returns( dirs );
-		spies.getCKE5Symlinks = sinon.stub( tools, 'getCKE5Symlinks' ).returns( [] );
+		spies.getDirectories = sinon.stub( ckeditor5Dirs, 'getCKE5Directories' ).returns( dirs );
+		spies.getCKE5Symlinks = sinon.stub( ckeditor5Dirs, 'getCKE5Symlinks' ).returns( [] );
 
 		const json = {
 			dependencies: {
@@ -79,8 +80,8 @@ describe( 'dev-update', () => {
 	it( 'should install missing dependencies', () => {
 		const dirs = [ 'ckeditor5-core', 'ckeditor5-devtest' ];
 		const installTask = sinon.spy();
-		spies.getDirectories = sinon.stub( tools, 'getCKE5Directories' ).returns( dirs );
-		spies.getCKE5Symlinks = sinon.stub( tools, 'getCKE5Symlinks' ).returns( [] );
+		spies.getDirectories = sinon.stub( ckeditor5Dirs, 'getCKE5Directories' ).returns( dirs );
+		spies.getCKE5Symlinks = sinon.stub( ckeditor5Dirs, 'getCKE5Symlinks' ).returns( [] );
 
 		const json = {
 			dependencies: {
@@ -122,8 +123,8 @@ describe( 'dev-update', () => {
 	it( 'should remove symlinks that are not needed', () => {
 		const dirs = [ 'ckeditor5-core', 'ckeditor5-devtest' ];
 		const installTask = sinon.spy();
-		spies.getDirectories = sinon.stub( tools, 'getCKE5Directories' ).returns( dirs );
-		spies.getCKE5Symlinks = sinon.stub( tools, 'getCKE5Symlinks' ).returns( [ 'ckeditor5-unused' ] );
+		spies.getDirectories = sinon.stub( ckeditor5Dirs, 'getCKE5Directories' ).returns( dirs );
+		spies.getCKE5Symlinks = sinon.stub( ckeditor5Dirs, 'getCKE5Symlinks' ).returns( [ 'ckeditor5-unused' ] );
 
 		const json = {
 			dependencies: {
@@ -167,8 +168,8 @@ describe( 'dev-update', () => {
 		const installTask = sinon.spy();
 		const outSpy = sinon.spy();
 		const errSpy = sinon.spy();
-		spies.getDirectories = sinon.stub( tools, 'getCKE5Directories' ).returns( dirs );
-		spies.getCKE5Symlinks = sinon.stub( tools, 'getCKE5Symlinks' ).returns( [ 'ckeditor5-unused' ] );
+		spies.getDirectories = sinon.stub( ckeditor5Dirs, 'getCKE5Directories' ).returns( dirs );
+		spies.getCKE5Symlinks = sinon.stub( ckeditor5Dirs, 'getCKE5Symlinks' ).returns( [ 'ckeditor5-unused' ] );
 		spies.linkDirectories.throws();
 
 		log.configure( outSpy, errSpy );
@@ -209,11 +210,11 @@ describe( 'dev-update', () => {
 
 	it( 'should skip updating if no dependencies found and fetch only main repository', () => {
 		spies.getDependencies.restore();
-		spies.getDependencies = sinon.stub( tools, 'getCKEditorDependencies' ).returns( null );
+		spies.getDependencies = sinon.stub( ckeditor5Dirs, 'getCKEditorDependencies' ).returns( null );
 		const dirs = [ 'ckeditor5-core', 'ckeditor5-devtest' ];
 		const installTask = sinon.spy();
-		spies.getDirectories = sinon.stub( tools, 'getCKE5Directories' ).returns( dirs );
-		spies.getCKE5Symlinks = sinon.stub( tools, 'getCKE5Symlinks' ).returns( [] );
+		spies.getDirectories = sinon.stub( ckeditor5Dirs, 'getCKE5Directories' ).returns( dirs );
+		spies.getCKE5Symlinks = sinon.stub( ckeditor5Dirs, 'getCKE5Symlinks' ).returns( [] );
 
 		const json = {
 			dependencies: {

+ 100 - 0
dev/utils/ckeditor5-dirs.js

@@ -0,0 +1,100 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+const path = require( 'path' );
+const tools = require( './tools' );
+const git = require( './git' );
+
+const dependencyRegExp = /^ckeditor5-/;
+
+module.exports = {
+
+	/**
+	 * Returns dependencies that starts with ckeditor5-, and have valid, short GitHub url. Returns null if no
+	 * dependencies are found.
+	 *
+	 * @param {Object} dependencies Dependencies object loaded from package.json file.
+	 * @returns {Object|null}
+	 */
+	getCKEditorDependencies( dependencies ) {
+		let result = null;
+
+		if ( dependencies ) {
+			Object.keys( dependencies ).forEach( function( key ) {
+				if ( dependencyRegExp.test( key ) ) {
+					if ( result === null ) {
+						result = {};
+					}
+
+					result[ key ] = dependencies[ key ];
+				}
+			} );
+		}
+
+		return result;
+	},
+
+	/**
+	 * Returns all directories under specified path that match 'ckeditor5' pattern.
+	 *
+	 * @param {String} path
+	 * @returns {Array}
+	 */
+	getCKE5Directories( path ) {
+		return tools.getDirectories( path ).filter( dir => {
+			return dependencyRegExp.test( dir );
+		} );
+	},
+
+	/**
+	 * Returns list of symbolic links to directories with names starting with `ckeditor5-` prefix.
+	 *
+	 * @param {String} path Path to directory,
+	 * @returns {Array} Array with directories names.
+	 */
+	getCKE5Symlinks( path ) {
+		const fs = require( 'fs' );
+		const pth = require( 'path' );
+
+		return fs.readdirSync( path ).filter( item => {
+			const fullPath = pth.join( path, item );
+
+			return dependencyRegExp.test( item ) && tools.isSymlink( fullPath );
+		} );
+	},
+
+	/**
+	 * Returns array with information about ckeditor5-* directories in development mode.
+	 *
+	 * @param {String} workspacePath Absolute path to workspace.
+	 * @param {Object} packageJSON Contents of ckeditor5 repo package.json file.
+	 * @param {String} ckeditor5Path Absolute path to ckeditor5 root directory.
+	 * @returns {Array.<Object>}
+	 */
+	getCKE5DevDirectories( workspacePath, packageJSON, ckeditor5Path ) {
+		const directories = this.getCKE5Directories( workspacePath );
+		const dependencies = this.getCKEditorDependencies( packageJSON.dependencies );
+
+		let devDirectories = [];
+
+		for ( let dependency in dependencies ) {
+			const repositoryURL = dependencies[ dependency ];
+			const urlInfo = git.parseRepositoryUrl( repositoryURL );
+			const repositoryPath = path.join( ckeditor5Path, 'node_modules', dependency );
+
+			// Check if repository's directory already exists.
+			if ( directories.indexOf( urlInfo.name ) > -1 ) {
+				devDirectories.push( {
+					repositoryPath,
+					repositoryURL
+				} );
+			}
+		}
+
+		return devDirectories;
+	}
+};

+ 0 - 56
dev/utils/tools.js

@@ -7,8 +7,6 @@
 
 const gutil = require( 'gulp-util' );
 
-const dependencyRegExp = /^ckeditor5-/;
-
 module.exports = {
 
 	/**
@@ -63,31 +61,6 @@ module.exports = {
 	},
 
 	/**
-	 * Returns dependencies that starts with ckeditor5-, and have valid, short GitHub url. Returns null if no
-	 * dependencies are found.
-	 *
-	 * @param {Object} dependencies Dependencies object loaded from package.json file.
-	 * @returns {Object|null}
-	 */
-	getCKEditorDependencies( dependencies ) {
-		let result = null;
-
-		if ( dependencies ) {
-			Object.keys( dependencies ).forEach( function( key ) {
-				if ( dependencyRegExp.test( key ) ) {
-					if ( result === null ) {
-						result = {};
-					}
-
-					result[ key ] = dependencies[ key ];
-				}
-			} );
-		}
-
-		return result;
-	},
-
-	/**
 	 * Returns array with all directories under specified path.
 	 *
 	 * @param {String} path
@@ -150,18 +123,6 @@ module.exports = {
 	},
 
 	/**
-	 * Returns all directories under specified path that match 'ckeditor5' pattern.
-	 *
-	 * @param {String} path
-	 * @returns {Array}
-	 */
-	getCKE5Directories( path ) {
-		return this.getDirectories( path ).filter( dir => {
-			return dependencyRegExp.test( dir );
-		} );
-	},
-
-	/**
 	 * 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
@@ -301,23 +262,6 @@ module.exports = {
 	},
 
 	/**
-	 * Returns list of symbolic links to directories with names starting with `ckeditor5-` prefix.
-	 *
-	 * @param {String} path Path to directory,
-	 * @returns {Array} Array with directories names.
-	 */
-	getCKE5Symlinks( path ) {
-		const fs = require( 'fs' );
-		const pth = require( 'path' );
-
-		return fs.readdirSync( path ).filter( item => {
-			const fullPath = pth.join( path, item );
-
-			return dependencyRegExp.test( item ) && this.isSymlink( fullPath );
-		} );
-	},
-
-	/**
 	 * Unlinks symbolic link under specified path.
 	 *
 	 * @param {String} path