@lenne.tech/cli
Version:
lenne.Tech CLI: lt
200 lines • 17.2 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = require("path");
/**
* Create a new server module
*/
const NewCommand = {
alias: ['dc'],
description: 'Creates a new deployment for mono repository',
hidden: false,
name: 'create',
run: (toolbox) => __awaiter(void 0, void 0, void 0, function* () {
// Retrieve the tools we need
const { filesystem, helper, parameters, patching, print: { info, spin, success }, prompt: { confirm }, strings: { camelCase, kebabCase, pascalCase }, system, template, } = toolbox;
// Start timer
const timer = system.startTimer();
// Info
info('Create a new deployment');
// Get default project name
let projectName = '';
const config = yield filesystem.exists('lt.json');
if (config) {
yield patching.update('lt.json', (data) => {
projectName = data.name;
return data;
});
}
if (!projectName) {
yield patching.update('package.json', (data) => {
projectName = pascalCase(data.name);
return data;
});
}
// Get name
const name = yield helper.getInput(parameters.first, {
initial: projectName,
name: `project name (e.g. ${projectName ? projectName : 'My new project'})`,
});
if (!name) {
return;
}
// Get domain
const domain = yield helper.getInput(parameters.second, {
initial: `${kebabCase(name)}.lenne.tech`,
name: `main domain of the project (e.g. ${kebabCase(name)}.lenne.tech)`,
});
if (!name) {
return;
}
const gitHub = yield confirm('Add GitHub pipeline?');
const gitLab = yield confirm('Add GitLab pipeline?');
// GitLab test runner
let testRunner;
let prodRunner;
if (gitLab) {
testRunner = yield helper.getInput('', {
initial: 'docker-swarm',
name: 'runner for test (tag in .gitlab-ci.yml, e.g. docker-swarm)',
});
if (!testRunner) {
return;
}
prodRunner = yield helper.getInput('', {
initial: 'docker-landing',
name: 'runner for production (tag in .gitlab-ci.yml, e.g. docker-landing)',
});
if (!prodRunner) {
return;
}
}
// Set up initial props (to pass into templates)
const nameCamel = camelCase(name);
const nameKebab = kebabCase(name);
const namePascal = pascalCase(name);
// Check if directory
const cwd = filesystem.cwd();
const generateSpinner = spin('Generate files');
yield template.generate({
props: { nameCamel, nameKebab, namePascal },
target: (0, path_1.join)(cwd, 'scripts', 'build-push.sh'),
template: 'deployment/scripts/build-push.sh.ejs',
});
yield template.generate({
props: { nameCamel, nameKebab, namePascal },
target: (0, path_1.join)(cwd, 'scripts', 'deploy.sh'),
template: 'deployment/scripts/deploy.sh.ejs',
});
yield template.generate({
props: { nameCamel, nameKebab, namePascal },
target: (0, path_1.join)(cwd, 'Dockerfile'),
template: 'deployment/Dockerfile.ejs',
});
yield template.generate({
props: { nameCamel, nameKebab, namePascal },
target: (0, path_1.join)(cwd, 'Dockerfile.app'),
template: 'deployment/Dockerfile.app.ejs',
});
yield template.generate({
props: { nameCamel, nameKebab, namePascal },
target: (0, path_1.join)(cwd, 'docker-compose.dev.yml'),
template: 'deployment/docker-compose.dev.yml.ejs',
});
yield template.generate({
props: { nameCamel, nameKebab, namePascal },
target: (0, path_1.join)(cwd, 'docker-compose.test.yml'),
template: 'deployment/docker-compose.test.yml.ejs',
});
yield template.generate({
props: { nameCamel, nameKebab, namePascal },
target: (0, path_1.join)(cwd, 'docker-compose.prod.yml'),
template: 'deployment/docker-compose.prod.yml.ejs',
});
if (gitHub) {
yield template.generate({
props: { nameCamel, nameKebab, namePascal, url: domain },
target: (0, path_1.join)(cwd, '.github', 'workflows', 'pre-release.yml'),
template: 'deployment/.github/workflows/pre-release.yml.ejs',
});
yield template.generate({
props: { nameCamel, nameKebab, namePascal, url: domain },
target: (0, path_1.join)(cwd, '.github', 'workflows', 'release.yml'),
template: 'deployment/.github/workflows/release.yml.ejs',
});
}
if (gitLab) {
yield template.generate({
props: { nameCamel, nameKebab, namePascal, prodRunner, testRunner, url: domain },
target: (0, path_1.join)(cwd, '.gitlab-ci.yml'),
template: 'deployment/.gitlab-ci.yml.ejs',
});
}
generateSpinner.succeed('Files generated');
const environmentsSpinner = spin('Update app environment files');
const prodEnv = yield filesystem.exists('projects/app/src/environments/environment.prod.ts');
if (prodEnv) {
yield patching.patch('projects/app/src/environments/environment.prod.ts', {
insert: `https://api.${domain}`,
replace: new RegExp('http://127.0.0.1:3000', 'g'),
});
yield patching.patch('projects/app/src/environments/environment.prod.ts', {
insert: `wss://api.${domain}`,
replace: new RegExp('ws://127.0.0.1:3000', 'g'),
});
yield patching.patch('projects/app/src/environments/environment.prod.ts', {
insert: `https://${domain}`,
replace: new RegExp('http://127.0.0.1:4200', 'g'),
});
}
else {
info('Missing projects/app/src/environments/environment.prod.ts');
}
const testEnv = yield filesystem.exists('projects/app/src/environments/environment.test.ts');
if (testEnv) {
yield patching.patch('projects/app/src/environments/environment.test.ts', {
insert: `https://api.test.${domain}`,
replace: new RegExp('http://127.0.0.1:3000', 'g'),
});
yield patching.patch('projects/app/src/environments/environment.test.ts', {
insert: `wss://api.test.${domain}`,
replace: new RegExp('ws://127.0.0.1:3000', 'g'),
});
yield patching.patch('projects/app/src/environments/environment.test.ts', {
insert: `https://test.${domain}`,
replace: new RegExp('http://127.0.0.1:4200', 'g'),
});
}
else {
info('Missing projects/app/src/environments/environment.test.ts');
}
environmentsSpinner.succeed('App environment files updated');
// We're done, so show what to do next
info('');
success(`Generated deployment for ${namePascal} in ${helper.msToMinutesAndSeconds(timer())}m.`);
info('');
// Hint for CI/CD
const subDomains = ['www', 'api', 'test', 'www.test', 'api.test'];
let urlStr = `\n- ${domain}`;
for (const sub of subDomains) {
urlStr += `\n- ${sub}.${domain}`;
}
success(`HINT: please initialize following Domains before running the CI/CD pipeline:${urlStr}`);
info('');
if (!toolbox.parameters.options.fromGluegunMenu) {
process.exit();
}
// For tests
return `new deployment ${name}`;
}),
};
exports.default = NewCommand;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL2RlcGxveW1lbnQvY3JlYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQ0EsK0JBQTRCO0FBSTVCOztHQUVHO0FBQ0gsTUFBTSxVQUFVLEdBQW1CO0lBQ2pDLEtBQUssRUFBRSxDQUFDLElBQUksQ0FBQztJQUNiLFdBQVcsRUFBRSw4Q0FBOEM7SUFDM0QsTUFBTSxFQUFFLEtBQUs7SUFDYixJQUFJLEVBQUUsUUFBUTtJQUNkLEdBQUcsRUFBRSxDQUFPLE9BQStCLEVBQUUsRUFBRTtRQUM3Qyw2QkFBNkI7UUFDN0IsTUFBTSxFQUNKLFVBQVUsRUFDVixNQUFNLEVBQ04sVUFBVSxFQUNWLFFBQVEsRUFDUixLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxFQUM5QixNQUFNLEVBQUUsRUFBRSxPQUFPLEVBQUUsRUFDbkIsT0FBTyxFQUFFLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsRUFDN0MsTUFBTSxFQUNOLFFBQVEsR0FDVCxHQUFHLE9BQU8sQ0FBQztRQUVaLGNBQWM7UUFDZCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUM7UUFFbEMsT0FBTztRQUNQLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBRWhDLDJCQUEyQjtRQUMzQixJQUFJLFdBQVcsR0FBRyxFQUFFLENBQUM7UUFDckIsTUFBTSxNQUFNLEdBQUcsTUFBTSxVQUFVLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2xELElBQUksTUFBTSxFQUFFLENBQUM7WUFDWCxNQUFNLFFBQVEsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUMsSUFBeUIsRUFBRSxFQUFFO2dCQUM3RCxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFDeEIsT0FBTyxJQUFJLENBQUM7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