You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

330 lines
11 KiB

  1. /*******************************
  2. Create Component Repos
  3. *******************************/
  4. /*
  5. This will create individual component repositories for each SUI component
  6. * copy component files from release
  7. * create commonjs files as index.js for NPM release
  8. * create release notes that filter only items related to component
  9. * custom package.json file from template
  10. * create bower.json from template
  11. * create README from template
  12. * create meteor.js file
  13. */
  14. let
  15. gulp = require('gulp'),
  16. {series, parallel} = gulp,
  17. // node dependencies
  18. console = require('better-console'),
  19. del = require('del'),
  20. fs = require('fs'),
  21. path = require('path'),
  22. // admin dependencies
  23. concatFileNames = require('gulp-concat-filenames'),
  24. debug = require('gulp-debug'),
  25. flatten = require('gulp-flatten'),
  26. git = require('gulp-git'),
  27. jsonEditor = require('gulp-json-editor'),
  28. plumber = require('gulp-plumber'),
  29. rename = require('gulp-rename'),
  30. replace = require('gulp-replace'),
  31. tap = require('gulp-tap'),
  32. // config
  33. config = require('../../config/user'),
  34. release = require('../../config/admin/release'),
  35. project = require('../../config/project/release'),
  36. // shorthand
  37. version = project.version,
  38. output = config.paths.output
  39. ;
  40. let
  41. stream,
  42. index,
  43. tasks = []
  44. ;
  45. for(index in release.components) {
  46. let
  47. component = release.components[index]
  48. ;
  49. // streams... designed to save time and make coding fun...
  50. (function(component) {
  51. let
  52. outputDirectory = path.join(release.outputRoot, component),
  53. isJavascript = fs.existsSync(output.compressed + component + '.js'),
  54. isCSS = fs.existsSync(output.compressed + component + '.css'),
  55. capitalizedComponent = component.charAt(0).toUpperCase() + component.slice(1),
  56. packageName = release.packageRoot + component,
  57. repoName = release.componentRepoRoot + capitalizedComponent,
  58. gitURL = 'https://github.com/' + release.org + '/' + repoName + '.git',
  59. repoURL = 'https://github.com/' + release.org + '/' + repoName + '/',
  60. concatSettings = {
  61. newline : '',
  62. root : outputDirectory,
  63. prepend : " '",
  64. append : "',"
  65. },
  66. regExp = {
  67. match : {
  68. // templated values
  69. name : '{component}',
  70. titleName : '{Component}',
  71. version : '{version}',
  72. files : '{files}',
  73. // release notes
  74. spacedVersions : /(###.*\n)\n+(?=###)/gm,
  75. spacedLists : /(^- .*\n)\n+(?=^-)/gm,
  76. trim : /^\s+|\s+$/g,
  77. unrelatedNotes : new RegExp('^((?!(^.*(' + component + ').*$|###.*)).)*$', 'gmi'),
  78. whitespace : /\n\s*\n\s*\n/gm,
  79. // npm
  80. componentExport : /(.*)\$\.fn\.\w+\s*=\s*function\(([^\)]*)\)\s*{/g,
  81. componentReference: '$.fn.' + component,
  82. settingsExport : /\$\.fn\.\w+\.settings\s*=/g,
  83. settingsReference : /\$\.fn\.\w+\.settings/g,
  84. trailingComma : /,(?=[^,]*$)/,
  85. jQuery : /jQuery/g,
  86. },
  87. replace : {
  88. // readme
  89. name : component,
  90. titleName : capitalizedComponent,
  91. // release notes
  92. spacedVersions : '',
  93. spacedLists : '$1',
  94. trim : '',
  95. unrelatedNotes : '',
  96. whitespace : '\n\n',
  97. // npm
  98. componentExport : 'var _module = module;\n$1module.exports = function($2) {',
  99. componentReference: '_module.exports',
  100. settingsExport : 'module.exports.settings =',
  101. settingsReference : '_module.exports.settings',
  102. jQuery : 'require("jquery")'
  103. }
  104. },
  105. task = {
  106. all : component + ' creating',
  107. repo : component + ' create repo',
  108. bower : component + ' create bower.json',
  109. readme : component + ' create README',
  110. npm : component + ' create NPM Module',
  111. notes : component + ' create release notes',
  112. composer : component + ' create composer.json',
  113. package : component + ' create package.json',
  114. meteor : component + ' create meteor package.js',
  115. },
  116. // paths to includable assets
  117. manifest = {
  118. assets : outputDirectory + '/assets/**/' + component + '?(s).*',
  119. component : outputDirectory + '/' + component + '+(.js|.css)'
  120. }
  121. ;
  122. // copy dist files into output folder adjusting asset paths
  123. let repoTask = function() {
  124. console.info(component);
  125. console.info('---------------------');
  126. console.info('Copying dist files to component');
  127. return gulp.src(release.source + component + '.*')
  128. .pipe(plumber())
  129. .pipe(flatten())
  130. .pipe(replace(release.paths.source, release.paths.output))
  131. .pipe(gulp.dest(outputDirectory))
  132. ;
  133. };
  134. // create npm module
  135. let npmTask = function() {
  136. console.info('Creating index.js for npm');
  137. return gulp.src(release.source + component + '!(*.min|*.map).js')
  138. .pipe(plumber())
  139. .pipe(flatten())
  140. .pipe(replace(regExp.match.componentExport, regExp.replace.componentExport))
  141. .pipe(replace(regExp.match.componentReference, regExp.replace.componentReference))
  142. .pipe(replace(regExp.match.settingsExport, regExp.replace.settingsExport))
  143. .pipe(replace(regExp.match.settingsReference, regExp.replace.settingsReference))
  144. .pipe(replace(regExp.match.jQuery, regExp.replace.jQuery))
  145. .pipe(rename('index.js'))
  146. .pipe(gulp.dest(outputDirectory))
  147. ;
  148. };
  149. // create readme
  150. let readmeTask = function() {
  151. console.info('Creating readme');
  152. return gulp.src(release.templates.readme)
  153. .pipe(plumber())
  154. .pipe(flatten())
  155. .pipe(replace(regExp.match.name, regExp.replace.name))
  156. .pipe(replace(regExp.match.titleName, regExp.replace.titleName))
  157. .pipe(gulp.dest(outputDirectory))
  158. ;
  159. };
  160. // extend bower.json
  161. let bowerTask = function() {
  162. console.info('Extending bower.json');
  163. return gulp.src(release.templates.bower)
  164. .pipe(plumber())
  165. .pipe(flatten())
  166. .pipe(jsonEditor(function(bower) {
  167. bower.name = packageName;
  168. bower.description = capitalizedComponent + ' - Semantic UI';
  169. if(isJavascript) {
  170. if(isCSS) {
  171. bower.main = [
  172. component + '.js',
  173. component + '.css'
  174. ];
  175. }
  176. else {
  177. bower.main = [
  178. component + '.js'
  179. ];
  180. }
  181. bower.dependencies = {
  182. jquery: '>=1.8'
  183. };
  184. }
  185. else {
  186. bower.main = [
  187. component + '.css'
  188. ];
  189. }
  190. return bower;
  191. }))
  192. .pipe(gulp.dest(outputDirectory))
  193. ;
  194. };
  195. // extend package.json
  196. let packageTask = function() {
  197. console.info('Extending package.json');
  198. return gulp.src(release.templates.package)
  199. .pipe(plumber())
  200. .pipe(flatten())
  201. .pipe(jsonEditor(function(npm) {
  202. if(isJavascript) {
  203. npm.dependencies = {
  204. jquery: 'x.x.x'
  205. };
  206. npm.main = 'index.js';
  207. }
  208. npm.name = packageName;
  209. if(version) {
  210. npm.version = version;
  211. }
  212. npm.title = 'Semantic UI - ' + capitalizedComponent;
  213. npm.description = 'Single component release of ' + component;
  214. npm.repository = {
  215. type : 'git',
  216. url : gitURL
  217. };
  218. return npm;
  219. }))
  220. .pipe(gulp.dest(outputDirectory))
  221. ;
  222. };
  223. // extend composer.json
  224. let composeTask = function() {
  225. console.info('Extending composer.json');
  226. return gulp.src(release.templates.composer)
  227. .pipe(plumber())
  228. .pipe(flatten())
  229. .pipe(jsonEditor(function(composer) {
  230. if(isJavascript) {
  231. composer.dependencies = {
  232. jquery: 'x.x.x'
  233. };
  234. composer.main = component + '.js';
  235. }
  236. composer.name = 'semantic/' + component;
  237. if(version) {
  238. composer.version = version;
  239. }
  240. composer.description = 'Single component release of ' + component;
  241. return composer;
  242. }))
  243. .pipe(gulp.dest(outputDirectory))
  244. ;
  245. };
  246. // create release notes
  247. let releateNotesTask = function() {
  248. return gulp.src(release.templates.notes)
  249. .pipe(plumber())
  250. .pipe(flatten())
  251. // Remove release notes for lines not mentioning component
  252. .pipe(replace(regExp.match.unrelatedNotes, regExp.replace.unrelatedNotes))
  253. .pipe(replace(regExp.match.whitespace, regExp.replace.whitespace))
  254. .pipe(replace(regExp.match.spacedVersions, regExp.replace.spacedVersions))
  255. .pipe(replace(regExp.match.spacedLists, regExp.replace.spacedLists))
  256. .pipe(replace(regExp.match.trim, regExp.replace.trim))
  257. .pipe(gulp.dest(outputDirectory))
  258. ;
  259. };
  260. // Creates meteor package.js
  261. let meteorTask = function() {
  262. console.info('Handling meteor release');
  263. let
  264. filenames = ''
  265. ;
  266. return gulp.src(manifest.component)
  267. .pipe(concatFileNames('empty.txt', concatSettings))
  268. .pipe(tap(function(file) {
  269. filenames += file.contents;
  270. }))
  271. .on('end', function() {
  272. gulp.src(manifest.assets)
  273. .pipe(concatFileNames('empty.txt', concatSettings))
  274. .pipe(tap(function(file) {
  275. filenames += file.contents;
  276. }))
  277. .on('end', function() {
  278. // remove trailing slash
  279. filenames = filenames.replace(regExp.match.trailingComma, '').trim();
  280. gulp.src(release.templates.meteor.component)
  281. .pipe(plumber())
  282. .pipe(flatten())
  283. .pipe(replace(regExp.match.name, regExp.replace.name))
  284. .pipe(replace(regExp.match.titleName, regExp.replace.titleName))
  285. .pipe(replace(regExp.match.version, version))
  286. .pipe(replace(regExp.match.files, filenames))
  287. .pipe(rename(release.files.meteor))
  288. .pipe(gulp.dest(outputDirectory))
  289. ;
  290. })
  291. ;
  292. })
  293. ;
  294. };
  295. tasks.push(repoTask);
  296. tasks.push(npmTask);
  297. tasks.push(readmeTask);
  298. tasks.push(bowerTask);
  299. tasks.push(packageTask);
  300. tasks.push(composeTask);
  301. tasks.push(releateNotesTask);
  302. tasks.push(meteorTask);
  303. })(component);
  304. }
  305. module.exports = series(tasks);