Skip to content

Commit 8d673b5

Browse files
authored
Merge pull request #22 from navarasu/fix_19_add_validation
#19 Added validation for edge cases and included user informative logs & errors
2 parents 0d8cda5 + cca4627 commit 8d673b5

File tree

2 files changed

+67
-19
lines changed

2 files changed

+67
-19
lines changed

lib/bundle.js

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,18 @@ Promise.promisifyAll(fs);
77

88
function runCommand(cmd,args,options,cli) {
99
const ps = spawnSync(cmd, args,options);
10-
cli.log(ps.stdout.toString())
11-
if (ps.error && ps.error.code != 'ENOENT') {
12-
cli.log(ps.stderr.toString())
10+
if (ps.stdout && this.debug){
11+
cli.log(ps.stdout.toString())
12+
}
13+
if (ps.stderr){
14+
cli.log(ps.stderr.toString())
15+
}
16+
if (ps.error && ps.error.code == 'ENOENT'){
17+
return ps;
18+
}
19+
if (ps.error) {
1320
throw new Error(ps.error);
1421
} else if (ps.status !== 0) {
15-
cli.log(ps.stderr.toString())
1622
throw new Error(ps.stderr);
1723
}
1824
return ps;
@@ -24,29 +30,39 @@ function docker(args, options,cli){
2430

2531
function cleanBuild(){
2632
this.cli = this.serverless.cli
27-
this.cli.log("Cleaning ruby layer build")
33+
this.cli.log("Clearing previous build ruby layer build")
2834
this.ruby_layer = path.join(this.servicePath,'.serverless','ruby_layer')
2935
if (fs.pathExistsSync(this.ruby_layer)){
3036
fs.removeSync(this.ruby_layer)
3137
}
3238
}
39+
3340
function bundleInstall(){
34-
this.cli.log(this.ruby_layer)
35-
const gem_path = path.join(this.ruby_layer,'Gemfile')
36-
fs.copySync(path.join(this.servicePath,'Gemfile'), gem_path )
41+
this.debug = process.env.SLS_DEBUG;
42+
const gem_file_path = path.join(this.servicePath,'Gemfile')
43+
if (!fs.pathExistsSync(gem_file_path)){
44+
throw new Error("No Gemfile found in the path "+gem_file_path+"\n Please add a Gemfile in the path");
45+
}
46+
47+
fs.copySync(path.join(this.servicePath,'Gemfile'), path.join(this.ruby_layer,'Gemfile') )
3748
const bundle_args = ['bundle', 'install', '--path=build','--without', 'test', 'development']
38-
const options={cwd : this.ruby_layer, encoding : 'utf8'}
3949
this.build_path = path.join(this.ruby_layer, 'build')
4050
fs.mkdirSync(this.build_path)
51+
const options = {cwd : this.ruby_layer, encoding : 'utf8'}
4152
if (this.options.use_docker) {
4253
docker_name = 'lambci/lambda:build-'+this.serverless.service.provider.runtime
4354
ps=docker(['version'], options,this.cli)
4455
if (ps.error && ps.error.code === 'ENOENT') {
45-
throw new Error('docker command not found');
56+
throw new Error('docker command not found. Please install docker https://www.docker.com/products/docker-desktop');
4657
}
4758
let buildDocker = false;
4859
if (this.options.docker_file) {
49-
fs.copySync(path.join(this.servicePath, this.options.docker_file),
60+
const docker_file_path = path.join(this.servicePath, this.options.docker_file)
61+
if (!fs.pathExistsSync(docker_file_path)){
62+
throw new Error("No Dockerfile found in the path "+docker_file_path);
63+
}
64+
65+
fs.copySync(docker_file_path,
5066
path.join(this.ruby_layer,'Dockerfile'))
5167
buildDocker = true
5268
}else if (this.options.docker_yums) {
@@ -60,10 +76,13 @@ function bundleInstall(){
6076
buildDocker = true
6177
}
6278
if (buildDocker) {
79+
this.cli.log("Building docker for bundle install")
6380
docker_name ='ruby-layer:docker'
6481
docker(['build', '-t', docker_name, '-f', 'Dockerfile', '.'], options,this.cli)
6582
}
83+
6684
if (this.options.native_libs) {
85+
this.cli.log("Packing the native libraries from the specified path")
6786
ps=docker(['run', '-d', docker_name, 'false'], options,this.cli)
6887
container_id = ps.stdout.toString().trim()
6988
const lib_path = path.join(this.build_path,'lib')
@@ -72,15 +91,27 @@ function bundleInstall(){
7291
ps=docker(['cp','-L', container_id+':'+lib_to_copy, lib_path],options,this.cli)
7392
})
7493
}
94+
95+
this.cli.log("Installing gem using docker bundler")
7596
args=['run','--rm', '-i','-v', `${this.ruby_layer}:/var/gem_build`, '-w', '/var/gem_build']
7697
args.push(docker_name)
98+
7799
docker(args.concat(bundle_args), options,this.cli)
78100
} else {
79-
ps = runCommand("bundle",['-v'],options,this.cli)
101+
ps = runCommand("bundle",['-v'], options, this.cli)
80102
if (ps.error && ps.error.code === 'ENOENT') {
81-
throw new Error('bundle command not found in local');
103+
throw new Error('bundle command not found in local. Please install ruby. https://www.ruby-lang.org/en/downloads/');
82104
}
83-
this.cli.log(bundle_args.slice(1,bundle_args.length))
105+
this.cli.log("Installing gem using local bundler")
106+
if (this.debug) {
107+
this.cli.log("Ruby layer Path: \n "+ this.ruby_layer)
108+
ps = runCommand("ruby",['--version'], options, this.cli)
109+
this.cli.log("Ruby version: "+ ps.stdout.toString().trim())
110+
ps = runCommand("bundle",['-v'],options,this.cli)
111+
this.cli.log("Bundler version: "+ ps.stdout.toString().trim())
112+
this.cli.log(bundle_args.join(" "))
113+
}
114+
84115
runCommand(bundle_args[0],bundle_args.slice(1,bundle_args.length),options,this.cli)
85116
}
86117
}
@@ -122,8 +153,13 @@ function zipBundleFolder() {
122153
this.gem_folder= fs.readdirSync(path.join(this.build_path,'ruby'))[0]
123154
fs.removeSync(path.join(this.build_path,'ruby',this.gem_folder,'cache'))
124155
const platform = process.platform == 'win32' ? 'DOS' : 'UNIX'
125-
return zipDir(this.build_path,
126-
path.join(this.ruby_layer, 'gemLayer.zip'),
156+
zipping_message = "Zipping the gemfiles"
157+
if (this.options.native_libs) {
158+
zipping_message+=" and native libs"
159+
}
160+
this.gemLayer_zip_path = path.join(this.ruby_layer, 'gemLayer.zip')
161+
this.cli.log(zipping_message+ ' to '+ this.gemLayer_zip_path)
162+
return zipDir(this.build_path, this.gemLayer_zip_path,
127163
{ platform: platform, compression: 'DEFLATE',
128164
compressionOptions: { level: 9 }});
129165
}
@@ -140,12 +176,17 @@ function excludePackage(){
140176
}
141177

142178
function configureLayer() {
179+
this.cli.log("Configuring Layer and GEM_PATH to the functions")
180+
if(this.debug){
181+
this.cli.log("GEM_PATH:" + "/opt/ruby/"+this.gem_folder)
182+
this.cli.log("Zip Path:" + this.gemLayer_zip_path )
183+
}
143184
if (!this.serverless.service.layers) {
144185
this.serverless.service.layers = {};
145186
}
146187
this.serverless.service.layers['gemLayer'] = Object.assign(
147188
{
148-
package: {artifact: path.join(this.ruby_layer, 'gemLayer.zip')},
189+
package: {artifact: this.gemLayer_zip_path },
149190
name: `${
150191
this.serverless.service.service
151192
}-${this.serverless.providers.aws.getStage()}-ruby-bundle`,
@@ -157,6 +198,9 @@ function configureLayer() {
157198
);
158199

159200
Object.keys(this.serverless.service.functions).forEach(funcName => {
201+
if(this.debug){
202+
this.cli.log("Configuring Layer for function: " + funcName)
203+
}
160204
const function_ = this.serverless.service.getFunction(funcName)
161205
function_.environment={}
162206
function_.environment["GEM_PATH"]="/opt/ruby/"+this.gem_folder

test/helper.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ const path = require('path');
66

77
function runCommand(cmd,args,options) {
88
const ps = spawnSync(cmd, args,options);
9-
console.log(ps.stderr.toString())
10-
console.log(ps.stdout.toString());
9+
if (ps.stdout){
10+
console.log(ps.stdout.toString())
11+
}
12+
if (ps.stderr){
13+
console.log(ps.stderr.toString())
14+
}
1115
if (ps.error) {
1216
throw new Error(ps.error);
1317
} else if (ps.status !== 0) {

0 commit comments

Comments
 (0)