Created
October 15, 2016 22:02
-
-
Save imaustink/e090c33a957b054d29c4e0fbd5a14b6a to your computer and use it in GitHub Desktop.
Lambda build tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var argv = require('yargs').argv; | |
var chmod = require("gulp-chmod"); | |
var debug = require('gulp-debug'); | |
var fs = require('fs'); | |
var gulp = require('gulp'); | |
var gutil = require('gulp-util'); | |
var istanbul = require('gulp-istanbul'); | |
var jshint = require('gulp-jshint'); | |
var mocha = require('gulp-mocha'); | |
var path = require('path'); | |
var publishLambda = require('gulp-awslambda'); | |
var Readline = require('readline'); | |
var sequence = require('gulp-sequence'); | |
var zip = require('gulp-zip'); | |
gulp.task('default', function() { | |
// be ready to read in any commands | |
readSTDIN((command) => { | |
gulp.start(command); | |
}); | |
// watch for changes to the lambda functions | |
return gulp.watch(['functions/**', '!*', '!functions/**/test/**', '!functions/**/coverage/**'], function(event){ | |
// get the lambda that was modified | |
var lambda = getLambdaArg(event.path); | |
// if no lambda, return | |
if(!lambda){ | |
return; | |
} | |
// log the lambda that was changed | |
gutil.log(`${lambda} changed!`); | |
// add to unpublished | |
Unpublished.push(lambda); | |
}); | |
}); | |
gulp.task('test', function(){ | |
// try to get a lambda from the -l arg | |
var lambda = getLambdaArg(argv.l); | |
var unpublished = Unpublished.get(); | |
// if we did have a lambda arg... | |
if(lambda){ | |
// publish the lambda | |
return gulp.start(`test-and-lint-${lambda}`); | |
} | |
// otherwise, we're going to use the unpublished array from the watcher | |
// anything? | |
if(!unpublished.length){ | |
// notify user that we couldn't find anything to publish | |
return console.error('Nothing to test!'); | |
} | |
// publish everything waiting to be published | |
unpublished.forEach(() => gulp.start(`test-and-lint-${lambda}`)); | |
// reset the unpublished array | |
Unpublished.set([]); | |
}); | |
gulp.task('publish', function(){ | |
// try to get a lambda from the -l arg | |
var lambda = getLambdaArg(argv.l); | |
// if we did have a lambda arg... | |
if(lambda){ | |
// publish the lambda | |
return gulp.start(`publish-${lambda}`); | |
} | |
// otherwise, we're going to use the unpublished array from the watcher | |
var unpublished = Unpublished.get(); | |
// anything? | |
if(!unpublished.length){ | |
// notify user that we couldn't find anything to publish | |
return gutil.log('Nothing to publish!'); | |
} | |
// publish everything waiting to be published | |
unpublished.forEach(lambda => gulp.start(`publish-${lambda}`)); | |
// reset the unpublished array | |
Unpublished.save([]); | |
}); | |
// for each lambda | |
getLambdas().forEach(lambda => { | |
var package; | |
var lambda_settings; | |
// register a gulp tasks | |
gulp.task(`check-${lambda}`, done => { | |
sequence(`test-${lambda}`, `lint-${lambda}`, done); | |
}); | |
gulp.task(`lint-${lambda}`, () => { | |
return gulp.src([`./functions/${lambda}/**/*.js`, `!./functions/${lambda}/+(node_modules|coverage)/**/*`]) | |
.pipe(jshint()) | |
.pipe(jshint.reporter('default')) | |
.pipe(jshint.reporter('fail')); | |
}); | |
gulp.task(`pre-test-${lambda}`, [`read-package-${lambda}`], () => { | |
return gulp.src([path.join('.', 'functions', lambda, package.main || 'index.js')]) | |
.pipe(istanbul()) | |
.pipe(istanbul.hookRequire()); | |
}); | |
gulp.task(`publish-${lambda}`, [`read-package-${lambda}`, `check-${lambda}`], () => { | |
return gulp.src([`./functions/${lambda}/**`, `!./functions/${lambda}/test`, `!./functions/${lambda}/test/**`]) | |
.pipe(chmod(777, true)) | |
.pipe(zip(lambda + '.zip')) | |
.pipe(publishLambda( | |
{ | |
FunctionName: lambda, | |
Handler: lambda_settings.handler || 'index.handler', | |
Role: lambda_settings.role || 'arn:aws:iam::455160284107:role/lambda-basic-execution', | |
Description: lambda_settings.description || package.description || '' | |
}, | |
{ | |
profile: 'personal', | |
region: lambda_settings.region || 'us-east-1' | |
} | |
)) | |
//.pipe(gulp.dest('./dist')) | |
; | |
}); | |
gulp.task(`read-package-${lambda}`, (done) => { | |
fs.readFile(`./functions/${lambda}/package.json`, 'utf8', (err, file) => { | |
if(err){ | |
package = {}; | |
lambda_settings = {}; | |
return done(); | |
} | |
// try to parse the JSON | |
try { | |
package = JSON.parse(file); | |
lambda_settings = package.lambda || {}; | |
return done(); | |
} catch(err){ | |
package = {}; | |
lambda_settings = {}; | |
return done(); | |
} | |
}); | |
}); | |
gulp.task(`test-${lambda}`, [`pre-test-${lambda}`], () => { | |
return gulp.src([`./functions/${lambda}/test/**/*.js`], { read:false }) | |
.pipe(mocha()) | |
.pipe(istanbul.writeReports({ reporters: ['lcov', 'json', 'text-summary'], dir: `./functions/${lambda}/coverage`})); | |
//.pipe(istanbul.enforceThresholds({ thresholds: { global: 100 } })); | |
}); | |
gulp.task(`test-and-lint-${lambda}`, [`test-${lambda}`, `lint-${lambda}`]); | |
}); | |
function getLambdas() { | |
return fs.readdirSync(path.join(__dirname, './functions/')).filter(function(file) { | |
return fs.statSync(path.join(__dirname, 'functions', file)).isDirectory(); | |
}); | |
} | |
function getLambdaArg(arg){ | |
// make sure we have something to work with | |
if(!arg){ | |
return; | |
} | |
// vars | |
var lambda_dir = path.join(__dirname, 'functions'); | |
var lambda = arg; | |
var stat; | |
// see if the arg is simply a lambda name | |
if(path.join(lambda_dir, arg, '..') !== lambda_dir){ | |
// wasn't a lambda name | |
// see if it's a relative or absolute path to the lambda file or subfolder/file | |
lambda = path.resolve(arg); | |
// does the first part of our lambda match the lambda directory? | |
if(lambda.substr(0, lambda_dir.length).toLowerCase() === lambda_dir.toLowerCase()){ | |
// strip off the lambda directory and any trailing directories | |
lambda = lambda.substr(lambda_dir.length + 1).match(/^([^\\\/]*)/)[0]; | |
} else { | |
// didn't match the lambda directory so we got nothing | |
return; | |
} | |
} | |
// check if something exists | |
try { | |
stat = fs.statSync(path.join(lambda_dir, lambda)); | |
} catch(err){ | |
return; | |
} | |
// check if folder | |
if(!stat.isDirectory()){ | |
return; | |
} | |
// return the valid lambda name | |
return lambda; | |
} | |
function readSTDIN(cb){ | |
Readline.createInterface({ | |
input: process.stdin | |
}).on('line', (line) => { | |
cb(line.trim()); | |
}); | |
} | |
function Unpublished(){}; | |
(function(){ | |
// This is where we save the file to | |
const FILE = './.unpublished.json'; | |
// Returns Array of file paths from FILE | |
this.get = (retry) => { | |
try{ | |
return JSON.parse(fs.readFileSync(FILE)); | |
}catch(err){ | |
// Prevent infinite loop | |
if(retry === false) throw 'Failed to create publish file!'; | |
// Create FILE with empty Array | |
this.save([]); | |
// Try again and disable retry | |
return this.get(false); | |
} | |
}; | |
// Push to Array of FILE | |
this.push = (val) => { | |
// Get starting value | |
var vals = this.get(); | |
// If it isn't already in the Array | |
if(!~vals.indexOf(val)){ | |
// Push to Array | |
vals.push(val); | |
// And save | |
this.save(vals); | |
} | |
}; | |
// Saves string to FILE | |
this.save = (val) => { | |
fs.writeFileSync(FILE, JSON.stringify(val)); | |
}; | |
return this; | |
}).call(Unpublished); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment