@kumologica/builder
Version:
Kumologica build and deploy module
133 lines (103 loc) • 3.61 kB
JavaScript
const fs = require('fs-extra');
const path = require('path');
const util = require('util');
const exec = util.promisify(require('child_process').exec);
const AdmZip = require('adm-zip');
const codegen = require('./codegen');
/**
* sample events:
* https://docs.aws.amazon.com/lambda/latest/dg/lambda-services.html
*/
class AWSBuilder {
constructor() {}
log(text) {
console.log(text);
}
async buildLambda(buildDir, zipFileName) {
const zipFilePath = path.join(buildDir, zipFileName);
this.log(`Building lambda... ${zipFilePath}`);
const npmCmd = `npm install --production`;
this.log(`Running command: ${npmCmd} in directory: ${buildDir}`);
const response = await exec(npmCmd, { cwd: buildDir });
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
await codegen.removeSymlinks(buildDir);
this.log('Zipping lambda...');
const zip = new AdmZip();
zip.addLocalFolder(buildDir);
zip.writeZip(zipFilePath);
this.log(`Lambda has been successfully built: ${zipFilePath}`);
return zipFilePath;
}
prepare(projectDir, flowFileName) {
const buildDir = path.join(projectDir, 'build');
const flowName = flowFileName.replace('.json', '');
// setup deployment directory
fs.ensureDirSync(buildDir);
fs.emptyDirSync(buildDir);
fs.ensureDirSync(path.join(buildDir, 'node_modules'));
// copy project files
codegen.generateProjectCode(
buildDir,
flowFileName,
flowName
);
this.processPackageJson(projectDir, buildDir);
}
processPackageJson(projectDir, buildDir) {
const pckg = codegen.loadJsonFile(path.join(projectDir, 'package.json'));
// remove aws-sdk v2
if (pckg.dependencies["aws-sdk"]) {
delete pckg.dependencies["aws-sdk"];
}
// remove aws sdk v3
for (let k in Object.keys(pckg.dependencies)) {
if (pckg.dependencies[k] && pckg.dependencies[k].startsWith("@aws-sdk")) {
delete pckg.dependencies[k];
}
}
// ensure dependencies contain runtime
// layers support added, layer may reference runtime
/*if (!pckg.dependencies["@kumologica/runtime"]) {
pckg.dependencies["@kumologica/runtime"] = `^${pckg.version.substr(0, 1)}`;
}*/
// recreate package.json file
codegen.createFile(buildDir, 'package.json', JSON.stringify(pckg));
if (pckg.files) {
pckg.files.forEach(f => {
if (!["node_modules/**/*", "lambda.js", "src/**/*" ].includes(f)) {
fs.copySync(
path.join(projectDir, f),
path.join(buildDir, f)
);
}
});
}
}
async build(argv) {
let projectDir = argv["project-directory"] || process.cwd();
let buildDir = path.join(projectDir, 'build');
let projectFlowName = argv["flow-file-name"] || codegen.findFlowFile(projectDir);
if (!projectFlowName) {
throw new Error(`Unable to find flow file in project directory: ${projectDir}`);
}
console.log(`project directory: ${projectDir}`);
console.log(`flow file name: ${projectFlowName}`);
console.log(`zip file name: ${argv["zip-file-name"]}`);
this.prepare(
projectDir,
projectFlowName
);
await this.buildLambda(buildDir, argv["zip-file-name"]);
}
}
module.exports = AWSBuilder;