UNPKG

imq-cli

Version:

Command Line Interface for IMQ

326 lines 13.3 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); /*! * IMQ-CLI command: config init * * Copyright (c) 2018, Mykhailo Stadnyk <mikhus@gmail.com> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ const inquirer = require("inquirer"); const lib_1 = require("../../lib"); const chalk_1 = require("chalk"); const fs = require("fs"); // we are going to ignore almost all code here because it's very hard to test // command line user interaction // istanbul ignore next async function selectTemplate(type) { let name = 'custom'; let path = ''; if (type === 'existing') { const defaultTemplates = await lib_1.loadTemplates(); let answer = await inquirer.prompt([{ type: 'list', name: 'tplName', message: 'Select one of existing templates:', choices: Object.keys(defaultTemplates) }]); return { [answer.tplName]: defaultTemplates[answer.tplName] }; } if (type === 'repo') { let answer = await inquirer.prompt([{ type: 'input', name: 'repoUrl', message: 'Enter git repository URL:' }]); if (!(answer.repoUrl && answer.repoUrl.trim())) { throw new TypeError('Repository URL expected, but was not given!'); } path = await lib_1.loadTemplate(answer.repoUrl); } else if (type === 'directory') { let answer = await inquirer.prompt([{ type: 'input', name: 'tplDir', message: 'Enter path to directory:' }]); if (!(answer.tplDir && answer.tplDir.trim())) { throw new TypeError('Template directory path expected, ' + 'but was not given!'); } if (!fs.existsSync(lib_1.resolve(answer.tplDir))) { throw new Error('Given template directory does not exist!'); } path = lib_1.resolve(answer.tplDir); } return { [name]: path }; } exports.selectTemplate = selectTemplate; // istanbul ignore next async function templateOptions(config) { let answer = await inquirer.prompt([{ type: 'confirm', name: 'useDefault', message: 'Do you want to use default template for newly created ' + 'services?', default: true }]); let templates; let tplName = 'default'; if (!answer.useDefault) { answer = await inquirer.prompt([{ type: 'list', name: 'tplType', message: 'Select required template:', choices: [{ name: 'From a list of existing templates', value: 'existing' }, { name: 'From a git repository', value: 'repo' }, { name: 'From file system directory', value: 'directory' }] }]); templates = await selectTemplate(answer.tplType); tplName = Object.keys(templates).shift() || ''; } else { templates = await lib_1.loadTemplates(); } if (templates[tplName]) { config.template = templates[tplName]; return console.log(chalk_1.default.green(`New services set to be created from template "${tplName}" (${config.template})`)); } else { throw new Error(`Template ${tplName} does not exists!`); } } exports.templateOptions = templateOptions; // istanbul ignore next async function versionSystemOptions(config) { let answer = await inquirer.prompt([{ type: 'confirm', name: 'autoCreateRepo', message: 'Would you like IMQ automatically create git ' + 'repository for new services when generate?', default: true, }]); if (!answer.autoCreateRepo) { config.useGit = false; return; } config.useGit = true; console.log(chalk_1.default.cyan(lib_1.wrap('\nTo publish git repository you need to provide base url ' + 'where your git repositories published to. It is recommended ' + 'also to set-up git SSH access on your machine to ' + 'make publishing process run smoothly.\n\nFor example, if ' + 'you are using GitHub for your repositories, you need to enter ' + 'git@github.com:[user_or_org] as base URL and setup SSH ' + 'access as described at https://help.github.com/articles/' + 'adding-a-new-ssh-key-to-your-github-account/\n'))); answer = await inquirer.prompt([{ type: 'input', name: 'url', message: 'Enter github organization or user name:', }]); if (!/^[-_a-z0-9]+$/i.test(answer.url)) { console.log(chalk_1.default.red('Wrong user or organization name.')); return await versionSystemOptions(config); } config.gitBaseUrl = `git@github.com:${answer.url}`; console.log(chalk_1.default.green(`Base git URL is set to "${config.gitBaseUrl}"`)); answer = await inquirer.prompt([{ type: 'confirm', name: 'saveGitHubToken', message: 'Would you like to save GitHub auth token in a local config ' + 'to prevent imq to ask it any time service is created?', default: false, }]); if (!answer.saveGitHubToken) { return; } console.log(chalk_1.default.cyan(lib_1.wrap('To make GitHub integration work you must provide a valid token ' + 'which grants permission to create repository for a specified ' + 'organization or user name.\nUsually you can generate the token ' + 'on this page: https://github.com/settings/tokens'))); answer = await inquirer.prompt([{ type: 'input', name: 'gitHubAuthToken', message: 'Enter GitHub auth token:', }]); if (!answer.gitHubAuthToken.trim()) { console.log(chalk_1.default.red('Given token is empty, you will be prompted to enter it on ' + 'service create command')); return; } config.gitHubAuthToken = answer.gitHubAuthToken.trim(); console.log(chalk_1.default.green('GitHub auth token stored in local config file')); answer = await inquirer.prompt([{ type: 'confirm', name: 'isPrivate', message: 'Does created service should a private repository on GitHub?', default: true, }]); config.gitRepoPrivate = answer.isPrivate; console.log(chalk_1.default.green(`Service on GitHub will be created as ${config.gitRepoPrivate ? 'private' : 'public'} repository.`)); } exports.versionSystemOptions = versionSystemOptions; // istanbul ignore next async function authorName(config) { const answer = await inquirer.prompt([{ type: 'input', name: 'author', message: 'Enter author\'s full name (user or organization):' }]); if (!answer.author.trim()) { console.log(chalk_1.default.red(`Given name is invalid, please, try again.`)); return await authorName(config); } config.author = answer.author.trim(); console.log(chalk_1.default.green(`Auto-generated code will be authored by "${config.author}"`)); } exports.authorName = authorName; // istanbul ignore next async function authorEmail(config) { const answer = await inquirer.prompt([{ type: 'input', name: 'email', message: 'Enter user or organization email:' }]); if (!/^[-a-z0-9.]+@[-a-z0-9.]+$/i.test(answer.email.trim())) { console.log(chalk_1.default.red(`Given email is invalid, please, try again.`)); return await authorName(config); } config.email = answer.email.trim(); console.log(chalk_1.default.green(`Generated code will be referred to given contact: ${config.email}`)); } exports.authorEmail = authorEmail; // istanbul ignore next async function authorOptions(config) { await authorName(config); await authorEmail(config); } exports.authorOptions = authorOptions; // istanbul ignore next async function dockerCredentials(config) { const answer = await inquirer.prompt([{ type: 'input', name: 'dockerHubUser', message: 'Docker hub user:' }, { type: 'password', name: 'dockerHubPassword', message: 'Docker hub password:' }]); if (!answer.dockerHubUser.trim()) { console.log(chalk_1.default.red('Given docker hub user name is empty, please try again')); return dockerCredentials(config); } if (!answer.dockerHubPassword.trim()) { console.log(chalk_1.default.red('Given docker hub password is empty, please try again')); return dockerCredentials(config); } config.dockerHubUser = answer.dockerHubUser.trim(); config.dockerHubPassword = answer.dockerHubPassword.trim(); console.log(chalk_1.default.green('Docker hub credentials saved in a local config file.')); } exports.dockerCredentials = dockerCredentials; // istanbul ignore next async function dockerQuestions(config) { let answer = await inquirer.prompt([{ type: 'confirm', name: 'useDocker', message: 'Would you like to dockerize created imq services?', default: true }]); if (!answer.useDocker) { config.useDocker = false; return; } answer = await inquirer.prompt([{ type: 'input', name: 'dockerHubNamespace', message: 'Docker hub namespace:' }]); if (!answer.dockerHubNamespace.trim()) { console.log(chalk_1.default.red('Given docker hub namespace is invalid, please, try again...')); return await dockerQuestions(config); } config.useDocker = true; config.dockerHubNamespace = answer.dockerHubNamespace.trim(); answer = await inquirer.prompt([{ type: 'confirm', name: 'saveDockerCredentials', message: 'Would you like to store docker credentials locally to ' + 'allow imq create CI-Docker secrets without prompt?', default: false }]); if (!answer.saveDockerCredentials) { return; } await dockerCredentials(config); } exports.dockerQuestions = dockerQuestions; // istanbul ignore next async function serviceQuestions(config) { await authorOptions(config); await templateOptions(config); const { id, name } = await lib_1.licensingOptions(); config.license = id; console.log(chalk_1.default.green(`Selected "${name}" to be a license for IMQ generated code and services`)); await versionSystemOptions(config); await dockerQuestions(config); } exports.serviceQuestions = serviceQuestions; // noinspection JSUnusedGlobalSymbols _a = { command: 'init', describe: 'Interactively initializes IMQ CLI configuration file', async handler() { try { if (!lib_1.configEmpty()) { process.stdout.write(chalk_1.default.bold.yellow('Config already initialized, path: ') + chalk_1.default.cyan(lib_1.CONFIG_PATH) + '\n'); const answer = await inquirer.prompt([{ type: 'confirm', name: 'reInit', message: 'Do you want to re-init?', default: false }]); if (!answer.reInit) { return; } } console.log(chalk_1.default.cyan(lib_1.wrap('Let\'s define global config options ' + 'for IMQ command line runs. These options will be used as ' + 'default parameters and will help you shorten your ' + 'commands.\n\n'))); console.log(chalk_1.default.yellow(lib_1.wrap('- You can skip this step by pressing ' + '[^C].\n- You can proceed to this step later by running:'))); console.log(chalk_1.default.magenta('\n $ imq config init\n')); const config = lib_1.loadConfig(); await serviceQuestions(config); lib_1.saveConfig(config); console.log(chalk_1.default.magenta('IMQ-CLI successfully configured!')); } catch (err) { lib_1.printError(err); console.error(err); } } }, exports.command = _a.command, exports.describe = _a.describe, exports.handler = _a.handler; //# sourceMappingURL=init.js.map