UNPKG

generator-pyhipster

Version:

Python (Flask) + Angular/React/Vue in one handy generator

391 lines (346 loc) 11.6 kB
/** * Copyright 2013-2022 the original author or authors from the JHipster project. * * This file is part of the JHipster project, see https://www.jhipster.tech/ * for more information. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const chalk = require('chalk'); const shelljs = require('shelljs'); const { loadConfigs, setClusteredApps } = require('./docker-base'); const { getBase64Secret } = require('./utils'); const { MICROSERVICE, MONOLITH, GATEWAY } = require('../jdl/jhipster/application-types'); const { COUCHBASE, MONGODB } = require('../jdl/jhipster/database-types'); const { PROMETHEUS } = require('../jdl/jhipster/monitoring-types'); const monitoring = require('../jdl/jhipster/monitoring-types'); const NO_MONITORING = monitoring.NO; const { CONSUL, EUREKA } = require('../jdl/jhipster/service-discovery-types'); module.exports = { askForApplicationType, askForGatewayType, askForPath, askForApps, askForClustersMode, askForMonitoring, askForServiceDiscovery, askForAdminPassword, askForDockerRepositoryName, askForDockerPushCommand, loadConfigs, }; /** * Ask For Application Type */ async function askForApplicationType() { if (this.regenerate) return; const prompts = [ { type: 'list', name: 'deploymentApplicationType', message: 'Which *type* of application would you like to deploy?', choices: [ { value: MONOLITH, name: 'Monolithic application', }, { value: MICROSERVICE, name: 'Microservice application', }, ], default: MONOLITH, }, ]; const props = await this.prompt(prompts); this.deploymentApplicationType = props.deploymentApplicationType; } /** * Ask For Gateway Type */ async function askForGatewayType() { if (this.regenerate) return; if (this.deploymentApplicationType !== MICROSERVICE) return; const prompts = [ { type: 'list', name: 'gatewayType', message: 'Which *type* of gateway would you like to use?', choices: [ { value: 'SpringCloudGateway', name: 'JHipster gateway based on Spring Cloud Gateway', }, ], default: 'SpringCloudGateway', }, ]; const props = await this.prompt(prompts); this.gatewayType = props.gatewayType; } /** * Ask For Path */ async function askForPath() { if (this.regenerate) return; const deploymentApplicationType = this.deploymentApplicationType; let messageAskForPath; if (deploymentApplicationType === MONOLITH) { messageAskForPath = 'Enter the root directory where your applications are located'; } else { messageAskForPath = 'Enter the root directory where your gateway(s) and microservices are located'; } const prompts = [ { type: 'input', name: 'directoryPath', message: messageAskForPath, default: this.directoryPath || '../', validate: input => { const path = this.destinationPath(input); if (shelljs.test('-d', path)) { const appsFolders = getAppFolders.call(this, input, deploymentApplicationType); if (appsFolders.length === 0) { return deploymentApplicationType === MONOLITH ? `No monolith found in ${path}` : `No microservice or gateway found in ${path}`; } return true; } return `${path} is not a directory or doesn't exist`; }, }, ]; const props = await this.prompt(prompts); this.directoryPath = props.directoryPath; // Patch the path if there is no trailing "/" if (!this.directoryPath.endsWith('/')) { this.log(chalk.yellow(`The path "${this.directoryPath}" does not end with a trailing "/", adding it anyway.`)); this.directoryPath += '/'; } this.appsFolders = getAppFolders.call(this, this.directoryPath, deploymentApplicationType); // Removing registry from appsFolders, using reverse for loop for (let i = this.appsFolders.length - 1; i >= 0; i--) { if (this.appsFolders[i] === 'jhipster-registry' || this.appsFolders[i] === 'registry') { this.appsFolders.splice(i, 1); } } this.log(chalk.green(`${this.appsFolders.length} applications found at ${this.destinationPath(this.directoryPath)}\n`)); } /** * Ask For Apps */ async function askForApps() { if (this.regenerate) return; const messageAskForApps = 'Which applications do you want to include in your configuration?'; const prompts = [ { type: 'checkbox', name: 'chosenApps', message: messageAskForApps, choices: this.appsFolders, default: this.defaultAppsFolders, validate: input => (input.length === 0 ? 'Please choose at least one application' : true), }, ]; const props = await this.prompt(prompts); this.appsFolders = props.chosenApps; loadConfigs.call(this); } /** * Ask For Clusters Mode */ async function askForClustersMode() { if (this.regenerate) return; const clusteredDbApps = []; this.appConfigs.forEach((appConfig, index) => { if (appConfig.prodDatabaseType === MONGODB || appConfig.prodDatabaseType === COUCHBASE) { clusteredDbApps.push(this.appsFolders[index]); } }); if (clusteredDbApps.length === 0) return; const prompts = [ { type: 'checkbox', name: 'clusteredDbApps', message: 'Which applications do you want to use with clustered databases (only available with MongoDB and Couchbase)?', choices: clusteredDbApps, default: this.clusteredDbApps, }, ]; const props = await this.prompt(prompts); this.clusteredDbApps = props.clusteredDbApps; setClusteredApps.call(this); } /** * Ask For Monitoring */ async function askForMonitoring() { if (this.regenerate) return; const prompts = [ { type: 'list', name: 'monitoring', message: 'Do you want to setup monitoring for your applications ?', choices: [ { value: NO_MONITORING, name: 'No', }, { value: PROMETHEUS, name: 'Yes, for metrics only with Prometheus', }, ], default: this.monitoring ? this.monitoring : NO_MONITORING, }, ]; const props = await this.prompt(prompts); this.monitoring = props.monitoring; } /** * Ask For Service Discovery */ async function askForServiceDiscovery() { if (this.regenerate) return; const serviceDiscoveryEnabledApps = []; this.appConfigs.forEach((appConfig, index) => { if (appConfig.serviceDiscoveryType) { serviceDiscoveryEnabledApps.push({ baseName: appConfig.baseName, serviceDiscoveryType: appConfig.serviceDiscoveryType, }); } }); if (serviceDiscoveryEnabledApps.length === 0) { this.serviceDiscoveryType = false; return; } if (serviceDiscoveryEnabledApps.every(app => app.serviceDiscoveryType === CONSUL)) { this.serviceDiscoveryType = CONSUL; this.log(chalk.green('Consul detected as the service discovery and configuration provider used by your apps')); } else if (serviceDiscoveryEnabledApps.every(app => app.serviceDiscoveryType === EUREKA)) { this.serviceDiscoveryType = EUREKA; this.log(chalk.green('JHipster registry detected as the service discovery and configuration provider used by your apps')); } else { this.log(chalk.yellow('Unable to determine the service discovery and configuration provider to use from your apps configuration.')); this.log('Your service discovery enabled apps:'); serviceDiscoveryEnabledApps.forEach(app => { this.log(` -${app.baseName} (${app.serviceDiscoveryType})`); }); const prompts = [ { type: 'list', name: 'serviceDiscoveryType', message: 'Which Service Discovery registry and Configuration server would you like to use ?', choices: [ { value: EUREKA, name: 'JHipster Registry', }, { value: CONSUL, name: 'Consul', }, { value: false, name: 'No Service Discovery and Configuration', }, ], default: EUREKA, }, ]; const props = this.prompt(prompts); this.serviceDiscoveryType = props.serviceDiscoveryType; } } /** * Ask For Admin Password */ async function askForAdminPassword() { if (this.regenerate || this.serviceDiscoveryType !== EUREKA) return; const prompts = [ { type: 'input', name: 'adminPassword', message: 'Enter the admin password used to secure the JHipster Registry', default: 'admin', validate: input => (input.length < 5 ? 'The password must have at least 5 characters' : true), }, ]; const props = await this.prompt(prompts); this.adminPassword = props.adminPassword; this.adminPasswordBase64 = getBase64Secret.call(this, this.adminPassword); } /** * Ask For Docker Repository Name */ async function askForDockerRepositoryName() { if (this.regenerate) return; const prompts = [ { type: 'input', name: 'dockerRepositoryName', message: 'What should we use for the base Docker repository name?', default: this.dockerRepositoryName, }, ]; const props = await this.prompt(prompts); this.dockerRepositoryName = props.dockerRepositoryName; } /** * Ask For Docker Push Command */ async function askForDockerPushCommand() { if (this.regenerate) return; const prompts = [ { type: 'input', name: 'dockerPushCommand', message: 'What command should we use for push Docker image to repository?', default: this.dockerPushCommand ? this.dockerPushCommand : 'docker push', }, ]; const props = await this.prompt(prompts); this.dockerPushCommand = props.dockerPushCommand; } /** * Get App Folders * @param input path to join to destination path * @param deploymentApplicationType type of application being composed * @returns {Array} array of string representing app folders */ function getAppFolders(input, deploymentApplicationType) { const destinationPath = this.destinationPath(input); const files = shelljs.ls('-l', destinationPath); const appsFolders = []; files.forEach(file => { if (file.isDirectory()) { if (shelljs.test('-f', `${destinationPath}/${file.name}/.yo-rc.json`)) { try { const fileData = this.fs.readJSON(`${destinationPath}/${file.name}/.yo-rc.json`); if ( fileData['generator-jhipster'].baseName !== undefined && (deploymentApplicationType === undefined || deploymentApplicationType === fileData['generator-jhipster'].applicationType || (deploymentApplicationType === MICROSERVICE && fileData['generator-jhipster'].applicationType === GATEWAY)) ) { appsFolders.push(file.name.match(/([^/]*)\/*$/)[1]); } } catch (err) { this.log(chalk.red(`${file}: this .yo-rc.json can't be read`)); this.debug('Error:', err); } } } }); return appsFolders; }