UNPKG

lithium-sdk

Version:
652 lines (578 loc) 22.3 kB
/** * Library methods for generating stubs * * @author jaker */ 'use strict'; var expect = require('gulp-expect-file'); var extend = require('gulp-extend'); var fs = require('fs'); var http = require('http'); var merge = require('merge-stream'); var path = require('path'); var rename = require('gulp-rename'); var spawnSeries = require('spawn-series'); var template = require('gulp-template'); var inquirer = require('inquirer'); var through = require('through2').obj; var prettyTime = require('pretty-hrtime'); var is = require('is_js'); var gulpif = require('gulp-if'); module.exports = function (gulp, gutil) { var skinLib = require('./skin')(gulp, gutil); function logFile() { function decorate(color, text) { return text ? '[' + gutil.colors[color](text) + ']' : ''; } var stream = through(function (file, enc, callback) { var items = []; items.push(gutil.colors.cyan(file.path)); if (file.isDirectory()) { items.push(decorate('magenta', 'DIR')); } else if (file.isNull()) { items.push(decorate('magenta', 'EMPTY')); } gutil.log(items.join(' ')); this.push(file); return callback(); }); stream.resume(); return stream; } function validate(value, regex, allowEmpty) { if (value === '') { if (allowEmpty) { return true; } else { return 'Please provide a valid value'; } } var cases = value.match(regex); if (cases === null) { return 'Invalid value, please try again.'; } else { return true; } } function npmLinkAndInstall(cwd, callback) { /** * Attempt to npm link global packages. * This may fail because of permissions, if it fails packages * will be installed locally using npm install */ spawnSeries( [ { command: 'npm', args: ['link', require('../package.json').name], options: { cwd: cwd, ignoreError: true, stdio: 'inherit' } }, { command: 'npm', args: ['link', 'gulp'], options: { cwd: cwd, ignoreError: true, stdio: 'inherit' } }, { command: 'npm', args: ['install'], options: { cwd: cwd, stdio: 'inherit' } } ], callback, function (child, i, cmdObj) { gutil.log(gutil.colors.blue('Starting: ' + cmdObj.command + ' ' + cmdObj.args.join(' '))); child.on('close', function (code) { if (code === 0) { gutil.log(gutil.colors.blue('Finished: ' + cmdObj.command + ' ' + cmdObj.args.join(' '))); } else if (cmdObj.options.ignoreError) { gutil.log(gutil.colors.red('Failed: ' + cmdObj.command + ' ' + cmdObj.args.join(' '))); gutil.log(gutil.colors.blue('Ignoring error and continuing (Package will be installed in npm install) ..')); } }); } ); } function parseVersionPage(page) { var start = page.lastIndexOf('<body>'); var end = page.lastIndexOf('</body>'); var body = page.substring(start + 6, end); var versionArr = body.split(' '); var revision; if (versionArr.length > 2) { revision = versionArr[2].replace(')', ''); } return { version: versionArr[0], branch: versionArr[1].replace('(', ''), revision: revision }; } function bowerInstall(cwd, callback) { spawnSeries( [ { command: 'bower', args: ['install'], options: { cwd: cwd, stdio: 'inherit' } } ], callback, function (child, i, cmdObj) { gutil.log(gutil.colors.blue('Starting: ' + cmdObj.command + ' ' + cmdObj.args.join(' '))); child.on('close', function () { gutil.log(gutil.colors.blue('Finished: ' + cmdObj.command + ' ' + cmdObj.args.join(' '))); }); } ); } var templateConstraint = function(file) { return path.basename(file.path) !== 'README.md'; }; return { scaffold: function () { var ops = { serverConf: {} }; inquirer.prompt([ { type: 'input', name: 'name', message: 'What is your repository name?\nOnly lower case characters, numbers or hyphens (-) are allowed.', validate: function (val) { return validate(val, /^[a-z0-9\-]+$/); } }, { type: 'confirm', name: 'continue', message: 'Do you want to continue?', when: function (repo) { if (fs.existsSync(path.join('.', repo.name))) { console.log(gutil.colors.red(gutil.colors.bold(repo.name) + ' already exists in ' + process.cwd() + '.' + '\nTo update the project please "li update" from root directory of the project.' + '\nTo recreate the project please delete the existing project and then re-run "li create"')); process.exit(1); return true; } else { return false; } }, default: true }, { type: 'input', name: 'serverUrl', message: function () { return 'What is the URL (include port if exists) to the dev/stage site that you will connect to ' + '(beginning with "https://")?'; }, validate: function (val) { return validate(val, /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)/); } }, { type: 'input', name: 'pluginToken', message: function () { return 'Do you have a plugin token (if not press enter)?'; }, validate: function (val) { return validate(val, /^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$/, true); }, default: function () { return ''; } } ], function (answers) { // set up vars for server.conf.json ops.serverConf.serverUrl = answers.serverUrl; if (answers.pluginToken) { ops.serverConf.pluginToken = answers.pluginToken; } //default studio overrides allowed ops.serverConf.allowStudioOverrides = true; //default strict mode false ops.serverConf.strictMode = false; //default dry run mode false ops.serverConf.dryRun = false; //default verbose false ops.serverConf.verbose = false; //default force false ops.serverConf.force = false; //default pluginPoints ops.serverConf.pluginPoints = []; //defaults for sass support ops.serverConf.useResponsiveConfigsFromServer = true; ops.serverConf.useLocalCompile = true; //default skipTemplateValidation to false ops.serverConf.skipTemplateValidation = false; ops.name = answers.name; ops.description = 'lithium-sdk project: ' + answers.name + '\nGenerated by ' + process.env.USER; ops.version = require('../package.json').version; // copy and process templates var checkResponseCallback = function() { gulp.src(path.join(__dirname, '../templates/project/**/*')) .pipe(rename(function (path) { if (path.basename.indexOf('_') === 0) { path.basename = path.basename.replace('_', ''); } })) .pipe(gulpif(templateConstraint, template(ops))) .pipe(rename(function (path) { if (path.extname === '.mdt') { path.extname = '.md'; } })) .pipe(gulp.dest('./' + answers.name)) .pipe(logFile()) .on('end', function () { // once templates are finished, create server.conf.json fs.writeFile(path.join('.', answers.name, 'server.conf.json'), JSON.stringify(ops.serverConf, null, 2), function (error) { if (error) { throw error; } else { gutil.log(gutil.colors.cyan(path.resolve(path.join('.', answers.name, 'server.conf.json')))); // npm link and install npmLinkAndInstall(path.join('.', answers.name), function (code) { if (code === 0) { gutil.log(gutil.colors.green('Created ' + answers.name)); } else { gutil.log(gutil.colors.red('Error while creating ' + answers.name)); } }); } }); }); }; answers.debugMode = gutil.env['debug']; //Check server version before processing the templates require('./version-check.js')(gulp, gutil).validate(answers.serverUrl, answers.pluginToken, answers, checkResponseCallback); }); }, update: function (cb) { var ops = { serverConf: {} }; try { ops.serverConf = require(path.join(process.cwd(), 'server.conf.json')); } catch (err) { console.log('Your project may be corrupt.\nPlease delete try recreating the project using "li create"'); process.exit(1); } inquirer.prompt([ { type: 'input', name: 'serverUrl', message: function () { return 'Enter the new URL (include port if exists) to the dev/stage site that you will connect to (beginning with "http") or press enter to use existing'; }, validate: function (val) { return validate(val, /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)/); }, default: function () { return ops.serverConf.serverUrl; } }, { type: 'input', name: 'pluginToken', message: function () { if (ops.serverConf.pluginToken) { return 'Enter plugin token to change it or press enter to continue'; } else { return 'Do you have a plugin token (if not press enter)?'; } }, validate: function (val) { return validate(val, /^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$/, true); }, default: function () { return ops.serverConf.pluginToken || ''; } } ], function (answers) { // set up vars for server.conf.json ops.serverConf.serverUrl = answers.serverUrl; if (answers.pluginToken) { ops.serverConf.pluginToken = answers.pluginToken; } //defaults for sass support ops.serverConf.useResponsiveConfigsFromServer = true; ops.serverConf.useLocalCompile = true; answers.name = process.cwd().split(path.normalize('/')).pop(); ops.name = answers.name; ops.description = 'lithium-sdk project: ' + answers.name + '\nGenerated by ' + process.env.USER; ops.version = require('../package.json').version; // copy and process templates var checkResponseCallback = function() { gulp.src([path.join(__dirname, '../templates/project/**/*'), '!' + path.join(__dirname, '../templates/project/sdk.conf.json'), '!' + path.join(__dirname, '../templates/project/_.gitignore')]) .pipe(rename(function (path) { if (path.basename.indexOf('_') === 0) { path.basename = path.basename.replace('_', ''); } })) .pipe(gulpif(templateConstraint, template(ops))) .pipe(rename(function (path) { if (path.extname === '.mdt') { path.extname = '.md'; } })) .pipe(gulp.dest('.')) .pipe(logFile()) .on('end', function () { // once templates are finished, create server.conf.json fs.writeFile(path.join('.', 'server.conf.json'), JSON.stringify(ops.serverConf, null, 2), function (error) { if (error) { cb(error); } else { gutil.log(gutil.colors.cyan(path.resolve('./server.conf.json'))); // npm link and install npmLinkAndInstall('./', function (code) { if (code === 0) { gutil.log(gutil.colors.green('Project updated!')); cb(); } else { gutil.log(gutil.colors.red('Error while updating project.')); cb(error); } }); } }); }); }; require('./version-check.js')(gulp, gutil).validate(answers.serverUrl, answers.pluginToken, answers, checkResponseCallback); // copy README files }); }, // before we enable angular, we need to make sure they have a few things verify: function () { var files = ['sdk.conf.json', 'server.conf.json']; return gulp.src(files) .pipe(expect({ checkRealFile: true, errorOnFailure: true }, files)) .on('end', function () { var sdkConf = require(path.join(process.cwd(), 'sdk.conf.json')); if (!is.undefined(sdkConf.ng)) { gutil.log(gutil.colors.red('Angularjs support is already enabled on this project.')); process.exit(1); } }) .on('error', function () { gutil.log(gutil.colors.red('File check failed.')); process.exit(1); }); }, enableAngular: function (cb) { // get version var serverUrl = require(path.join(process.cwd(), 'server.conf.json')).serverUrl; var statusPath = '/t5/status/versionpage'; var request = http.get(serverUrl + statusPath); var reqCallStarted = setInterval(function () { gutil.log(gutil.colors.cyan('Waiting for response from ' + serverUrl + ' ...')); }, 3000); var reqCallStartTime = process.hrtime(); gutil.log(gutil.colors.cyan('Starting call to ' + serverUrl + ' ...')); request.on('response', function (response) { clearInterval(reqCallStarted); if (response.statusCode === 200) { var serverCallTime = prettyTime(process.hrtime(reqCallStartTime)); gutil.log(gutil.colors.cyan('Finished call to ' + serverUrl + ' in ' + gutil.colors.magenta(serverCallTime))); response.setEncoding('utf8'); response.on('data', function (chunk) { var liaBranch = parseVersionPage(chunk); var custName = require(path.join(process.cwd(), 'package.json')).name; gutil.log(gutil.colors.cyan('Lia version ' + gutil.colors.magenta(liaBranch.branch))); if (liaBranch.branch.indexOf('release') > -1) { liaBranch = 'release/' + liaBranch.version; } else { // active branch liaBranch = 'develop'; } var ops = { name: custName, branch: liaBranch }; // now that we have template variables, run gulp.src merge( // merge sdk.conf.json gulp.src(['./sdk.conf.json', path.join(__dirname, '../templates/project-ng/sdk.conf.json')]) .pipe(extend('sdk.conf.json')) .pipe(gulp.dest('./')) .pipe(logFile()), // copy over everything else gulp.src([path.join(__dirname, '../templates/project-ng/**/*'), '!' + path.join(__dirname, '../templates/project-ng/sdk.conf.json')]) .pipe(template(ops)) .pipe(rename(function (path) { path.basename = path.basename.replace('_', ''); })) .pipe(gulp.dest('./')) .pipe(logFile()) ).on('end', function () { bowerInstall('./', function (code) { if (code === 0) { gutil.log(gutil.colors.green('Finished! You may now use angular in your sdk environment.')); cb(); } else { gutil.log(gutil.colors.red('Bower install failed')); cb(new Error('Bower install failed')); } }); }); }); } else { gutil.log(gutil.colors.red('Call to ' + serverUrl + ' failed. Response status code: ' + response.statusCode)); cb(new Error('Call to lia failed.')); } }); }, server: function (opts, cb) { var ops = { serverConf: {} }; var questions = [ { type: 'input', name: 'serverUrl', message: function () { return 'What is the URL (include port if exists) to the dev/stage site that you will connect to ' + '(beginning with "https://")?'; }, validate: function (val) { return validate(val, /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)/); } } ]; var noToken = gutil.env['notoken']; if (noToken) { var skins = skinLib.getResponsiveSkinIds(); if (skins.length < 1) { process.exitCode = 1; throw new Error('There are no responsive skins. You should create a skin in the res/skins folder and make its ' + 'parent a responsive skin (such as the responsive_peak skin) by setting the parent property in the ' + 'skin.properties file'); } questions = questions.concat([ { type: 'input', name: 'liaVersion', message: function() { return 'What version of LIA are you running on your dev/stage site?'; }, default: function() { return '16.2'; } }, { type: 'input', name: 'responsiveVersion', message: function() { return 'What version of the core responsive feature (responsivepeak) are you using?'; }, default: function() { return '1.7'; } }, { name: 'localSkinCompileSkin', type: 'list', message: function() { return 'What responsive skin would you like to serve locally?' }, choices: skins }, { type: 'input', name: 'localServerPort', message: function() { return 'What port would you like to use to serve the compiled css for your skin from?'; }, default: function() { return '9000'; } } ]); } else { questions = questions.concat([ { type: 'input', name: 'pluginToken', message: function () { return 'Do you have a plugin token (if not press enter)?'; }, validate: function (val) { return validate(val, /^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$/, true); }, default: function () { return ''; } } ]); } inquirer.prompt(questions, function (answers) { // set up vars for server.conf.json ops.serverConf.serverUrl = answers.serverUrl; if (answers.pluginToken) { ops.serverConf.pluginToken = answers.pluginToken; } //default studio overrides allowed ops.serverConf.allowStudioOverrides = true; //default strict mode false ops.serverConf.strictMode = false; //default dry run mode false ops.serverConf.dryRun = false; //default verbose false ops.serverConf.verbose = false; //default force false ops.serverConf.force = false; //default pluginPoints ops.serverConf.pluginPoints = []; //defaults for sass support ops.serverConf.useResponsiveConfigsFromServer = true; ops.serverConf.useLocalCompile = true; //default skipTemplateValidation to false ops.serverConf.skipTemplateValidation = false; // notoken options if (noToken) { ops.serverConf.useResponsiveConfigsFromServer = false; ops.serverConf.localSkinCompileFeature = 'responsivepeak'; ops.serverConf.localSkinCompileVersion = 'v' + answers.responsiveVersion + 'lia' + answers.liaVersion; ops.serverConf.localSkinCompileSkin = answers.localSkinCompileSkin; ops.serverConf.localServerPort = parseInt(answers.localServerPort); } answers.name = process.cwd().split(path.normalize('/')).pop(); ops.name = answers.name; ops.description = 'server.conf.json file for ' + answers.name + '\nGenerated by ' + process.env.USER; //create server.conf.json fs.writeFile(path.join('.', 'server.conf.json'), JSON.stringify(ops.serverConf, null, 2), function (error) { if (error) { gutil.log(gutil.colors.red('Some error occured while creating server.conf.json file')); cb(error); } else { gutil.log(gutil.colors.green("Finished creating server.conf.json file")); gutil.log(gutil.colors.cyan(path.resolve(path.join('.', 'server.conf.json')))); cb(); } }); }); } }; };