UNPKG

atlas-connect

Version:

CLI for the atlassian-connect-express library (helpers for building Atlassian Connect apps on top of Express)

174 lines (152 loc) 6.48 kB
var AdmZip = require('adm-zip'); var chalk = require('chalk'); var json = require('comment-json'); var fs = require('fs'); var inquirer = require('inquirer'); var fetch = require('node-fetch'); var path = require('path'); var rimraf = require('rimraf'); var temp = require('temp'); var descriptorModules = require('./descriptor-modules.json'); var extractTemplate = function (projectName, product, buffer, callback) { fs.exists(projectName, function (err) { if (err) { inquirer.prompt({ type: 'confirm', name: 'overwrite', message: 'Directory ' + projectName + ' already exists. Do you wish to remove and continue?', default: false }).then(function (answer) { if (answer.overwrite) { rimraf(projectName, function (err) { if (!err) { createScaffold(projectName, product, buffer, callback); } }); } else { callback(new Error('Chose not to overwrite directory ' + projectName)); } }); } else { createScaffold(projectName, product, buffer, callback); } }); }; var logError = function (message) { logMessage('error', message); }; var logMessage = function (type, message) { var prefix = ''; message = message || ''; if (type === 'error') { prefix = chalk.red('ERR!'); } message.split('\\n').forEach(function (m) { console.log(prefix, m); }); }; var createScaffold = function (projectName, product, buffer, callback) { var writeJsonObjectToFile = function (jsonObject, filename) { // We use 4 spaces as an indention fs.writeFileSync(filename, json.stringify(jsonObject, null, 4)); }; var setProductInConfigFile = function(projectDir, product) { var configFilename = path.join(projectDir, 'config.json'); var config = json.parse(fs.readFileSync(configFilename, { encoding: 'utf8' })); config.product = product === 'jira-service-desk' ? 'jira' : product; writeJsonObjectToFile(config, configFilename); }; var setProductModulesInDescriptor = function(projectDir, product) { var productModules = descriptorModules[product]; if (productModules) { var descriptorFilename = path.join(projectDir, 'atlassian-connect.json'); var descriptor = json.parse(fs.readFileSync(descriptorFilename, { encoding: 'utf8' })); descriptor.modules = productModules; writeJsonObjectToFile(descriptor, descriptorFilename); } }; temp.mkdir(projectName, function (err, dirPath) { var zip = new AdmZip(buffer); var zipEntries = zip.getEntries(); // write the zip archive into the current directory var outDir = process.cwd(); // The bitbucket archive includes the account, repository name and commit hash // as the first directory in the archive, eg: "atlassian-atlassian-connect-express-template-564020eabcd4/" // let's get this folder name and remove it from the extracted archive. var zipFolderName = zipEntries[0].entryName.split(path.sep)[0]; zip.extractAllTo(outDir, true); // Move all files in "outdir/zipFolderName" to "outdir/projectName" fs.renameSync(path.join(outDir, zipFolderName), path.join(process.cwd(), projectName)); if (product) { var projectDir = path.join(outDir, projectName); setProductInConfigFile(projectDir, product); setProductModulesInDescriptor(projectDir, product); } console.log('\nExtracting template:'); zipEntries.forEach(function (zipEntry) { // Replace "zipFolderName" with "projectName" var zipFilenameWithoutFirstDirectory = zipEntry.entryName.split(path.sep).slice(1).join(path.sep); var fileName = [projectName, zipFilenameWithoutFirstDirectory].join(path.sep); console.log(' ' + chalk.green(fileName)); }); callback(err); }); }; var generateScaffold = function (projectName, template, callback) { var templateUrl; var product = template; if (template.match(/^http/)) { templateUrl = template; product = null; } else { templateUrl = 'https://bitbucket.org/atlassian/atlassian-connect-express-template/get/'; switch (template) { case 'jira': case 'jira-service-desk': case 'confluence': templateUrl += 'master.zip'; break; case 'bitbucket': templateUrl += 'bitbucket.zip'; break; default: var msg = 'No template for type ' + template; logError(msg); return callback(new Error(msg)); break; } } fetch(templateUrl).then(function (response) { if (response.status === 404) { logError('The Atlassian Connect app template ' + chalk.bold(template) + ' was not found.'); logError(); logError('Please check that you are connected to the internet and try again.'); } else if (!response.ok) { logError('The Atlassian Connect app template ' + chalk.bold(template) + ' was unable to be downloaded.'); logError(); logError(chalk.bold('Status code: ') + response.status); response.text().then(function (body) { logError(body); }); } else { response.buffer().then(function (buffer) { extractTemplate(projectName, product, buffer, callback); }); } }); }; module.exports = { createTemplate: function (name, template) { generateScaffold(name, template, function (err) { if (!err) { console.log(); console.log('A directory ' + chalk.bold.green(name) + ' has been created for your project with a Node.js'); console.log('application pre-configured. For information on what to do next, visit:'); console.log(); console.log(' http://go.atlassian.com/get-started-with-atlassian-connect-express'); console.log(); } }); }, logError: logError };