plopfile.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. 'use strict';
  2. const path = require('path');
  3. module.exports = function (plop) {
  4. // starting prompt can be customized to display what you want
  5. // plop.setWelcomeMessage('[CUSTOM]'.yellow + ' What can I do for you?');
  6. // helpers are passed through handlebars syntax and made
  7. // available for use in the generator templates
  8. // adds 4 dashes around some text (yes es6/es2015 is supported)
  9. plop.addHelper('dashAround', (text) => '---- ' + text + ' ----');
  10. // formats an array of options like you would write
  11. // it, if you were speaking (one, two, and three)
  12. plop.addHelper('wordJoin', function (words) {
  13. return words.join(', ').replace(/(:?.*),/, '$1, and');
  14. });
  15. plop.addHelper('absPath', function (p) {
  16. return path.resolve(plop.getPlopfilePath(), p);
  17. });
  18. // greet the user using a partial
  19. plop.addPartial('salutation', '{{ greeting }}, my name is {{ properCase name }} and I am {{ age }}.');
  20. // load some additional helpers from a module installed using npm
  21. plop.load('plop-pack-fancy-comments', {
  22. prefix: '',
  23. upperCaseHeaders: true,
  24. commentStart: '',
  25. commentEnd: ''
  26. });
  27. const delayLog = msg => answers => new Promise((resolve) => {
  28. setTimeout(() => resolve(msg), 1000);
  29. });
  30. // setGenerator creates a generator that can be run with "plop generatorName"
  31. plop.setGenerator('test', {
  32. description: 'this is a test',
  33. prompts: [
  34. {
  35. type: 'input',
  36. name: 'name',
  37. message: 'What is your name?',
  38. validate: function (value) {
  39. if ((/.+/).test(value)) { return true; }
  40. return 'name is required';
  41. }
  42. }, {
  43. type: 'input',
  44. name: 'age',
  45. message: 'How old are you?',
  46. validate: function (value) {
  47. var digitsOnly = /\d+/;
  48. if (digitsOnly.test(value)) { return true; }
  49. return 'Invalid age! Must be a number genius!';
  50. }
  51. }, {
  52. type: 'checkbox',
  53. name: 'toppings',
  54. message: 'What pizza toppings do you like?',
  55. choices: [
  56. {name: 'Cheese', value: 'cheese', checked: true},
  57. {name: 'Pepperoni', value: 'pepperoni'},
  58. {name: 'Pineapple', value: 'pineapple'},
  59. {name: 'Mushroom', value: 'mushroom'},
  60. {name: 'Bacon', value: 'bacon', checked: true}
  61. ]
  62. }
  63. ],
  64. actions: [
  65. `this is a comment`,
  66. 'this is another comment',
  67. delayLog('delayed thing'),
  68. delayLog('another delayed thing'),
  69. delayLog('this was also delayed'),
  70. {
  71. type: 'add',
  72. path: 'folder/{{dashCase name}}.txt',
  73. templateFile: 'templates/temp.txt',
  74. abortOnFail: true
  75. },
  76. function customAction(answers) {
  77. // move the current working directory to the plop file path
  78. // this allows this action to work even when the generator is
  79. // executed from inside a subdirectory
  80. process.chdir(plop.getPlopfilePath());
  81. // custom function can be synchronous or async (by returning a promise)
  82. var fs = require('fs');
  83. var existsMsg = 'psst {{name}}, change-me.txt already exists';
  84. var copiedMsg = 'hey {{name}}, I copied change-me.txt for you';
  85. var changeFileName = 'change-me.txt';
  86. var changeFilePath = plop.getDestBasePath() + '/folder/' + changeFileName;
  87. // you can use plop.renderString to render templates
  88. existsMsg = plop.renderString(existsMsg, answers);
  89. copiedMsg = plop.renderString(copiedMsg, answers);
  90. if (fs.existsSync(changeFilePath)) {
  91. // returned value shows up in the console
  92. return existsMsg;
  93. } else {
  94. // do a synchronous copy via node fs
  95. fs.writeFileSync(changeFilePath, fs.readFileSync('templates/' + changeFileName));
  96. return copiedMsg;
  97. }
  98. },{
  99. type: 'modify',
  100. path: 'folder/change-me.txt',
  101. pattern: /(-- APPEND ITEMS HERE --)/gi,
  102. template: '$1\r\n{{name}}: {{age}}'
  103. },{
  104. type: 'modify',
  105. path: 'folder/change-me.txt',
  106. pattern: /(-- PREPEND ITEMS HERE --)/gi,
  107. templateFile: 'templates/part.txt'
  108. },{
  109. type: 'modify',
  110. path: 'folder/change-me.txt',
  111. pattern: /## replace name here ##/gi,
  112. template: 'replaced => {{dashCase name}}'
  113. },{
  114. type: 'modify',
  115. path: 'folder/change-me.txt',
  116. skip(data) {
  117. if (!data.toppings.includes('mushroom')) {
  118. // Skip this action
  119. return 'Skipped replacing mushrooms';
  120. } else {
  121. // Continue with this action
  122. return;
  123. }
  124. },
  125. transform(fileContents, data) {
  126. return fileContents.replace(/mushrooms/g, 'pepperoni');
  127. }
  128. },
  129. ]
  130. });
  131. // adding a custom inquirer prompt type
  132. plop.addPrompt('directory', require('inquirer-directory'));
  133. plop.setGenerator('custom-prompt', {
  134. description: 'custom inquirer prompt example',
  135. prompts: [
  136. {
  137. type: 'input',
  138. name: 'fileName',
  139. message: 'Pick a file name:',
  140. validate: function (value) {
  141. if ((/.+/).test(value)) { return true; }
  142. return 'file name is required';
  143. }
  144. }, {
  145. type: 'directory',
  146. name: 'path',
  147. message: 'where would you like to put this component?',
  148. basePath: plop.getPlopfilePath()
  149. }
  150. ],
  151. actions: [
  152. function(data) {
  153. console.log(data);
  154. return 'yay';
  155. }, {
  156. type: 'add',
  157. path: '{{absPath path}}/{{fileName}}.txt',
  158. template: '{{absPath path}}/{{fileName}} plopped!'
  159. }
  160. ]
  161. });
  162. // test with dynamic actions, regarding responses to prompts
  163. plop.setGenerator('dynamic actions', {
  164. description: 'another test using an actions function',
  165. prompts: [
  166. {
  167. type: 'input',
  168. name: 'name',
  169. message: 'What is your name?',
  170. validate: function (value) {
  171. if ((/.+/).test(value)) { return true; }
  172. return 'name is required';
  173. }
  174. }, {
  175. type: 'confirm',
  176. name: 'hasPotatoes',
  177. message: 'Do you want potatoes with your burger?'
  178. }
  179. ],
  180. actions: function(data) {
  181. var actions = [
  182. {
  183. type: 'add',
  184. path: 'folder/{{dashCase name}}-burger.txt',
  185. templateFile: 'templates/burger.txt',
  186. abortOnFail: true
  187. }
  188. ];
  189. if(data.hasPotatoes) {
  190. actions = actions.concat([
  191. {
  192. type: 'add',
  193. path: 'folder/{{dashCase name}}-potatoes.txt',
  194. templateFile: 'templates/potatoes.txt',
  195. abortOnFail: true
  196. },{
  197. type: 'modify',
  198. path: 'folder/{{dashCase name}}-burger.txt',
  199. pattern: /(!\n)/gi,
  200. template: '$1Your potatoes: {{dashCase name}}-potatoes.txt'
  201. }
  202. ]);
  203. }
  204. return actions;
  205. }
  206. });
  207. };