plugin.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. 'use strict';
  2. var path = require( 'path' );
  3. var tools = require( './utils/tools' );
  4. var inquirer = require( 'inquirer' );
  5. var fs = require( 'fs' );
  6. var grunt;
  7. module.exports = function( g ) {
  8. grunt = g;
  9. grunt.registerTask( 'plugin', function( target ) {
  10. var done = this.async();
  11. switch ( target ) {
  12. case 'create':
  13. createNewPlugin( done );
  14. break;
  15. }
  16. } );
  17. };
  18. // Logs message using grunt.log.writeln.
  19. function log( message ) {
  20. grunt.log.writeln( message );
  21. }
  22. function createNewPlugin( done ) {
  23. var info = { };
  24. askForPluginName( info )
  25. .then( askForRepositoryLocation )
  26. .then( askForPluginVersion )
  27. .then( askForGitHubUrl )
  28. .then( createRepository )
  29. .then( updatePluginPackageJSON )
  30. .then( updatePackageJson )
  31. .then( linkNPM )
  32. .then( function() {
  33. done();
  34. } ).catch( function( e ) {
  35. done( e );
  36. } );
  37. }
  38. // Links new plugin directory using npm link.
  39. function linkNPM( info ) {
  40. // Don't use sudo on windows when executing npm link.
  41. var isWin = process.platform == 'win32';
  42. log( 'Linking plugin using npm link...' );
  43. return new Promise( function( resolve ) {
  44. tools.shExec( ( !isWin ? 'sudo ' : '' ) + 'npm link ' + info.repositoryLocation );
  45. resolve( info );
  46. } );
  47. }
  48. // Updates project's package.json by adding GitHub URL to dependencies.
  49. function updatePackageJson( info ) {
  50. return new Promise( function( resolve ) {
  51. changePackageJson( path.join( process.cwd(), 'package.json' ), function( json ) {
  52. json.dependencies[ info.pluginName ] = info.gitHubUrl;
  53. return json;
  54. } ).then( function() {
  55. resolve( info );
  56. } );
  57. } );
  58. }
  59. // Updates plugin package.json by adding name of the plugin and version.
  60. function updatePluginPackageJSON( info ) {
  61. return new Promise( function( resolve ) {
  62. var packageJSONPath = path.join( info.repositoryLocation, 'package.json' );
  63. changePackageJson( packageJSONPath, function( json ) {
  64. json.name = info.pluginName;
  65. json.version = info.version;
  66. return json;
  67. } ).then( function() {
  68. resolve( info );
  69. } );
  70. } );
  71. }
  72. // Initializes git repository and merges ckeditor5 boilerplate into master branch.
  73. function createRepository( info ) {
  74. log( 'Initializing plugin repository...' );
  75. return new Promise( function( resolve ) {
  76. var repositoryLocation = info.repositoryLocation;
  77. var initializeRepoCommands = [
  78. 'git init ' + repositoryLocation,
  79. 'cd ' + repositoryLocation,
  80. 'git remote add boilerplate git@github.com:ckeditor/ckeditor-boilerplate.git',
  81. 'git fetch boilerplate ckeditor5',
  82. 'git merge boilerplate/ckeditor5'
  83. ];
  84. tools.shExec( initializeRepoCommands.join( ' && ' ) );
  85. resolve( info );
  86. } );
  87. }
  88. // Ask for new plugin name.
  89. function askForPluginName( info ) {
  90. return new Promise( function( resolve ) {
  91. inquirer.prompt( [ {
  92. name: 'pluginName',
  93. message: 'Enter plugin name (without -ckeditor5-plugin postfix):',
  94. validate: function( input ) {
  95. var regexp = /^[a-zA-Z0-9-_]+$/;
  96. return regexp.test( input ) ? true : 'Please provide a valid plugin name.';
  97. }
  98. } ], function( answers ) {
  99. info.pluginName = answers.pluginName + '-ckeditor5-plugin';
  100. resolve( info );
  101. } );
  102. } );
  103. }
  104. // Ask for the location of the repository.
  105. function askForRepositoryLocation( info ) {
  106. var def = path.join( process.cwd(), '..', info.pluginName );
  107. return new Promise( function( resolve ) {
  108. inquirer.prompt( [ {
  109. name: 'path',
  110. message: 'Enter repository location:',
  111. default: def
  112. } ], function( answers ) {
  113. info.repositoryLocation = answers.path;
  114. resolve( info );
  115. } );
  116. } );
  117. }
  118. // Ask for initial version of the plugin.
  119. function askForPluginVersion( info ) {
  120. return new Promise( function( resolve ) {
  121. inquirer.prompt( [ {
  122. name: 'version',
  123. message: 'Enter plugin\'s initial version:',
  124. default: '0.0.1'
  125. } ], function( answers ) {
  126. info.version = answers.version;
  127. resolve( info );
  128. } );
  129. } );
  130. }
  131. // Ask for GitHub Url.
  132. function askForGitHubUrl( info ) {
  133. return new Promise( function( resolve ) {
  134. inquirer.prompt( [ {
  135. name: 'gitHubUrl',
  136. message: 'Enter plugin\'s GitHub URL:',
  137. default: 'ckeditor/' + info.pluginName
  138. } ], function( answers ) {
  139. info.gitHubUrl = answers.gitHubUrl;
  140. resolve( info );
  141. } );
  142. } );
  143. }
  144. // Changes given package.json.
  145. function changePackageJson( path, changeFn ) {
  146. return new Promise( function( resolve ) {
  147. fs.readFile( path, 'utf-8', function( err, file ) {
  148. var json;
  149. if ( err ) {
  150. throw err;
  151. }
  152. // Update package.json file.
  153. json = JSON.parse( file );
  154. json = changeFn( json );
  155. fs.writeFile( path, JSON.stringify( json, null, 2 ), 'utf-8', function( err ) {
  156. if ( err ) {
  157. throw err;
  158. }
  159. resolve( );
  160. } );
  161. } );
  162. } );
  163. }