plugin.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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. log( 'Linking plugin using npm link...' );
  41. return new Promise( function( resolve ) {
  42. tools.shExec( 'sudo npm link ' + info.repositoryLocation );
  43. resolve( info );
  44. } );
  45. }
  46. // Updates project's package.json by adding GitHub URL to dependencies.
  47. function updatePackageJson( info ) {
  48. return new Promise( function( resolve ) {
  49. changePackageJson( path.join( process.cwd(), 'package.json' ), function( json ) {
  50. json.dependencies[ info.pluginName ] = info.gitHubUrl;
  51. return json;
  52. } ).then( function() {
  53. resolve( info );
  54. } );
  55. } );
  56. }
  57. // Updates plugin package.json by adding name of the plugin and version.
  58. function updatePluginPackageJSON( info ) {
  59. return new Promise( function( resolve ) {
  60. var packageJSONPath = path.join( info.repositoryLocation, 'package.json' );
  61. changePackageJson( packageJSONPath, function( json ) {
  62. json.name = info.pluginName;
  63. json.version = info.version;
  64. return json;
  65. } ).then( function() {
  66. resolve( info );
  67. } );
  68. } );
  69. }
  70. // Initializes git repository and merges ckeditor5 boilerplate into master branch.
  71. function createRepository( info ) {
  72. log( 'Initializing plugin repository...' );
  73. return new Promise( function( resolve ) {
  74. var repositoryLocation = info.repositoryLocation;
  75. var initializeRepoCommands = [
  76. 'git init ' + repositoryLocation,
  77. 'cd ' + repositoryLocation,
  78. 'git remote add boilerplate git@github.com:ckeditor/ckeditor-boilerplate.git',
  79. 'git fetch boilerplate ckeditor5',
  80. 'git merge boilerplate/ckeditor5'
  81. ];
  82. tools.shExec( initializeRepoCommands.join( ' && ' ) );
  83. resolve( info );
  84. } );
  85. }
  86. // Ask for new plugin name.
  87. function askForPluginName( info ) {
  88. return new Promise( function( resolve ) {
  89. inquirer.prompt( [ {
  90. name: 'pluginName',
  91. message: 'Enter plugin name (without -ckeditor5-plugin postfix):',
  92. validate: function( input ) {
  93. var regexp = /^[a-zA-Z0-9-_]+$/;
  94. return regexp.test( input ) ? true : 'Please provide a valid plugin name.';
  95. }
  96. } ], function( answers ) {
  97. info.pluginName = answers.pluginName + '-ckeditor5-plugin';
  98. resolve( info );
  99. } );
  100. } );
  101. }
  102. // Ask for the location of the repository.
  103. function askForRepositoryLocation( info ) {
  104. var def = path.join( process.cwd(), '..', info.pluginName );
  105. return new Promise( function( resolve ) {
  106. inquirer.prompt( [ {
  107. name: 'path',
  108. message: 'Enter repository location:',
  109. default: def
  110. } ], function( answers ) {
  111. info.repositoryLocation = answers.path;
  112. resolve( info );
  113. } );
  114. } );
  115. }
  116. // Ask for initial version of the plugin.
  117. function askForPluginVersion( info ) {
  118. return new Promise( function( resolve ) {
  119. inquirer.prompt( [ {
  120. name: 'version',
  121. message: 'Enter plugin\'s initial version:',
  122. default: '0.0.1'
  123. } ], function( answers ) {
  124. info.version = answers.version;
  125. resolve( info );
  126. } );
  127. } );
  128. }
  129. // Ask for GitHub Url.
  130. function askForGitHubUrl( info ) {
  131. return new Promise( function( resolve ) {
  132. inquirer.prompt( [ {
  133. name: 'gitHubUrl',
  134. message: 'Enter plugin\'s GitHub URL:',
  135. default: 'ckeditor/' + info.pluginName
  136. } ], function( answers ) {
  137. info.gitHubUrl = answers.gitHubUrl;
  138. resolve( info );
  139. } );
  140. } );
  141. }
  142. // Changes given package.json.
  143. function changePackageJson( path, changeFn ) {
  144. return new Promise( function( resolve ) {
  145. fs.readFile( path, 'utf-8', function( err, file ) {
  146. var json;
  147. if ( err ) {
  148. throw err;
  149. }
  150. // Update package.json file.
  151. json = JSON.parse( file );
  152. json = changeFn( json );
  153. fs.writeFile( path, JSON.stringify( json, null, 2 ), 'utf-8', function( err ) {
  154. if ( err ) {
  155. throw err;
  156. }
  157. resolve( );
  158. } );
  159. } );
  160. } );
  161. }