| /******************************* |
| Install Task |
| *******************************/ |
| |
| /* |
| Install tasks |
| |
| For more notes |
| |
| * Runs automatically after npm update (hooks) |
| * (NPM) Install - Will ask for where to put semantic (outside pm folder) |
| * (NPM) Upgrade - Will look for semantic install, copy over files and update if new version |
| * Standard installer runs asking for paths to site files etc |
| |
| */ |
| |
| var |
| gulp = require('gulp'), |
| |
| // node dependencies |
| console = require('better-console'), |
| extend = require('extend'), |
| fs = require('fs'), |
| mkdirp = require('mkdirp'), |
| path = require('path'), |
| runSequence = require('run-sequence'), |
| |
| // gulp dependencies |
| chmod = require('gulp-chmod'), |
| del = require('del'), |
| jsonEditor = require('gulp-json-editor'), |
| plumber = require('gulp-plumber'), |
| prompt = require('gulp-prompt'), |
| rename = require('gulp-rename'), |
| replace = require('gulp-replace'), |
| requireDotFile = require('require-dot-file'), |
| wrench = require('wrench'), |
| |
| // install config |
| install = require('./config/project/install'), |
| |
| // user config |
| config = require('./config/user'), |
| |
| // release config (name/title/etc) |
| release = require('./config/project/release'), |
| |
| // shorthand |
| questions = install.questions, |
| files = install.files, |
| folders = install.folders, |
| regExp = install.regExp, |
| settings = install.settings, |
| source = install.source |
| ; |
| |
| // Export install task |
| module.exports = function (callback) { |
| |
| var |
| currentConfig = requireDotFile('semantic.json'), |
| manager = install.getPackageManager(), |
| rootQuestions = questions.root, |
| installFolder = false, |
| answers |
| ; |
| |
| console.clear(); |
| |
| /* Test NPM install |
| manager = { |
| name : 'NPM', |
| root : path.normalize(__dirname + '/../') |
| }; |
| */ |
| |
| |
| /* Don't do end user config if SUI is a sub-module */ |
| if( install.isSubModule() ) { |
| console.info('SUI is a sub-module, skipping end-user install'); |
| return; |
| } |
| |
| /*----------------- |
| Update SUI |
| -----------------*/ |
| |
| // run update scripts if semantic.json exists |
| if(currentConfig && manager.name === 'NPM') { |
| |
| var |
| updateFolder = path.join(manager.root, currentConfig.base), |
| updatePaths = { |
| config : path.join(manager.root, files.config), |
| tasks : path.join(updateFolder, folders.tasks), |
| themeImport : path.join(updateFolder, folders.themeImport), |
| definition : path.join(currentConfig.paths.source.definitions), |
| site : path.join(currentConfig.paths.source.site), |
| theme : path.join(currentConfig.paths.source.themes), |
| defaultTheme : path.join(currentConfig.paths.source.themes, folders.defaultTheme) |
| } |
| ; |
| |
| // duck-type if there is a project installed |
| if( fs.existsSync(updatePaths.definition) ) { |
| |
| // perform update if new version |
| if(currentConfig.version !== release.version) { |
| console.log('Updating Semantic UI from ' + currentConfig.version + ' to ' + release.version); |
| |
| console.info('Updating ui definitions...'); |
| wrench.copyDirSyncRecursive(source.definitions, updatePaths.definition, settings.wrench.overwrite); |
| |
| console.info('Updating default theme...'); |
| wrench.copyDirSyncRecursive(source.themes, updatePaths.theme, settings.wrench.merge); |
| wrench.copyDirSyncRecursive(source.defaultTheme, updatePaths.defaultTheme, settings.wrench.overwrite); |
| |
| console.info('Updating tasks...'); |
| wrench.copyDirSyncRecursive(source.tasks, updatePaths.tasks, settings.wrench.overwrite); |
| |
| console.info('Updating gulpfile.js'); |
| gulp.src(source.userGulpFile) |
| .pipe(plumber()) |
| .pipe(gulp.dest(updateFolder)) |
| ; |
| |
| // copy theme import |
| console.info('Updating theme import file'); |
| gulp.src(source.themeImport) |
| .pipe(plumber()) |
| .pipe(gulp.dest(updatePaths.themeImport)) |
| ; |
| |
| console.info('Adding new site theme files...'); |
| wrench.copyDirSyncRecursive(source.site, updatePaths.site, settings.wrench.merge); |
| |
| console.info('Updating version...'); |
| |
| // update version number in semantic.json |
| gulp.src(updatePaths.config) |
| .pipe(plumber()) |
| .pipe(rename(settings.rename.json)) // preserve file extension |
| .pipe(jsonEditor({ |
| version: release.version |
| })) |
| .pipe(gulp.dest(manager.root)) |
| ; |
| |
| console.info('Update complete! Run "\x1b[92mgulp build\x1b[0m" to rebuild dist/ files.'); |
| |
| return; |
| } |
| else { |
| console.log('Current version of Semantic UI already installed'); |
| return; |
| } |
| |
| } |
| else { |
| console.error('Cannot locate files to update at path: ', updatePaths.definition); |
| console.log('Running installer'); |
| } |
| |
| } |
| |
| /*-------------- |
| Determine Root |
| ---------------*/ |
| |
| // PM that supports Build Tools (NPM Only Now) |
| if(manager.name == 'NPM') { |
| rootQuestions[0].message = rootQuestions[0].message |
| .replace('{packageMessage}', 'We detected you are using \x1b[92m' + manager.name + '\x1b[0m. Nice! ') |
| .replace('{root}', manager.root) |
| ; |
| // set default path to detected PM root |
| rootQuestions[0].default = manager.root; |
| rootQuestions[1].default = manager.root; |
| |
| // insert PM questions after "Install Type" question |
| Array.prototype.splice.apply(questions.setup, [2, 0].concat(rootQuestions)); |
| |
| // omit cleanup questions for managed install |
| questions.cleanup = []; |
| } |
| |
| |
| /*-------------- |
| Create SUI |
| ---------------*/ |
| |
| gulp.task('run setup', function() { |
| |
| // If auto-install is switched on, we skip the configuration section and simply reuse the configuration from semantic.json |
| if(install.shouldAutoInstall()) { |
| answers = { |
| overwrite : 'yes', |
| install : 'auto', |
| }; |
| } |
| else { |
| return gulp |
| .src('gulpfile.js') |
| .pipe(prompt.prompt(questions.setup, function(setupAnswers) { |
| // hoist |
| answers = setupAnswers; |
| })) |
| ; |
| } |
| }); |
| |
| gulp.task('create install files', function(callback) { |
| |
| /*-------------- |
| Exit Conditions |
| ---------------*/ |
| |
| // if config exists and user specifies not to proceed |
| if(answers.overwrite !== undefined && answers.overwrite == 'no') { |
| return; |
| } |
| console.clear(); |
| if(install.shouldAutoInstall()) { |
| console.log('Auto-Installing (Without User Interaction)'); |
| } |
| else { |
| console.log('Installing'); |
| } |
| console.log('------------------------------'); |
| |
| |
| /*-------------- |
| Paths |
| ---------------*/ |
| |
| var |
| installPaths = { |
| config : files.config, |
| configFolder : folders.config, |
| site : answers.site || folders.site, |
| themeConfig : files.themeConfig, |
| themeConfigFolder : folders.themeConfig |
| } |
| ; |
| |
| /*-------------- |
| NPM Install |
| ---------------*/ |
| |
| // Check if PM install |
| if(answers.useRoot || answers.customRoot) { |
| |
| // Set root to custom root path if set |
| if(answers.customRoot) { |
| if(answers.customRoot === '') { |
| console.log('Unable to proceed, invalid project root'); |
| return; |
| } |
| manager.root = answers.customRoot; |
| } |
| |
| // special install paths only for PM install |
| installPaths = extend(false, {}, installPaths, { |
| definition : folders.definitions, |
| lessImport : folders.lessImport, |
| tasks : folders.tasks, |
| theme : folders.themes, |
| defaultTheme : path.join(folders.themes, folders.defaultTheme), |
| themeImport : folders.themeImport |
| }); |
| |
| // add project root to semantic root |
| installFolder = path.join(manager.root, answers.semanticRoot); |
| |
| // add install folder to all output paths |
| for(var destination in installPaths) { |
| if( installPaths.hasOwnProperty(destination) ) { |
| // config goes in project root, rest in install folder |
| installPaths[destination] = (destination == 'config' || destination == 'configFolder') |
| ? path.normalize( path.join(manager.root, installPaths[destination]) ) |
| : path.normalize( path.join(installFolder, installPaths[destination]) ) |
| ; |
| } |
| } |
| |
| // create project folders |
| try { |
| mkdirp.sync(installFolder); |
| mkdirp.sync(installPaths.definition); |
| mkdirp.sync(installPaths.theme); |
| mkdirp.sync(installPaths.tasks); |
| } |
| catch(error) { |
| console.error('NPM does not have permissions to create folders at your specified path. Adjust your folders permissions and run "npm install" again'); |
| } |
| |
| console.log('Installing to \x1b[92m' + answers.semanticRoot + '\x1b[0m'); |
| |
| console.info('Copying UI definitions'); |
| wrench.copyDirSyncRecursive(source.definitions, installPaths.definition, settings.wrench.overwrite); |
| |
| console.info('Copying UI themes'); |
| wrench.copyDirSyncRecursive(source.themes, installPaths.theme, settings.wrench.merge); |
| wrench.copyDirSyncRecursive(source.defaultTheme, installPaths.defaultTheme, settings.wrench.overwrite); |
| |
| console.info('Copying gulp tasks'); |
| wrench.copyDirSyncRecursive(source.tasks, installPaths.tasks, settings.wrench.overwrite); |
| |
| // copy theme import |
| console.info('Adding theme files'); |
| gulp.src(source.themeImport) |
| .pipe(plumber()) |
| .pipe(gulp.dest(installPaths.themeImport)) |
| ; |
| gulp.src(source.lessImport) |
| .pipe(plumber()) |
| .pipe(gulp.dest(installPaths.lessImport)) |
| ; |
| |
| // create gulp file |
| console.info('Creating gulpfile.js'); |
| gulp.src(source.userGulpFile) |
| .pipe(plumber()) |
| .pipe(gulp.dest(installFolder)) |
| ; |
| |
| } |
| |
| |
| /*-------------- |
| Site Theme |
| ---------------*/ |
| |
| // Copy _site templates folder to destination |
| if( fs.existsSync(installPaths.site) ) { |
| console.info('Site folder exists, merging files (no overwrite)', installPaths.site); |
| } |
| else { |
| console.info('Creating site theme folder', installPaths.site); |
| } |
| wrench.copyDirSyncRecursive(source.site, installPaths.site, settings.wrench.merge); |
| |
| /*-------------- |
| Theme Config |
| ---------------*/ |
| |
| gulp.task('create theme.config', function() { |
| var |
| // determine path to site theme folder from theme config |
| // force CSS path variable to use forward slashes for paths |
| pathToSite = path.relative(path.resolve(installPaths.themeConfigFolder), path.resolve(installPaths.site)).replace(/\\/g,'/'), |
| siteVariable = "@siteFolder : '" + pathToSite + "/';" |
| ; |
| |
| // rewrite site variable in theme.less |
| console.info('Adjusting @siteFolder to: ', pathToSite + '/'); |
| |
| if(fs.existsSync(installPaths.themeConfig)) { |
| console.info('Modifying src/theme.config (LESS config)', installPaths.themeConfig); |
| return gulp.src(installPaths.themeConfig) |
| .pipe(plumber()) |
| .pipe(replace(regExp.siteVariable, siteVariable)) |
| .pipe(gulp.dest(installPaths.themeConfigFolder)) |
| ; |
| } |
| else { |
| console.info('Creating src/theme.config (LESS config)', installPaths.themeConfig); |
| return gulp.src(source.themeConfig) |
| .pipe(plumber()) |
| .pipe(rename({ extname : '' })) |
| .pipe(replace(regExp.siteVariable, siteVariable)) |
| .pipe(gulp.dest(installPaths.themeConfigFolder)) |
| ; |
| } |
| }); |
| |
| /*-------------- |
| Semantic.json |
| ---------------*/ |
| |
| gulp.task('create semantic.json', function() { |
| |
| var |
| jsonConfig = install.createJSON(answers) |
| ; |
| |
| // adjust variables in theme.less |
| if( fs.existsSync(files.config) ) { |
| console.info('Extending config file (semantic.json)', installPaths.config); |
| return gulp.src(installPaths.config) |
| .pipe(plumber()) |
| .pipe(rename(settings.rename.json)) // preserve file extension |
| .pipe(jsonEditor(jsonConfig)) |
| .pipe(gulp.dest(installPaths.configFolder)) |
| ; |
| } |
| else { |
| console.info('Creating config file (semantic.json)', installPaths.config); |
| return gulp.src(source.config) |
| .pipe(plumber()) |
| .pipe(rename({ extname : '' })) // remove .template from ext |
| .pipe(jsonEditor(jsonConfig)) |
| .pipe(gulp.dest(installPaths.configFolder)) |
| ; |
| } |
| |
| }); |
| |
| runSequence( |
| 'create theme.config', |
| 'create semantic.json', |
| callback |
| ); |
| |
| }); |
| |
| gulp.task('clean up install', function() { |
| |
| // Completion Message |
| if(installFolder) { |
| console.log('\n Setup Complete! \n Installing Peer Dependencies. \x1b[0;31mPlease refrain from ctrl + c\x1b[0m... \n After completion navigate to \x1b[92m' + answers.semanticRoot + '\x1b[0m and run "\x1b[92mgulp build\x1b[0m" to build'); |
| process.exit(0); |
| } |
| else { |
| console.log(''); |
| console.log(''); |
| } |
| |
| // If auto-install is switched on, we skip the configuration section and simply build the dependencies |
| if(install.shouldAutoInstall()) { |
| return gulp.start('build'); |
| } |
| else { |
| return gulp |
| .src('gulpfile.js') |
| .pipe(prompt.prompt(questions.cleanup, function(answers) { |
| if(answers.cleanup == 'yes') { |
| del(install.setupFiles); |
| } |
| if(answers.build == 'yes') { |
| gulp.start('build'); |
| } |
| })) |
| ; |
| } |
| |
| |
| }); |
| |
| runSequence( |
| 'run setup', |
| 'create install files', |
| 'clean up install', |
| callback |
| ); |
| |
| }; |