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