Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 55 additions & 31 deletions lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ Lambda.prototype._createSampleFile = function(file) {
fs.writeFileSync(exampleFile, fs.readFileSync(boilerplateFile));
console.log(exampleFile + ' file successfully created');
}

};

Lambda.prototype.setup = function() {
Expand Down Expand Up @@ -70,44 +69,75 @@ Lambda.prototype._params = function(program, buffer) {
MemorySize: program.memorySize,
Timeout: program.timeout
};
params.FunctionName += (program.version ? '-' + program.version.replace(/\./g, '-'): '');

return params;
};

Lambda.prototype.deploy = function(program) {
this._createSampleFile('.env');
Lambda.prototype._zipfileTmpPath = function(program) {
var ms_since_epoch = +new Date;
var filename = program.functionName + '-' + ms_since_epoch + '.zip';
var zipfile = path.join(os.tmpDir(), filename);

var _this = this;
var regions = program.region.split(',');
return zipfile;
};

// Generate random directory name
var dirName = uuid.v4();
Lambda.prototype._rsync = function(program, codeDirectory, callback) {
exec('rsync -r --exclude=.git --exclude=*.log --exclude=event.json --exclude=node_modules . ' + codeDirectory, function(err, stdout, stderr) {
if (err) {
throw err;
}

// Create folder where everything woll happen
fs.mkdirSync('/tmp/' + dirName);
return callback(null, true);
});
};

// Move all files to tmp folder (except .git, .log, event.json and node_modules)
exec('rsync -r --exclude=.git --exclude=*.log --exclude=event.json --exclude=node_modules . /tmp/' + dirName, function(err, stdout, stderr) {
Lambda.prototype._npmInstall = function(program, codeDirectory, callback) {
exec('npm install --production --prefix ' + codeDirectory, function(err, stdout, stderr) {
if (err) {
throw err;
}
// Install production modules in the specified folder
exec('npm install --production --prefix /tmp/' + dirName, function(err, stdout, stderr) {
if (err) {
throw err;
}
exec('cd /tmp/' + dirName +'/ zip -rq /tmp/' + dirName + '/' + dirName + '.zip .', function(err, stdout, stderr) {
if (err) {
throw err;
}
console.log(os.tmpDir());

return callback(null, true);
});
};

Lambda.prototype._zip = function(program, codeDirectory, callback) {
var zipfile = this._zipfileTmpPath(program);

var command = 'cd ' + codeDirectory + ' && zip -roq ' + zipfile + ' .';
console.log('_zip: ', command);
exec(command, function(err, stdout, stderr) {
if (err) {
throw err;
}

return callback(null, zipfile);
});
};

Lambda.prototype._codeDirectory = function(program) {
var epoch_time = +new Date;
return os.tmpDir() + '/' + program.functionName + '-' + epoch_time;
};

Lambda.prototype.deploy = function(program) {
this._createSampleFile('.env');

var _this = this;
var regions = program.region.split(',');
var codeDirectory = _this._codeDirectory(program);

// Move all files to tmp folder (except .git, .log, event.json and node_modules)
_this._rsync(program, codeDirectory, function(err, result) {
_this._npmInstall(program, codeDirectory, function(err, result) {
_this._zip(program, codeDirectory, function(err, zipfile) {

console.log('Reading zip file to memory');
var buffer = fs.readFileSync('/tmp/' + dirName + '/' + dirName + '.zip');
var buffer = fs.readFileSync(zipfile);
var params = _this._params(program, buffer);

async.map(regions, function(region, cb) {
console.log('Working in region: ' + region);
console.log('Uploading zip file to AWS Lambda with parameters:');
console.log('Uploading zip file to AWS Lambda '+ region + ' with parameters:');
console.log(params);

aws.config.update({
Expand All @@ -123,12 +153,6 @@ Lambda.prototype.deploy = function(program) {
});

}, function(err, results) {
rmdir('/tmp/' + dirName, function(error){
if (error) {
console.log(error);
}
});

if (err) {
console.log(err);
} else {
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "node-lambda",
"version": "0.3.6",
"version": "0.3.7",
"description": "Command line tool for locally running and remotely deploying your node.js applications to Amazon Lambda.",
"main": "lib/main.js",
"directories": {
Expand Down Expand Up @@ -30,6 +30,9 @@
"author": "motdotla",
"license": "BSD",
"devDependencies": {
"adm-zip": "^0.4.7",
"chai": "^2.0.0",
"lodash": "^3.2.0",
"mocha": "",
"should": ""
},
Expand Down
86 changes: 81 additions & 5 deletions test/main.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
var assert = require('assert');
var chai = require('chai');
var program = require('commander');
var fs = require('fs');
var lambda = require('../lib/main');
var should = require('should');
var os = require('os');
var fs = require('fs');
var _ = require('lodash');
var admzip = require('adm-zip');

var assert = chai.assert;

var program = {
environment: 'development',
Expand All @@ -15,18 +20,89 @@ var program = {
memorySize: 128,
timeout: 3,
description: '',
runtime: 'nodejs'
runtime: 'nodejs',
region: 'us-east-1,us-west-2,eu-west-1'
};

var codeDirectory = lambda._codeDirectory(program);

describe('node-lambda', function() {
it('version should be set', function() {
lambda.version.should.eql('0.3.6');
assert.equal(lambda.version, '0.3.7');
});

describe('_params', function() {
it( 'appends environment to original functionName', function() {
var params = lambda._params(program);
params.FunctionName.should.eql('node-lambda-development');
assert.equal(params.FunctionName, 'node-lambda-development');
});
});

describe('_zipfileTmpPath', function() {
it('has the correct path', function() {
var zipfileTmpPath = lambda._zipfileTmpPath(program);
var value = zipfileTmpPath.indexOf(program.functionName) > 0;
assert.equal(value, true);
});
});

describe('_rsync', function() {
it('rsync an index.js as well as other files', function(done) {
lambda._rsync(program, codeDirectory, function(err, result) {
var contents = fs.readdirSync(codeDirectory);

var result = _.includes(contents, 'index.js');
assert.equal(result, true);

done();
});
});
});

describe('_npmInstall', function() {
beforeEach(function(done) {
lambda._rsync(program, codeDirectory, function(err, result) {
done();
});
});

it('_npm adds node_mdules', function(done) {
this.timeout(5000); // give it time to build the node modules

lambda._npmInstall(program, codeDirectory, function(err, result) {
var contents = fs.readdirSync(codeDirectory);

var result = _.includes(contents, 'index.js');
assert.equal(result, true);

done();
});
});
});

describe('_zip', function() {
beforeEach(function(done) {
this.timeout(5000); // give it time to build the node modules
lambda._rsync(program, codeDirectory, function(err, result) {

lambda._npmInstall(program, codeDirectory, function(err, result) {
done();
});
});
});

it('zips the file and has an index.js file', function(done) {
this.timeout(5000); // give it time to zip

lambda._zip(program, codeDirectory, function(err, zipfilePath) {
var zip = new admzip(zipfilePath);
var zipEntries = zip.getEntries();
var contents = _.map(zipEntries, function(entry) { return entry.entryName.toString() });
var result = _.includes(contents, 'index.js');
assert.equal(result, true);

done();
});
});
});
});