Skip to content

Commit c9d910c

Browse files
authored
Fix resolving requirements recursively (#396)
Fix resolving requirements recursively
2 parents dddea23 + 49ab1f3 commit c9d910c

File tree

6 files changed

+52
-4
lines changed

6 files changed

+52
-4
lines changed

lib/pip.js

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,28 @@ function dockerPathForWin(path) {
338338
return path;
339339
}
340340
}
341+
342+
/**
343+
* get requirements from requirements.txt
344+
* @param {string} source
345+
* @return {string[]}
346+
*/
347+
function getRequirements(source) {
348+
const requirements = fse
349+
.readFileSync(source, { encoding: 'utf-8' })
350+
.replace(/\\\n/g, ' ')
351+
.split(/\r?\n/);
352+
353+
return requirements.reduce((acc, req) => {
354+
req = req.trim();
355+
if (!req.startsWith('-r')) {
356+
return [...acc, req];
357+
}
358+
source = path.join(path.dirname(source), req.replace(/^-r\s+/, ''));
359+
return [...acc, ...getRequirements(source)];
360+
}, []);
361+
}
362+
341363
/** create a filtered requirements.txt without anything from noDeploy
342364
* then remove all comments and empty lines, and sort the list which
343365
* assist with matching the static cache. The sorting will skip any
@@ -351,10 +373,7 @@ function dockerPathForWin(path) {
351373
*/
352374
function filterRequirementsFile(source, target, options) {
353375
const noDeploy = new Set(options.noDeploy || []);
354-
const requirements = fse
355-
.readFileSync(source, { encoding: 'utf-8' })
356-
.replace(/\\\n/g, ' ')
357-
.split(/\r?\n/);
376+
const requirements = getRequirements(source);
358377
var prepend = [];
359378
const filteredRequirements = requirements.filter(req => {
360379
req = req.trim();

test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,21 @@ test('py3.6 can package flask with hashes', t => {
170170
t.end();
171171
});
172172

173+
test('py3.6 can package flask with nested', t => {
174+
process.chdir('tests/base');
175+
const path = npm(['pack', '../..']);
176+
npm(['i', path]);
177+
sls([
178+
`--pythonBin=${getPythonBin(3)}`,
179+
'--fileName=requirements-w-nested.txt',
180+
'package'
181+
]);
182+
const zipfiles = listZipFiles('.serverless/sls-py-req-test.zip');
183+
t.true(zipfiles.includes(`flask${sep}__init__.py`), 'flask is packaged');
184+
t.true(zipfiles.includes(`boto3${sep}__init__.py`), 'boto3 is packaged');
185+
t.end();
186+
});
187+
173188
test('py3.6 can package flask with zip option', t => {
174189
process.chdir('tests/base');
175190
const path = npm(['pack', '../..']);
@@ -1471,6 +1486,10 @@ test('py3.6 can package only requirements of module', t => {
14711486
zipfiles_hello.includes(`pyaml${sep}__init__.py`),
14721487
'pyaml is packaged in function hello1'
14731488
);
1489+
t.true(
1490+
zipfiles_hello.includes(`boto3${sep}__init__.py`),
1491+
'boto3 is packaged in function hello1'
1492+
);
14741493
t.false(
14751494
zipfiles_hello.includes(`flask${sep}__init__.py`),
14761495
'flask is NOT packaged in function hello1'
@@ -1491,6 +1510,10 @@ test('py3.6 can package only requirements of module', t => {
14911510
zipfiles_hello2.includes(`pyaml${sep}__init__.py`),
14921511
'pyaml is NOT packaged in function hello2'
14931512
);
1513+
t.false(
1514+
zipfiles_hello2.includes(`boto3${sep}__init__.py`),
1515+
'boto3 is NOT packaged in function hello2'
1516+
);
14941517
t.true(
14951518
zipfiles_hello2.includes(`flask${sep}__init__.py`),
14961519
'flask is packaged in function hello2'

tests/base/requirements-common.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
boto3

tests/base/requirements-w-nested.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
flask
2+
bottle
3+
-r requirements-common.txt
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
-r ../requirements-common.txt
12
pyaml
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
boto3

0 commit comments

Comments
 (0)