Skip to content

Commit 3b20787

Browse files
committed
override slimPatterns instead of appending (serverless#276)
closes serverless#216
1 parent abc9a10 commit 3b20787

File tree

8 files changed

+191
-19
lines changed

8 files changed

+191
-19
lines changed

README.md

+12-2
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ except ImportError:
116116
_Works on non 'win32' environments: Docker, WSL are included_
117117
To remove the tests, information and caches from the installed packages,
118118
enable the `slim` option. This will: `strip` the `.so` files, remove `__pycache__`
119-
directories and `dist-info` directories.
119+
and `dist-info` directories as well as `.pyc` and `.pyo` files.
120120
```yaml
121121
custom:
122122
pythonRequirements:
@@ -125,7 +125,8 @@ custom:
125125
#### Custom Removal Patterns
126126
To specify additional directories to remove from the installed packages,
127127
define a list of patterns in the serverless config using the `slimPatterns`
128-
option and glob syntax. Note, it matches against whole paths, so to match a file in any
128+
option and glob syntax. These paterns will be added to the default ones (`**/*.py[c|o]`, `**/__pycache__*`, `**/*.dist-info*`).
129+
Note, the glob syntax matches against whole paths, so to match a file in any
129130
directory, start your pattern with `**/`.
130131
```yaml
131132
custom:
@@ -134,6 +135,15 @@ custom:
134135
slimPatterns:
135136
- "**/*.egg-info*"
136137
```
138+
To overwrite the default patterns set the option `slimPatternsAppendDefaults` to `false` (`true` by default).
139+
```yaml
140+
custom:
141+
pythonRequirements:
142+
slim: true
143+
slimPatternsAppendDefaults: false
144+
slimPatterns:
145+
- "**/*.egg-info*"
146+
```
137147
This will remove all folders within the installed requirements that match
138148
the names in `slimPatterns`
139149
## Omitting Packages

appveyor.yml

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
version: '{build}'
22
init:
3-
- ps: npm i -g serverless
3+
- cmd: pip install pipenv
4+
- ps: npm i -g serverless
45
build: off
56
test_script:
6-
- cmd: >-
7-
npm i
7+
- cmd: >-
8+
npm i
89
9-
node test.js
10+
node test.js

index.js

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class ServerlessPythonRequirements {
2929
{
3030
slim: false,
3131
slimPatterns: false,
32+
slimPatternsAppendDefaults: true,
3233
zip: false,
3334
cleanupZipHelper: true,
3435
invalidateCaches: false,

lib/slim.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ const getStripCommand = (options, folderPath) =>
1010
const deleteFiles = (options, folderPath) => {
1111
let patterns = ['**/*.py[c|o]', '**/__pycache__*', '**/*.dist-info*'];
1212
if (options.slimPatterns) {
13-
patterns = patterns.concat(options.slimPatterns);
13+
if (
14+
options.slimPatternsAppendDefaults === false ||
15+
options.slimPatternsAppendDefaults == 'false'
16+
) {
17+
patterns = options.slimPatterns;
18+
} else {
19+
patterns = patterns.concat(options.slimPatterns);
20+
}
1421
}
1522
for (const pattern of patterns) {
1623
for (const file of glob.sync(`${folderPath}/${pattern}`)) {

test.bats

+1-3
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ teardown() {
297297
cd tests/base
298298
cat _slimPatterns.yml > slimPatterns.yml
299299
npm i $(npm pack ../..)
300-
sls --runtime=python2.7 --slim=true packag
300+
sls --runtime=python2.7 --slim=true package
301301
unzip .serverless/sls-py-req-test.zip -d puck
302302
ls puck/flask
303303
test $(find puck -name "*.pyc" | wc -l) -eq 0
@@ -462,7 +462,6 @@ teardown() {
462462
test $(find "puck*" -name "*.pyc" | wc -l) -eq 0
463463
}
464464

465-
466465
@test "py2.7 can package flask with package individually option" {
467466
cd tests/base
468467
npm i $(npm pack ../..)
@@ -488,7 +487,6 @@ teardown() {
488487
test $(find puck* -name "*.pyc" | wc -l) -eq 0
489488
}
490489

491-
492490
@test "py3.6 can package only requirements of module" {
493491
cd tests/individually
494492
npm i $(npm pack ../..)

test.js

+160-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const deasync = require('deasync-promise');
33
const glob = require('glob-all');
44
const JSZip = require('jszip');
55
const tape = require('tape');
6-
const { removeSync, readFileSync } = require('fs-extra');
6+
const { removeSync, readFileSync, copySync } = require('fs-extra');
77
const { sep } = require('path');
88

99
const { getUserCachePath } = require('./lib/shared');
@@ -63,8 +63,8 @@ const teardown = () => {
6363
removeSync('tests/base with a space');
6464
};
6565

66-
const test = (desc, func) =>
67-
tape.test(desc, t => {
66+
const test = (desc, func, opts = {}) =>
67+
tape.test(desc, opts, t => {
6868
setup();
6969
try {
7070
func(t);
@@ -86,7 +86,17 @@ const listRequirementsZipFiles = filename => {
8686
const zip = deasync(new JSZip().loadAsync(readFileSync(filename)));
8787
const reqsBuffer = deasync(zip.file('.requirements.zip').async('nodebuffer'));
8888
const reqsZip = deasync(new JSZip().loadAsync(reqsBuffer));
89-
return Object.keys(reqsZip.files)
89+
return Object.keys(reqsZip.files);
90+
};
91+
92+
const canUseDocker = () => {
93+
let result;
94+
try {
95+
result = crossSpawn.sync('docker', ['ps']);
96+
} catch (e) {
97+
return false;
98+
}
99+
return result.status === 0;
90100
};
91101

92102
test('default pythonBin can package flask with default options', t => {
@@ -142,7 +152,6 @@ test('py3.6 can package flask with slim option', t => {
142152
t.end();
143153
});
144154

145-
146155
/*
147156
* News tests not in test.bats
148157
*/
@@ -151,10 +160,18 @@ test("py3.6 doesn't package bottle with zip option", t => {
151160
process.chdir('tests/base');
152161
const path = npm(['pack', '../..']);
153162
npm(['i', path]);
154-
perl(['-p', "-i'.bak'", '-e', 's/(pythonRequirements:$)/\\1\\n noDeploy: [bottle]/', 'serverless.yml'])
163+
perl([
164+
'-p',
165+
"-i'.bak'",
166+
'-e',
167+
's/(pythonRequirements:$)/\\1\\n noDeploy: [bottle]/',
168+
'serverless.yml'
169+
]);
155170
sls([`--pythonBin=${getPythonBin(3)}`, '--zip=true', 'package']);
156171
const zipfiles = listZipFiles('.serverless/sls-py-req-test.zip');
157-
const zippedReqs = listRequirementsZipFiles('.serverless/sls-py-req-test.zip');
172+
const zippedReqs = listRequirementsZipFiles(
173+
'.serverless/sls-py-req-test.zip'
174+
);
158175
t.true(
159176
zipfiles.includes('.requirements.zip'),
160177
'zipped requirements are packaged'
@@ -164,7 +181,141 @@ test("py3.6 doesn't package bottle with zip option", t => {
164181
zipfiles.includes(`flask${sep}__init__.py`),
165182
"flask isn't packaged on its own"
166183
);
167-
t.true(zippedReqs.includes(`flask/__init__.py`), 'flask is packaged in the .requirements.zip file');
168-
t.false(zippedReqs.includes(`bottle.py`), 'bottle is not packaged in the .requirements.zip file');
184+
t.true(
185+
zippedReqs.includes(`flask/__init__.py`),
186+
'flask is packaged in the .requirements.zip file'
187+
);
188+
t.false(
189+
zippedReqs.includes(`bottle.py`),
190+
'bottle is not packaged in the .requirements.zip file'
191+
);
192+
t.end();
193+
});
194+
195+
test('py3.6 can package flask with slim, slimPatterns & slimPatternsAppendDefaults=false options', t => {
196+
process.chdir('tests/base');
197+
copySync('_slimPatterns.yml', 'slimPatterns.yml');
198+
const path = npm(['pack', '../..']);
199+
npm(['i', path]);
200+
sls(['--slim=true', '--slimPatternsAppendDefaults=false', 'package']);
201+
202+
const zipfiles = listZipFiles('.serverless/sls-py-req-test.zip');
203+
t.true(zipfiles.includes(`flask${sep}__init__.py`), 'flask is packaged');
204+
t.true(
205+
zipfiles.filter(filename => filename.endsWith('.pyc')).length >= 1,
206+
'pyc files are packaged'
207+
);
208+
t.deepEqual(
209+
zipfiles.filter(filename => filename.includes('.egg-info')),
210+
[],
211+
'.egg-info folders are not packaged'
212+
);
213+
t.end();
214+
});
215+
216+
test(
217+
'py3.6 can package flask with slim & dockerizePip & slimPatterns & slimPatternsAppendDefaults=false options',
218+
t => {
219+
process.chdir('tests/base');
220+
copySync('_slimPatterns.yml', 'slimPatterns.yml');
221+
const path = npm(['pack', '../..']);
222+
npm(['i', path]);
223+
sls([
224+
'--dockerizePip=true',
225+
'--slim=true',
226+
'--slimPatternsAppendDefaults=false',
227+
'package'
228+
]);
229+
230+
const zipfiles = listZipFiles('.serverless/sls-py-req-test.zip');
231+
t.true(zipfiles.includes(`flask${sep}__init__.py`), 'flask is packaged');
232+
t.true(
233+
zipfiles.filter(filename => filename.endsWith('.pyc')).length >= 1,
234+
'pyc files are packaged'
235+
);
236+
t.deepEqual(
237+
zipfiles.filter(filename => filename.includes('.egg-infooo')),
238+
[],
239+
'.egg-info folders are not packaged'
240+
);
241+
t.end();
242+
},
243+
{ skip: !canUseDocker() }
244+
);
245+
246+
test('py2.7 can package flask with slim & slimPatterns & slimPatternsAppendDefaults=false options', t => {
247+
process.chdir('tests/base');
248+
copySync('_slimPatterns.yml', 'slimPatterns.yml');
249+
const path = npm(['pack', '../..']);
250+
npm(['i', path]);
251+
sls([
252+
'--runtime=python2.7',
253+
'--slim=true',
254+
'--slimPatternsAppendDefaults=false',
255+
'package'
256+
]);
257+
258+
const zipfiles = listZipFiles('.serverless/sls-py-req-test.zip');
259+
t.true(zipfiles.includes(`flask${sep}__init__.py`), 'flask is packaged');
260+
t.true(
261+
zipfiles.filter(filename => filename.endsWith('.pyc')).length >= 1,
262+
'pyc files are packaged'
263+
);
264+
t.deepEqual(
265+
zipfiles.filter(filename => filename.includes('.egg-info')),
266+
[],
267+
'.egg-info folders are not packaged'
268+
);
269+
t.end();
270+
});
271+
272+
test(
273+
'py2.7 can package flask with slim & dockerizePip & slimPatterns & slimPatternsAppendDefaults=false options',
274+
t => {
275+
process.chdir('tests/base');
276+
copySync('_slimPatterns.yml', 'slimPatterns.yml');
277+
const path = npm(['pack', '../..']);
278+
npm(['i', path]);
279+
sls([
280+
'--dockerizePip=true',
281+
'--runtime=python2.7',
282+
'--slim=true',
283+
'--slimPatternsAppendDefaults=false',
284+
'package'
285+
]);
286+
const zipfiles = listZipFiles('.serverless/sls-py-req-test.zip');
287+
t.true(zipfiles.includes(`flask${sep}__init__.py`), 'flask is packaged');
288+
t.true(
289+
zipfiles.filter(filename => filename.endsWith('.pyc')).length >= 1,
290+
'pyc files are packaged'
291+
);
292+
t.deepEqual(
293+
zipfiles.filter(filename => filename.includes('.egg-info')),
294+
[],
295+
'.egg-info folders are not packaged'
296+
);
297+
t.end();
298+
},
299+
{ skip: !canUseDocker() }
300+
);
301+
302+
test('pipenv py3.6 can package flask with slim & slimPatterns & slimPatternsAppendDefaults=false option', t => {
303+
process.chdir('tests/pipenv');
304+
copySync('_slimPatterns.yml', 'slimPatterns.yml');
305+
const path = npm(['pack', '../..']);
306+
npm(['i', path]);
307+
308+
sls(['--slim=true', '--slimPatternsAppendDefaults=false', 'package']);
309+
const zipfiles = listZipFiles('.serverless/sls-py-req-test.zip');
310+
t.true(zipfiles.includes(`flask${sep}__init__.py`), 'flask is packaged');
311+
t.true(
312+
zipfiles.filter(filename => filename.endsWith('.pyc')).length >= 1,
313+
'pyc files are packaged'
314+
);
315+
t.deepEqual(
316+
zipfiles.filter(filename => filename.includes('.egg-info')),
317+
[],
318+
'.egg-info folders are not packaged'
319+
);
169320
t.end();
170321
});

tests/base/serverless.yml

+2
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ custom:
1212
dockerizePip: ${opt:dockerizePip, self:custom.defaults.dockerizePip}
1313
slim: ${opt:slim, self:custom.defaults.slim}
1414
slimPatterns: ${file(./slimPatterns.yml):slimPatterns, self:custom.defaults.slimPatterns}
15+
slimPatternsAppendDefaults: ${opt:slimPatternsAppendDefaults, self:custom.defaults.slimPatternsAppendDefaults}
1516
vendor: ${opt:vendor, ''}
1617
fileName: ${opt:fileName, 'requirements.txt'}
1718
defaults:
1819
slim: false
1920
slimPatterns: false
21+
slimPatternsAppendDefaults: true
2022
zip: false
2123
dockerizePip: false
2224
individually: false

tests/pipenv/serverless.yml

+2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ custom:
1111
zip: ${opt:zip, self:custom.defaults.zip}
1212
slim: ${opt:slim, self:custom.defaults.slim}
1313
slimPatterns: ${file(./slimPatterns.yml):slimPatterns, self:custom.defaults.slimPatterns}
14+
slimPatternsAppendDefaults: ${opt:slimPatternsAppendDefaults, self:custom.defaults.slimPatternsAppendDefaults}
1415
dockerizePip: ${opt:dockerizePip, self:custom.defaults.dockerizePip}
1516
defaults:
1617
zip: false
1718
slimPatterns: false
19+
slimPatternsAppendDefaults: true
1820
slim: false
1921
dockerizePip: false
2022

0 commit comments

Comments
 (0)