@@ -5,52 +5,70 @@ const Promise = require('bluebird');
5
5
var JSZip = require ( 'jszip' ) ;
6
6
Promise . promisifyAll ( fs ) ;
7
7
8
- function runCommand ( cmd , args , options ) {
8
+ function runCommand ( cmd , args , options , cli ) {
9
9
const ps = spawnSync ( cmd , args , options ) ;
10
- if ( ps . error ) {
10
+ cli . log ( ps . stdout . toString ( ) )
11
+ if ( ps . error && ps . error . code != 'ENOENT' ) {
12
+ cli . log ( ps . stderr . toString ( ) )
11
13
throw new Error ( ps . error ) ;
12
14
} else if ( ps . status !== 0 ) {
15
+ cli . log ( ps . stderr . toString ( ) )
13
16
throw new Error ( ps . stderr ) ;
14
17
}
15
18
return ps ;
16
19
}
17
20
18
- function docker ( args , options ) {
19
- return runCommand ( "docker" , args , options )
21
+ function docker ( args , options , cli ) {
22
+ return runCommand ( "docker" , args , options , cli )
20
23
}
21
24
22
25
function cleanBuild ( ) {
23
- this . serverless . cli . log ( "Cleaning ruby layer build" )
24
- this . build_path = path . join ( this . servicePath , '.serverless' , 'build' , 'ruby_layer' )
25
- if ( fs . pathExistsSync ( this . build_path ) ) {
26
- fs . rmdirSync ( this . build_path , { recursive : true } )
26
+ this . cli = this . serverless . cli
27
+ this . cli . log ( "Cleaning ruby layer build" )
28
+ this . ruby_layer = path . join ( this . servicePath , '.serverless' , 'ruby_layer' )
29
+ if ( fs . pathExistsSync ( this . ruby_layer ) ) {
30
+ fs . rmdirSync ( this . ruby_layer , { recursive : true } )
27
31
}
28
32
}
29
-
30
33
function bundleInstall ( ) {
31
- this . serverless . cli . log ( this . build_path )
32
- const gem_path = path . join ( this . build_path , 'Gemfile' )
34
+ this . cli . log ( this . ruby_layer )
35
+ const gem_path = path . join ( this . ruby_layer , 'Gemfile' )
33
36
fs . copySync ( path . join ( this . servicePath , 'Gemfile' ) , gem_path )
34
- const bundle_args = [ 'bundle' , 'install' , '--path=.' , '--without' , 'test' , 'development' ]
35
- const options = { cwd : this . build_path , encoding : 'utf8' }
37
+ const bundle_args = [ 'bundle' , 'install' , '--path=build' , '--without' , 'test' , 'development' ]
38
+ const options = { cwd : this . ruby_layer , encoding : 'utf8' }
39
+ this . build_path = path . join ( this . ruby_layer , 'build' )
40
+ fs . mkdirSync ( this . build_path )
36
41
if ( this . options . use_docker ) {
37
42
docker_name = 'lambci/lambda:build-' + this . serverless . service . provider . runtime
38
- ps = docker ( [ 'version' ] , options )
43
+ ps = docker ( [ 'version' ] , options , this . cli )
39
44
if ( ps . error && ps . error . code === 'ENOENT' ) {
40
45
throw new Error ( 'docker command not found' ) ;
41
46
}
42
- args = [ 'run' , '--rm' , '-i' , '-v' , `${ this . build_path } :/var/gem_build` , '-w' , '/var/gem_build' ]
47
+ if ( this . options . docker_file ) {
48
+ fs . copySync ( path . join ( this . servicePath , this . options . docker_file ) ,
49
+ path . join ( this . ruby_layer , 'Dockerfile' ) )
50
+ docker_name = 'ruby-layer:docker'
51
+ docker ( [ 'build' , '-t' , docker_name , '-f' , 'Dockerfile' , '.' ] , options , this . cli )
52
+ }
53
+ if ( this . options . native_libs ) {
54
+ ps = docker ( [ 'run' , '-d' , docker_name , 'false' ] , options , this . cli )
55
+ container_id = ps . stdout . toString ( ) . trim ( )
56
+ const lib_path = path . join ( this . build_path , 'lib' )
57
+ fs . mkdirSync ( lib_path )
58
+ this . options . native_libs . forEach ( lib_to_copy => {
59
+ ps = docker ( [ 'cp' , '-L' , container_id + ':' + lib_to_copy , lib_path ] , options , this . cli )
60
+ } )
61
+ }
62
+ args = [ 'run' , '--rm' , '-i' , '-v' , `${ this . ruby_layer } :/var/gem_build` , '-w' , '/var/gem_build' ]
43
63
args . push ( docker_name )
44
- ps = docker ( args . concat ( bundle_args ) , options )
45
- this . serverless . cli . log ( ps . stdout )
64
+ docker ( args . concat ( bundle_args ) , options , this . cli )
46
65
} else {
47
- ps = runCommand ( "bundle" , [ '-v' ] )
66
+ ps = runCommand ( "bundle" , [ '-v' ] , options , this . cli )
48
67
if ( ps . error && ps . error . code === 'ENOENT' ) {
49
68
throw new Error ( 'bundle command not found in local' ) ;
50
69
}
51
- this . serverless . cli . log ( bundle_args . slice ( 1 , bundle_args . length ) )
52
- ps = runCommand ( bundle_args [ 0 ] , bundle_args . slice ( 1 , bundle_args . length ) , options )
53
- this . serverless . cli . log ( ps . stdout )
70
+ this . cli . log ( bundle_args . slice ( 1 , bundle_args . length ) )
71
+ runCommand ( bundle_args [ 0 ] , bundle_args . slice ( 1 , bundle_args . length ) , options , this . cli )
54
72
}
55
73
}
56
74
@@ -91,14 +109,13 @@ function zipBundleFolder() {
91
109
this . gem_folder = fs . readdirSync ( path . join ( this . build_path , 'ruby' ) ) [ 0 ]
92
110
fs . rmdirSync ( path . join ( this . build_path , 'ruby' , this . gem_folder , 'cache' ) , { recursive : true } )
93
111
const platform = process . platform == 'win32' ? 'DOS' : 'UNIX'
94
- return zipDir ( path . join ( this . build_path , 'ruby' ) ,
95
- path . join ( this . build_path , 'gemLayer.zip' ) ,
112
+ return zipDir ( this . build_path ,
113
+ path . join ( this . ruby_layer , 'gemLayer.zip' ) ,
96
114
{ platform : platform , compression : 'DEFLATE' ,
97
115
compressionOptions : { level : 9 } } ) ;
98
116
}
99
117
100
118
function excludePackage ( ) {
101
- this . serverless . cli . log ( JSON . stringify ( this . serverless . service . package ) )
102
119
if ( ! this . serverless . service . package ) {
103
120
this . serverless . service . package = Object . assign ( { } )
104
121
}
@@ -115,7 +132,7 @@ function configureLayer() {
115
132
}
116
133
this . serverless . service . layers [ 'gemLayer' ] = Object . assign (
117
134
{
118
- package : { artifact : path . join ( this . build_path , 'gemLayer.zip' ) } ,
135
+ package : { artifact : path . join ( this . ruby_layer , 'gemLayer.zip' ) } ,
119
136
name : `${
120
137
this . serverless . service . service
121
138
} -${ this . serverless . providers . aws . getStage ( ) } -ruby-bundle`,
@@ -129,7 +146,7 @@ function configureLayer() {
129
146
Object . keys ( this . serverless . service . functions ) . forEach ( funcName => {
130
147
const function_ = this . serverless . service . getFunction ( funcName )
131
148
function_ . environment = { }
132
- function_ . environment [ "GEM_PATH" ] = "/opt/" + this . gem_folder
149
+ function_ . environment [ "GEM_PATH" ] = "/opt/ruby/ " + this . gem_folder
133
150
function_ . layers = [ { "Ref" :"GemLayerLambdaLayer" } ]
134
151
} )
135
152
return Promise . resolve ( ) ;
0 commit comments