@@ -6,17 +6,19 @@ const {spawnSync} = require('child_process');
6
6
const { quote} = require ( 'shell-quote' ) ;
7
7
const values = require ( 'lodash.values' ) ;
8
8
const { buildImage, getBindPath} = require ( './docker' ) ;
9
+ const md5File = require ( 'md5-file' )
10
+
9
11
10
12
/**
11
- * Install requirements described in requirementsPath to targetPath
13
+ * Just generate the requirements file in the .serverless folder
12
14
* @param {string } requirementsPath
13
15
* @param {string } targetFolder
14
16
* @param {Object } serverless
15
17
* @param {string } servicePath
16
18
* @param {Object } options
17
19
* @return {undefined }
18
20
*/
19
- function installRequirements ( requirementsPath , targetFolder , serverless , servicePath , options ) {
21
+ function installRequirementsFile ( requirementsPath , targetFolder , serverless , servicePath , options ) {
20
22
// Create target folder if it does not exist
21
23
const targetRequirementsFolder = path . join ( targetFolder , 'requirements' ) ;
22
24
fse . ensureDirSync ( targetRequirementsFolder ) ;
@@ -27,8 +29,24 @@ function installRequirements(requirementsPath, targetFolder, serverless, service
27
29
} else {
28
30
generateRequirementsFile ( requirementsPath , dotSlsReqs , options ) ;
29
31
}
32
+
33
+ serverless . cli . log ( `Generated requirements of ${ requirementsPath } in ${ targetFolder } ...` ) ;
34
+ }
30
35
31
- serverless . cli . log ( `Installing requirements of ${ requirementsPath } in ${ targetFolder } ...` ) ;
36
+
37
+ /**
38
+ * Install requirements described in requirementsPath to targetPath
39
+ * @param {string } targetFolder
40
+ * @param {Object } serverless
41
+ * @param {string } servicePath
42
+ * @param {Object } options
43
+ * @return {undefined }
44
+ */
45
+ function installRequirements ( targetFolder , serverless , servicePath , options ) {
46
+ const targetRequirementsFolder = path . join ( targetFolder , 'requirements' ) ;
47
+ const dotSlsReqs = path . join ( targetFolder , 'requirements.txt' ) ;
48
+
49
+ serverless . cli . log ( `Installing requirements from ${ dotSlsReqs } ...` ) ;
32
50
33
51
let cmd ;
34
52
let cmdOptions ;
@@ -149,7 +167,13 @@ function generateRequirementsFile(source, target, options) {
149
167
* @return {undefined }
150
168
*/
151
169
function installAllRequirements ( ) {
170
+ // Added a static cache folder and try to read the cached sum
171
+ const requirementsStaticCacheFolder = path . join ( this . servicePath , '.serverless-python-requirements-static-cache' ) ;
172
+ fse . ensureDirSync ( requirementsStaticCacheFolder ) ;
173
+ try { cached_sum = fse . readFileSync ( path . join ( requirementsStaticCacheFolder , '.requirements.txt.md5' ) ) ; } catch ( exception ) { cached_sum = false ; }
174
+
152
175
fse . ensureDirSync ( path . join ( this . servicePath , '.serverless' ) ) ;
176
+
153
177
if ( this . serverless . service . package . individually ) {
154
178
let doneModules = [ ] ;
155
179
values ( this . serverless . service . functions )
@@ -158,24 +182,54 @@ function installAllRequirements() {
158
182
set ( f , [ 'module' ] , '.' ) ;
159
183
}
160
184
if ( ! doneModules . includes ( f . module ) ) {
161
- installRequirements (
185
+ installRequirementsFile (
162
186
path . join ( f . module , this . options . fileName ) ,
163
187
path . join ( '.serverless' , f . module ) ,
164
188
this . serverless ,
165
189
this . servicePath ,
166
190
this . options
167
191
) ;
192
+ if ( cached_sum && cached_sum == md5File . sync ( path . join ( this . servicePath , '.serverless/requirements.txt' ) ) ) {
193
+ this . serverless . cli . log ( `Using static cache...` ) ;
194
+ fse . copySync ( requirementsStaticCacheFolder , path . join ( '.serverless' , f . module , 'requirements/' ) )
195
+ fse . removeSync ( path . join ( '.serverless' , f . module , 'requirements/.requirements.txt.md5' ) )
196
+ } else {
197
+ installRequirements (
198
+ path . join ( '.serverless' , f . module ) ,
199
+ this . serverless ,
200
+ this . servicePath ,
201
+ this . options
202
+ ) ;
203
+ }
204
+ // Write our MD5 hash of our requirements.txt to a file to detect if we need to re-run installRequirements
205
+ fse . writeFileSync ( path . join ( requirementsStaticCacheFolder , '.requirements.txt.md5' ) , md5File . sync ( path . join ( this . servicePath , '.serverless/requirements.txt' ) ) ) ;
168
206
doneModules . push ( f . module ) ;
169
207
}
170
208
} ) ;
171
209
} else {
172
- installRequirements (
210
+ installRequirementsFile (
173
211
this . options . fileName ,
174
212
'.serverless' ,
175
213
this . serverless ,
176
214
this . servicePath ,
177
215
this . options
178
216
) ;
217
+ if ( cached_sum && cached_sum == md5File . sync ( path . join ( this . servicePath , '.serverless/requirements.txt' ) ) ) {
218
+ this . serverless . cli . log ( `Using static cache...` ) ;
219
+ fse . copySync ( requirementsStaticCacheFolder , '.serverless/requirements/' )
220
+ fse . removeSync ( '.serverless/requirements/.requirements.txt.md5' )
221
+ } else {
222
+ installRequirements (
223
+ '.serverless' ,
224
+ this . serverless ,
225
+ this . servicePath ,
226
+ this . options
227
+ ) ;
228
+ }
229
+ // Backup our static files to cache...
230
+ fse . copySync ( '.serverless/requirements' , requirementsStaticCacheFolder )
231
+ // Write our MD5 hash of our requirements.txt to a file to detect if we need to re-run installRequirements
232
+ fse . writeFileSync ( path . join ( requirementsStaticCacheFolder , '.requirements.txt.md5' ) , md5File . sync ( path . join ( this . servicePath , '.serverless/requirements.txt' ) ) ) ;
179
233
}
180
234
} ;
181
235
0 commit comments