Browse Source

Merge pull request #92 from ckeditor/t/87

Fill template files with data.
Piotrek Koszuliński 9 years ago
parent
commit
588071919d

+ 27 - 4
dev/tasks/dev/tasks/create-package.js

@@ -35,7 +35,13 @@ module.exports = ( ckeditor5Path, workspaceRoot ) => {
 			'.jshintrc',
 			'.jscsrc',
 			'.gitattributes',
-			'./dev/tasks/dev/templates'
+			'dev/tasks/dev/templates/.gitignore',
+			'dev/tasks/dev/templates/CHANGES.md',
+			'dev/tasks/dev/templates/CONTRIBUTING.md',
+			'dev/tasks/dev/templates/gulpfile.js',
+			'dev/tasks/dev/templates/LICENSE.md',
+			'dev/tasks/dev/templates/package.json',
+			'dev/tasks/dev/templates/README.md'
 		],
 		'tests/': [
 			'tests/.jshintrc'
@@ -43,21 +49,28 @@ module.exports = ( ckeditor5Path, workspaceRoot ) => {
 		'dev/': [
 			'dev/.jshintrc'
 		],
-		'dev/tasks/lint': [
-			'dev/tasks/lint'
+		'dev/tasks/lint/': [
+			'dev/tasks/lint/tasks.js'
 		]
 	};
 
 	let packageName;
+	let packageFullName;
 	let repositoryPath;
 	let packageVersion;
 	let gitHubUrl;
+	let packageDescription;
 
 	return inquiries.getPackageName()
 		.then( result => {
 			packageName = result;
 			repositoryPath = path.join( workspaceAbsolutePath, packageName );
 
+			return inquiries.getApplicationName();
+		} )
+		.then( result => {
+			packageFullName = result;
+
 			return inquiries.getPackageVersion();
 		} )
 		.then( result => {
@@ -68,19 +81,29 @@ module.exports = ( ckeditor5Path, workspaceRoot ) => {
 		.then( result => {
 			gitHubUrl = result;
 
+			return inquiries.getPackageDescription();
+		} )
+		.then( result => {
+			packageDescription = result;
+
 			log.out( `Initializing repository ${ repositoryPath }...` );
 			git.initializeRepository( repositoryPath );
 
 			log.out( `Copying files into ${ repositoryPath }...` );
 
 			for ( let destination in fileStructure ) {
-				tools.copy( fileStructure[ destination ], path.join( repositoryPath, destination ) );
+				tools.copyTemplateFiles( fileStructure[ destination ], path.join( repositoryPath, destination ), {
+					'{{AppName}}': packageFullName,
+					'{{GitHubRepositoryPath}}': gitHubUrl,
+					'{{ProjectDescription}}': packageDescription
+				} );
 			}
 
 			log.out( `Updating package.json files...` );
 			tools.updateJSONFile( path.join( repositoryPath, 'package.json' ), ( json ) => {
 				json.name = packageName;
 				json.version = packageVersion;
+				json.description = packageDescription;
 
 				return json;
 			} );

+ 22 - 0
dev/tasks/dev/utils/inquiries.js

@@ -27,6 +27,17 @@ module.exports = {
 		} );
 	},
 
+	getApplicationName() {
+		return new Promise( ( resolve ) => {
+			inquirer.prompt( [ {
+				name: 'applicationName',
+				message: 'Enter application full name:'
+			} ], ( answers ) => {
+				resolve( answers.applicationName );
+			} );
+		} );
+	},
+
 	getPackageVersion( ) {
 		return new Promise( ( resolve ) => {
 			inquirer.prompt( [ {
@@ -51,5 +62,16 @@ module.exports = {
 				resolve( answers.gitHubUrl );
 			} );
 		} );
+	},
+
+	getPackageDescription( ) {
+		return new Promise( ( resolve ) => {
+			inquirer.prompt( [ {
+				name: 'description',
+				message: 'Package description (one sentence):'
+			} ], ( answers ) => {
+				resolve( answers.description || '' );
+			} );
+		} );
 	}
 };

+ 20 - 13
dev/tasks/dev/utils/tools.js

@@ -224,29 +224,36 @@ module.exports = {
 	},
 
 	/**
-	 * Copies source files/directories into destination directory.
-	 * If directory path is provided in sources array - all files inside that directory will be copied.
+	 * Copies source files into destination directory and replaces contents of the file using provided `replace` object.
 	 *
-	 * @param { Array } source Source files/directories.
-	 * @param { String} destination Path to destination directory.
+	 *		// Each occurrence of `{{appName}}` inside README.md and CHANGES.md will be changed to `ckeditor5`.
+	 * 		tools.copyTemplateFiles( [ 'README.md', 'CHANGES.md' ], '/new/path', { '{{AppName}}': 'ckeditor5' } );
+	 *
+	 * @param {Array} sources Source files.
+	 * @param {String} destination Path to destination directory.
+	 * @param {Object} [replace] Object with data to fill template. Method will take object's keys and replace their
+	 * occurrences with value stored under that key.
 	 */
-	copy( sources, destination ) {
+	copyTemplateFiles( sources, destination, replace ) {
 		const path = require( 'path' );
 		const fs = require( 'fs-extra' );
+		replace = replace || {};
 		destination = path.resolve( destination );
+		const regexps = [];
+
+		for ( let variableName in replace ) {
+			regexps.push( variableName );
+		}
+		const regexp = new RegExp( regexps.join( '|' ), 'g' );
+		const replaceFunction = ( matched ) => replace[ matched ];
 
 		fs.ensureDirSync( destination );
 
 		sources.forEach( source => {
 			source = path.resolve( source );
-
-			if ( this.isFile( source ) ) {
-				fs.copySync( source, path.join( destination, path.basename( source ) ) );
-			}
-
-			if ( this.isDirectory( source ) ) {
-				fs.copySync( source, destination );
-			}
+			let fileData = fs.readFileSync( source, 'utf8' );
+			fileData = fileData.replace( regexp, replaceFunction );
+			fs.writeFileSync( path.join( destination, path.basename( source ) ), fileData, 'utf8' );
 		} );
 	},
 

+ 8 - 2
dev/tests/dev/create-package.js

@@ -15,15 +15,17 @@ const inquiries = require( '../../tasks/dev/utils/inquiries' );
 const git = require( '../../tasks/dev/utils/git' );
 const path = require( 'path' );
 
-describe( 'dev-package-create', () => {
+describe( 'dev-create-package', () => {
 	let spies;
 
 	const mainRepositoryPath = '/path/to/repository';
 	const workspaceRoot = '..';
 	const workspacePath = path.join( mainRepositoryPath, workspaceRoot );
 	const packageName = 'package-name';
+	const applicationName = 'Full application name';
 	const packageVersion = '0.0.1';
 	const gitHubUrl = 'ckeditor5/package-name';
+	const packageDescription = 'Package description.';
 
 	beforeEach( () => createSpies() );
 	afterEach( () => restoreSpies() );
@@ -33,11 +35,13 @@ describe( 'dev-package-create', () => {
 			linkDirectories: sinon.stub( tools, 'linkDirectories' ),
 			npmInstall: sinon.stub( tools, 'npmInstall' ),
 			getPackageName: sinon.stub( inquiries, 'getPackageName' ).returns( new Promise( ( r ) => r( packageName ) ) ),
+			getApplicationName: sinon.stub( inquiries, 'getApplicationName' ).returns( new Promise( ( r ) => r( applicationName ) ) ),
 			getPackageVersion: sinon.stub( inquiries, 'getPackageVersion' ).returns( new Promise( ( r ) => r( packageVersion ) ) ),
 			getPackageGitHubUrl: sinon.stub( inquiries, 'getPackageGitHubUrl' ).returns( new Promise( ( r ) => r( gitHubUrl ) ) ),
+			getPackageDescription: sinon.stub( inquiries, 'getPackageDescription' ).returns( new Promise( ( r ) => r( packageDescription ) ) ),
 			initializeRepository: sinon.stub( git, 'initializeRepository' ),
 			updateJSONFile: sinon.stub( tools, 'updateJSONFile' ),
-			copy: sinon.stub( tools, 'copy' ),
+			copy: sinon.stub( tools, 'copyTemplateFiles' ),
 			initialCommit: sinon.stub( git, 'initialCommit' )
 		};
 	}
@@ -56,8 +60,10 @@ describe( 'dev-package-create', () => {
 	it( 'should create a package', () => {
 		return packageCreateTask( mainRepositoryPath, workspaceRoot ).then( () => {
 			expect( spies.getPackageName.calledOnce ).to.equal( true );
+			expect( spies.getApplicationName.calledOnce ).to.equal( true );
 			expect( spies.getPackageVersion.calledOnce ).to.equal( true );
 			expect( spies.getPackageGitHubUrl.calledOnce ).to.equal( true );
+			expect( spies.getPackageDescription.calledOnce ).to.equal( true );
 			expect( spies.initializeRepository.calledOnce ).to.equal( true );
 			expect( spies.initializeRepository.firstCall.args[ 0 ] ).to.equal( repositoryPath );
 			expect( spies.copy.called ).to.equal( true );

+ 24 - 33
dev/tests/dev/tools.js

@@ -366,44 +366,35 @@ describe( 'utils', () => {
 			} );
 		} );
 
-		describe( 'copy', () => {
-			it( 'should be defined', () => expect( tools.copy ).to.be.a( 'function' ) );
-			it( 'should copy files', () => {
-				const fs = require( 'fs-extra' );
+		describe( 'copyTemplateFiles', () => {
+			it( 'should be defined', () => expect( tools.copyTemplateFiles ).to.be.a( 'function' ) );
+			it( 'should copy files and replace provided texts', () => {
 				const path = require( 'path' );
-				let destination = 'destination';
-				let file = 'file.js';
-				sandbox.stub( fs, 'ensureDirSync' );
-				const copyStub = sandbox.stub( fs, 'copySync' );
-				sandbox.stub( tools, 'isFile', () => true );
-				sandbox.stub( tools, 'isDirectory', () => false );
-
-				tools.copy( [ file ], destination );
-
-				file = path.resolve( file );
-				destination = path.join( path.resolve( destination ), path.basename( file ) );
-
-				sinon.assert.calledOnce( copyStub );
-				sinon.assert.calledWithExactly( copyStub.firstCall, file, destination );
-			} );
-
-			it( 'should copy directories', () => {
 				const fs = require( 'fs-extra' );
-				const path = require( 'path' );
-				let destination = 'destination';
-				let dir = 'source';
-				sandbox.stub( fs, 'ensureDirSync' );
-				const copyStub = sandbox.stub( fs, 'copySync' );
-				sandbox.stub( tools, 'isFile', () => false );
-				sandbox.stub( tools, 'isDirectory', () => true );
 
-				tools.copy( [ dir ], destination );
+				const readFileStub = sandbox.stub( fs, 'readFileSync' );
+				readFileStub.onFirstCall().returns( 'file data {{var1}}, {{var2}}' );
+				readFileStub.onSecondCall().returns( '{{var1}}, {{var2}}, {{var2}}{{var1}}' );
 
-				dir = path.resolve( dir );
-				destination = path.resolve( destination );
+				const writeFileStub = sandbox.stub( fs, 'writeFileSync' );
+				const ensureDirStub = sandbox.stub( fs, 'ensureDirSync' );
+				const sources = [ '/path/to/file1.md', '/path/to/file2.md' ];
+				const destination = '/destination/path';
+
+				tools.copyTemplateFiles( sources, destination, {
+					'{{var1}}': 'foo',
+					'{{var2}}': 'bar'
+				} );
 
-				sinon.assert.calledOnce( copyStub );
-				sinon.assert.calledWithExactly( copyStub.firstCall, dir, destination );
+				sinon.assert.calledWithExactly( ensureDirStub, destination );
+				sinon.assert.calledTwice( readFileStub );
+				sinon.assert.calledWithExactly( readFileStub.firstCall, sources[ 0 ], 'utf8' );
+				sinon.assert.calledWithExactly( readFileStub.secondCall, sources[ 1 ], 'utf8' );
+				sinon.assert.calledTwice( writeFileStub );
+				let savePath = path.join( destination, path.basename( sources[ 0 ] ) );
+				sinon.assert.calledWithExactly( writeFileStub.firstCall, savePath, 'file data foo, bar', 'utf8' );
+				savePath = path.join( destination, path.basename( sources[ 1 ] ) );
+				sinon.assert.calledWithExactly( writeFileStub.secondCall, savePath, 'foo, bar, barfoo', 'utf8' );
 			} );
 		} );