@kumologica/builder
Version:
Kumologica build and deploy module
176 lines (140 loc) • 4.72 kB
JavaScript
const fs = require('fs-extra');
const path = require('path');
const AdmZip = require('adm-zip');
const util = require('util');
const exec = util.promisify(require('child_process').exec);
const codegen = require('../build/codegen');
const { throws } = require('assert');
/**
* Class managing login and deployment to kumohub.
*/
class KumohubBuilder {
constructor(terminal) {
this.term = terminal;
}
log(text, calog = true, source = 'builder') {
//console.log(text);
var t = text;
if (calog) {
t = `${source}: ${text}`;
}
if (this.term) {
this.term.emit('terminal-output', t);
} else {
console.log(text);
}
}
prepare(params) {
const deployDir = path.join(params["project-directory"], '/deploy');
const flowName = params["flow-file-name"].replace('.json', '');
// setup deployment directory
fs.ensureDirSync(deployDir);
fs.emptyDirSync(deployDir);
fs.ensureDirSync(deployDir + '/node_modules');
// copy project files
codegen.generateProjectCode(
deployDir,
params["flow-file-name"],
true
);
this.processPackageJson(params, deployDir);
return {
deployDir,
flowName,
zipFileName: params["zip-file-name"]
};
}
processPackageJson(params, deployDir) {
const pckg = this.loadJsonFile(path.join(params["project-directory"], 'package.json'));
if (pckg.dependencies["@kumologica/runtime"] || pckg.dependencies["aws-sdk"]) {
delete pckg.dependencies["@kumologica/runtime"];
delete pckg.dependencies["aws-sdk"];
this.createFile(deployDir, 'package.json', JSON.stringify(pckg));
} else {
fs.copySync(
path.join(params["project-directory"], 'package.json'),
path.join(deployDir, 'package.json')
);
}
if (pckg.files) {
pckg.files.forEach(f => {
if (!["node_modules/**/*", "lambda.js" ].includes(f)) {
fs.copySync(path.join(params["project-directory"], f), path.join(deployDir, f));
}
});
}
}
/*
* Main function orchestrating build of lambda to kumohub.
*/
async build(params) {
params["project-directory"] = params["project-directory"] || process.cwd();
//console.log(`kumohub deploy params: ${JSON.stringify(params)}`);
if (!params["flow-file-name"]) {
params["flow-file-name"] = codegen.findFlowFile(params["project-directory"]);
}
this.log(` flow file name: ${params["flow-file-name"]}`, false);
this.log(` working directory: ${params["project-directory"]}`, false);
this.log(` zip file name: ${params["zip-file-name"]}`, false);
this.log('', false);
const settings = this.prepare(params);
const nodes = this.loadJsonFile(
path.join(params["project-directory"], params["flow-file-name"])
);
try {
const zipFileFullName = await this.buildLambda(settings);
this.log(`Success.`);
this.log(`Zip file: ${zipFileFullName}`);
} catch (error) {
this.log(`Build failed.`);
this.log(` ${error}`);
return;
}
let response = {};
return response;
}
/*
* Builds lambda and zips all sources.
*/
async buildLambda(settings) {
this.log('Building lambda...');
//console.log(`cwd: ${process.cwd()}`);
//console.log(`Deploy directory: ${settings.deployDir}`);
const npmCmd = `npm install --production --prefix "${settings.deployDir}"`;
const response = await exec(npmCmd, { cwd: settings.deployDir });
if (response) {
this.log('', false);
const lines = response.stdout.split('\n');
for (var i = 0; i < lines.length; i++) {
if (lines[i]) {
this.log(lines[i], false);
}
}
this.log('', false);
}
// for npm 8 on windows is creating symlink that causes recursions and zip to fail
const splitdir = path.dirname(buildDir).split(path.sep);
const linkname = splitdir[splitdir.length-1];
try {
fs.unlinkSync(path.join(buildDir, 'node_modules', linkname));
} catch (e) {
// ignore ENOENT
if (e.code !== "ENOENT") {
throw e;
}
}
const zipFileFullName = path.join(settings.deployDir, settings.zipFileName);
this.log('Zipping lambda...');
const zip = new AdmZip();
zip.addLocalFolder(settings.deployDir);
zip.writeZip(zipFileFullName);
return zipFileFullName;
}
loadJsonFile(flowFileName) {
return JSON.parse(fs.readFileSync(flowFileName));
}
createFile(baseDir, fileName, content) {
fs.outputFileSync(path.join(baseDir, fileName), content, 'utf-8');
}
}
module.exports = KumohubBuilder;