@@ -7,12 +7,18 @@ Promise.promisifyAll(fs);
7
7
8
8
function runCommand ( cmd , args , options , cli ) {
9
9
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 ) {
13
20
throw new Error ( ps . error ) ;
14
21
} else if ( ps . status !== 0 ) {
15
- cli . log ( ps . stderr . toString ( ) )
16
22
throw new Error ( ps . stderr ) ;
17
23
}
18
24
return ps ;
@@ -24,29 +30,39 @@ function docker(args, options,cli){
24
30
25
31
function cleanBuild ( ) {
26
32
this . cli = this . serverless . cli
27
- this . cli . log ( "Cleaning ruby layer build" )
33
+ this . cli . log ( "Clearing previous build ruby layer build" )
28
34
this . ruby_layer = path . join ( this . servicePath , '.serverless' , 'ruby_layer' )
29
35
if ( fs . pathExistsSync ( this . ruby_layer ) ) {
30
36
fs . removeSync ( this . ruby_layer )
31
37
}
32
38
}
39
+
33
40
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' ) )
37
48
const bundle_args = [ 'bundle' , 'install' , '--path=build' , '--without' , 'test' , 'development' ]
38
- const options = { cwd : this . ruby_layer , encoding : 'utf8' }
39
49
this . build_path = path . join ( this . ruby_layer , 'build' )
40
50
fs . mkdirSync ( this . build_path )
51
+ const options = { cwd : this . ruby_layer , encoding : 'utf8' }
41
52
if ( this . options . use_docker ) {
42
53
docker_name = 'lambci/lambda:build-' + this . serverless . service . provider . runtime
43
54
ps = docker ( [ 'version' ] , options , this . cli )
44
55
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 ' ) ;
46
57
}
47
58
let buildDocker = false ;
48
59
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 ,
50
66
path . join ( this . ruby_layer , 'Dockerfile' ) )
51
67
buildDocker = true
52
68
} else if ( this . options . docker_yums ) {
@@ -60,10 +76,13 @@ function bundleInstall(){
60
76
buildDocker = true
61
77
}
62
78
if ( buildDocker ) {
79
+ this . cli . log ( "Building docker for bundle install" )
63
80
docker_name = 'ruby-layer:docker'
64
81
docker ( [ 'build' , '-t' , docker_name , '-f' , 'Dockerfile' , '.' ] , options , this . cli )
65
82
}
83
+
66
84
if ( this . options . native_libs ) {
85
+ this . cli . log ( "Packing the native libraries from the specified path" )
67
86
ps = docker ( [ 'run' , '-d' , docker_name , 'false' ] , options , this . cli )
68
87
container_id = ps . stdout . toString ( ) . trim ( )
69
88
const lib_path = path . join ( this . build_path , 'lib' )
@@ -72,15 +91,27 @@ function bundleInstall(){
72
91
ps = docker ( [ 'cp' , '-L' , container_id + ':' + lib_to_copy , lib_path ] , options , this . cli )
73
92
} )
74
93
}
94
+
95
+ this . cli . log ( "Installing gem using docker bundler" )
75
96
args = [ 'run' , '--rm' , '-i' , '-v' , `${ this . ruby_layer } :/var/gem_build` , '-w' , '/var/gem_build' ]
76
97
args . push ( docker_name )
98
+
77
99
docker ( args . concat ( bundle_args ) , options , this . cli )
78
100
} else {
79
- ps = runCommand ( "bundle" , [ '-v' ] , options , this . cli )
101
+ ps = runCommand ( "bundle" , [ '-v' ] , options , this . cli )
80
102
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/ ' ) ;
82
104
}
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
+
84
115
runCommand ( bundle_args [ 0 ] , bundle_args . slice ( 1 , bundle_args . length ) , options , this . cli )
85
116
}
86
117
}
@@ -122,8 +153,13 @@ function zipBundleFolder() {
122
153
this . gem_folder = fs . readdirSync ( path . join ( this . build_path , 'ruby' ) ) [ 0 ]
123
154
fs . removeSync ( path . join ( this . build_path , 'ruby' , this . gem_folder , 'cache' ) )
124
155
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 ,
127
163
{ platform : platform , compression : 'DEFLATE' ,
128
164
compressionOptions : { level : 9 } } ) ;
129
165
}
@@ -140,12 +176,17 @@ function excludePackage(){
140
176
}
141
177
142
178
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
+ }
143
184
if ( ! this . serverless . service . layers ) {
144
185
this . serverless . service . layers = { } ;
145
186
}
146
187
this . serverless . service . layers [ 'gemLayer' ] = Object . assign (
147
188
{
148
- package : { artifact : path . join ( this . ruby_layer , 'gemLayer.zip' ) } ,
189
+ package : { artifact : this . gemLayer_zip_path } ,
149
190
name : `${
150
191
this . serverless . service . service
151
192
} -${ this . serverless . providers . aws . getStage ( ) } -ruby-bundle`,
@@ -157,6 +198,9 @@ function configureLayer() {
157
198
) ;
158
199
159
200
Object . keys ( this . serverless . service . functions ) . forEach ( funcName => {
201
+ if ( this . debug ) {
202
+ this . cli . log ( "Configuring Layer for function: " + funcName )
203
+ }
160
204
const function_ = this . serverless . service . getFunction ( funcName )
161
205
function_ . environment = { }
162
206
function_ . environment [ "GEM_PATH" ] = "/opt/ruby/" + this . gem_folder
0 commit comments