1
+ const BbPromise = require ( 'bluebird' ) ;
1
2
const fse = require ( 'fs-extra' ) ;
2
3
const glob = require ( 'glob-all' ) ;
3
4
const get = require ( 'lodash.get' ) ;
4
5
const set = require ( 'lodash.set' ) ;
5
6
const path = require ( 'path' ) ;
6
7
const values = require ( 'lodash.values' ) ;
7
- const zipper = require ( 'zip-local' ) ;
8
8
const JSZip = require ( 'jszip' ) ;
9
+ const { writeZip, zipFile } = require ( './zipTree' ) ;
9
10
10
- /**
11
- * write zip contents to a file
12
- * @param {Object } zip
13
- * @param {string } path
14
- */
15
- function writeZip ( zip , path ) {
16
- const buff = zip . generate ( {
17
- type : 'nodebuffer' ,
18
- compression : 'DEFLATE'
19
- } ) ;
20
-
21
- fse . writeFileSync ( path , buff ) ;
22
- }
23
-
24
- /**
25
- * add a new file to a zip file from a buffer
26
- * @param {Object } zip
27
- * @param {string } path path to put in zip
28
- * @param {string } buffer file contents
29
- */
30
- function zipFile ( zip , path , buffer ) {
31
- zip . file ( path , buffer , {
32
- date : new Date ( 0 ) // necessary to get the same hash when zipping the same content
33
- } ) ;
34
- }
11
+ BbPromise . promisifyAll ( fse ) ;
35
12
36
13
/**
37
- * inject requirements into packaged application
14
+ * Inject requirements into packaged application.
38
15
* @param {string } requirementsPath requirements folder path
39
16
* @param {string } packagePath target package path
40
17
* @param {Object } options our options object
18
+ * @return {Promise } the JSZip object constructed.
41
19
*/
42
20
function injectRequirements ( requirementsPath , packagePath , options ) {
43
21
const noDeploy = new Set ( options . noDeploy || [ ] ) ;
44
22
45
- const zip = zipper . sync . unzip ( packagePath ) . lowLevel ( ) ;
46
-
47
- glob
48
- . sync ( [ path . join ( requirementsPath , '**' ) ] , { mark : true , dot : true } )
49
- . forEach ( file => {
50
- if ( file . endsWith ( '/' ) ) {
51
- return ;
52
- }
53
-
54
- const relativeFile = path . relative ( requirementsPath , file ) ;
55
-
56
- if ( relativeFile . match ( / ^ _ _ p y c a c h e _ _ [ \\ / ] / ) ) {
57
- return ;
58
- }
59
- if ( noDeploy . has ( relativeFile . split ( / ( [ - \\ / ] | \. p y $ | \. p y c $ ) / , 1 ) [ 0 ] ) ) {
60
- return ;
61
- }
62
-
63
- zipFile ( zip , relativeFile , fse . readFileSync ( file ) ) ;
64
- } ) ;
65
-
66
- writeZip ( zip , packagePath ) ;
23
+ return fse
24
+ . readFileAsync ( packagePath )
25
+ . then ( buffer => JSZip . loadAsync ( buffer ) )
26
+ . then ( zip =>
27
+ BbPromise . resolve (
28
+ glob . sync ( [ path . join ( requirementsPath , '**' ) ] , {
29
+ mark : true ,
30
+ dot : true
31
+ } )
32
+ )
33
+ . map ( file => [ file , path . relative ( requirementsPath , file ) ] )
34
+ . filter (
35
+ ( [ file , relativeFile ] ) =>
36
+ ! file . endsWith ( '/' ) &&
37
+ ! relativeFile . match ( / ^ _ _ p y c a c h e _ _ [ \\ / ] / ) &&
38
+ ! noDeploy . has ( relativeFile . split ( / ( [ - \\ / ] | \. p y $ | \. p y c $ ) / , 1 ) [ 0 ] )
39
+ )
40
+ . map ( ( [ file , relativeFile ] ) =>
41
+ zipFile ( zip , relativeFile , fse . readFileAsync ( file ) )
42
+ )
43
+ . then ( ( ) => writeZip ( zip , packagePath ) )
44
+ ) ;
67
45
}
68
46
69
47
/**
70
- * remove all modules but the selected module from a package
71
- * @param {string } source original package
72
- * @param {string } target result package
48
+ * Remove all modules but the selected module from a package.
49
+ * @param {string } source path to original package
50
+ * @param {string } target path to result package
73
51
* @param {string } module module to keep
52
+ * @return {Promise } the JSZip object written out.
74
53
*/
75
54
function moveModuleUp ( source , target , module ) {
76
- const sourceZip = zipper . sync . unzip ( source ) . memory ( ) ;
77
- const targetZip = JSZip . make ( ) ;
78
-
79
- sourceZip . contents ( ) . forEach ( file => {
80
- if ( ! file . startsWith ( module + '/' ) ) {
81
- return ;
82
- }
83
- zipFile (
84
- targetZip ,
85
- file . replace ( module + '/' , '' ) ,
86
- sourceZip . read ( file , 'buffer' )
87
- ) ;
88
- } ) ;
89
-
90
- writeZip ( targetZip , target ) ;
55
+ const targetZip = new JSZip ( ) ;
56
+
57
+ return fse
58
+ . readFileAsync ( source )
59
+ . then ( buffer => JSZip . loadAsync ( buffer ) )
60
+ . then ( sourceZip => sourceZip . filter ( file => file . startsWith ( module + '/' ) ) )
61
+ . map ( srcZipObj =>
62
+ zipFile (
63
+ targetZip ,
64
+ srcZipObj . name . replace ( module + '/' , '' ) ,
65
+ srcZipObj . async ( 'nodebuffer' )
66
+ )
67
+ )
68
+ . then ( ( ) => writeZip ( targetZip , target ) ) ;
91
69
}
92
70
93
71
/**
94
- * inject requirements into packaged application
72
+ * Inject requirements into packaged application.
73
+ * @return {Promise } the combined promise for requirements injection.
95
74
*/
96
75
function injectAllRequirements ( ) {
97
76
this . serverless . cli . log ( 'Injecting required Python packages to package...' ) ;
@@ -101,30 +80,39 @@ function injectAllRequirements() {
101
80
}
102
81
103
82
if ( this . serverless . service . package . individually ) {
104
- values ( this . serverless . service . functions ) . forEach ( f => {
105
- if (
106
- ! ( f . runtime || this . serverless . service . provider . runtime ) . match (
83
+ return BbPromise . resolve ( values ( this . serverless . service . functions ) )
84
+ . filter ( func =>
85
+ ( func . runtime || this . serverless . service . provider . runtime ) . match (
107
86
/ ^ p y t h o n .* /
108
87
)
109
- ) {
110
- return ;
111
- }
112
- if ( ! get ( f , 'module' ) ) {
113
- set ( f , [ 'module' ] , '.' ) ;
114
- }
115
- if ( f . module !== '.' ) {
116
- const artifactPath = path . join ( '.serverless' , `${ f . module } .zip` ) ;
117
- moveModuleUp ( f . package . artifact , artifactPath , f . module ) ;
118
- f . package . artifact = artifactPath ;
119
- }
120
- injectRequirements (
121
- path . join ( '.serverless' , f . module , 'requirements' ) ,
122
- f . package . artifact ,
123
- this . options
88
+ )
89
+ . map ( func => {
90
+ if ( ! get ( func , 'module' ) ) {
91
+ set ( func , [ 'module' ] , '.' ) ;
92
+ }
93
+ return func ;
94
+ } )
95
+ . map ( func => {
96
+ if ( func . module !== '.' ) {
97
+ const artifact = func . package . artifact ;
98
+ const newArtifact = path . join ( '.serverless' , `${ func . module } .zip` ) ;
99
+ func . package . artifact = newArtifact ;
100
+ return moveModuleUp ( artifact , newArtifact , func . module ) . then (
101
+ ( ) => func
102
+ ) ;
103
+ } else {
104
+ return func ;
105
+ }
106
+ } )
107
+ . map ( func =>
108
+ injectRequirements (
109
+ path . join ( '.serverless' , func . module , 'requirements' ) ,
110
+ func . package . artifact ,
111
+ this . options
112
+ )
124
113
) ;
125
- } ) ;
126
114
} else {
127
- injectRequirements (
115
+ return injectRequirements (
128
116
path . join ( '.serverless' , 'requirements' ) ,
129
117
this . serverless . service . package . artifact ,
130
118
this . options
0 commit comments