Skip to content

Commit 4c0c95a

Browse files
Translate Pipfiles to Requirements in modules
The plugin does not properly handle Pipfiles that sit in submodules since the pipenv integration does not anticipate submodules. This commit reworks the pipenv integration such that submodules are supported. This changes will convert Pipfiles into requirements as they are parsed by `pip.js` instead of doing it as a pre-processing step. This is done since the submodule discovery logic sits in pip.js.
1 parent 1c14588 commit 4c0c95a

File tree

3 files changed

+25
-15
lines changed

3 files changed

+25
-15
lines changed

index.js

-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ const {
1212
const { injectAllRequirements } = require('./lib/inject');
1313
const { layerRequirements } = require('./lib/layer');
1414
const { installAllRequirements } = require('./lib/pip');
15-
const { pipfileToRequirements } = require('./lib/pipenv');
1615
const { pyprojectTomlToRequirements } = require('./lib/poetry');
1716
const { cleanup, cleanupCache } = require('./lib/clean');
1817

@@ -165,7 +164,6 @@ class ServerlessPythonRequirements {
165164
return;
166165
}
167166
return BbPromise.bind(this)
168-
.then(pipfileToRequirements)
169167
.then(pyprojectTomlToRequirements)
170168
.then(addVendorHelper)
171169
.then(installAllRequirements)

lib/pip.js

+10-6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const {
1313
getRequirementsWorkingPath,
1414
getUserCachePath
1515
} = require('./shared');
16+
const { pipfileToRequirements } = require('./pipenv');
1617

1718
/**
1819
* Omit empty commands.
@@ -55,6 +56,7 @@ function mergeCommands(commands) {
5556
*/
5657
function generateRequirementsFile(
5758
requirementsPath,
59+
modulePath,
5860
targetFile,
5961
serverless,
6062
servicePath,
@@ -74,10 +76,11 @@ function generateRequirementsFile(
7476
);
7577
} else if (
7678
options.usePipenv &&
77-
fse.existsSync(path.join(servicePath, 'Pipfile'))
79+
fse.existsSync(path.join(servicePath, modulePath, 'Pipfile'))
7880
) {
81+
pipfileToRequirements(modulePath, targetFile, serverless, options);
7982
filterRequirementsFile(
80-
path.join(servicePath, '.serverless/requirements.txt'),
83+
targetFile,
8184
targetFile,
8285
options
8386
);
@@ -398,19 +401,19 @@ function copyVendors(vendorFolder, targetFolder, serverless) {
398401
* @param {Object} options
399402
* @param {string} fileName
400403
*/
401-
function requirementsFileExists(servicePath, options, fileName) {
404+
function requirementsFileExists(servicePath, modulePath, options) {
402405
if (
403406
options.usePoetry &&
404407
fse.existsSync(path.join(servicePath, 'pyproject.toml'))
405408
) {
406409
return true;
407410
}
408411

409-
if (options.usePipenv && fse.existsSync(path.join(servicePath, 'Pipfile'))) {
412+
if (options.usePipenv && fse.existsSync(path.join(servicePath, modulePath, 'Pipfile'))) {
410413
return true;
411414
}
412415

413-
if (fse.existsSync(fileName)) {
416+
if (fse.existsSync(path.join(servicePath, modulePath, options.fileName))) {
414417
return true;
415418
}
416419

@@ -439,7 +442,7 @@ function installRequirementsIfNeeded(
439442
const fileName = path.join(servicePath, modulePath, options.fileName);
440443

441444
// Skip requirements generation, if requirements file doesn't exist
442-
if (!requirementsFileExists(servicePath, options, fileName)) {
445+
if (!requirementsFileExists(servicePath, modulePath, options)) {
443446
return false;
444447
}
445448

@@ -459,6 +462,7 @@ function installRequirementsIfNeeded(
459462

460463
generateRequirementsFile(
461464
fileName,
465+
modulePath,
462466
slsReqsTxt,
463467
serverless,
464468
servicePath,

lib/pipenv.js

+15-7
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,32 @@ const { EOL } = require('os');
66
/**
77
* pipenv install
88
*/
9-
function pipfileToRequirements() {
9+
function pipfileToRequirements(
10+
modulePath,
11+
outputRequirements,
12+
serverless,
13+
options
14+
) {
15+
const pipenvPath = path.join(modulePath, 'Pipfile')
16+
17+
// Stop if Pipfile file does not exist
1018
if (
11-
!this.options.usePipenv ||
12-
!fse.existsSync(path.join(this.servicePath, 'Pipfile'))
19+
!options.usePipenv ||
20+
!fse.existsSync(pipenvPath)
1321
) {
1422
return;
1523
}
1624

17-
this.serverless.cli.log('Generating requirements.txt from Pipfile...');
25+
serverless.cli.log('Generating requirements.txt from Pipfile...');
1826

1927
const res = spawnSync(
2028
'pipenv',
2129
['lock', '--requirements', '--keep-outdated'],
2230
{
23-
cwd: this.servicePath
31+
cwd: modulePath
2432
}
2533
);
34+
2635
if (res.error) {
2736
if (res.error.code === 'ENOENT') {
2837
throw new Error(
@@ -34,9 +43,8 @@ function pipfileToRequirements() {
3443
if (res.status !== 0) {
3544
throw new Error(res.stderr);
3645
}
37-
fse.ensureDirSync(path.join(this.servicePath, '.serverless'));
3846
fse.writeFileSync(
39-
path.join(this.servicePath, '.serverless/requirements.txt'),
47+
outputRequirements,
4048
removeEditableFlagFromRequirementsString(res.stdout)
4149
);
4250
}

0 commit comments

Comments
 (0)