diff --git a/index.js b/index.js index c826bb88..2900cef8 100644 --- a/index.js +++ b/index.js @@ -28,9 +28,10 @@ class ServerlessPythonRequirements { return new BbPromise((resolve, reject) => { let cmd = 'pip'; let options = [ - 'install', + '--isolated', 'install', '-t', '.requirements', '-r', 'requirements.txt', + '-U', '--upgrade-strategy=only-if-needed' ]; if (this.serverless.service.custom && this.serverless.service.custom.dockerizePip) { @@ -52,8 +53,34 @@ class ServerlessPythonRequirements { }); }; + packLocalRequirements() { + if (!fse.existsSync(path.join(this.serverless.config.servicePath, 'requirements.txt'))) { + return BbPromise.resolve(); + } + + this.serverless.cli.log('Packaging required Python packages locally...'); + + return new BbPromise((resolve, reject) => { + let cmd = 'pip'; + let options = [ + '--isolated', 'install', + '-t', '.local_requirements', + '-r', 'requirements.txt', + '-U', '--upgrade-strategy=only-if-needed' + ]; + const res = child_process.spawnSync(cmd, options); + if (res.error) { + return reject(res.error); + } + if (res.status != 0) { + return reject(res.stderr); + } + resolve(); + }); + }; + cleanup() { - const artifacts = ['requirements.py', '.requirements']; + const artifacts = ['requirements.py', '.requirements', '.local_requirements']; return BbPromise.all(_.map(artifacts, (artifact) => fse.removeAsync(path.join(this.serverless.config.servicePath, artifact))));; @@ -87,10 +114,18 @@ class ServerlessPythonRequirements { ], }, 'install': { - usage: 'install requirements manually', + usage: 'Install requirements manually', lifecycleEvents: [ 'install', ], + commands: { + 'local': { + usage: 'Install requirements using host machine (not docker) into .local_requirements', + lifecycleEvents: [ + 'installLocal' + ] + } + }, }, }, }, @@ -105,6 +140,10 @@ class ServerlessPythonRequirements { .then(this.packVendorHelper) .then(this.packRequirements), + 'requirements:install:local:installLocal': () => BbPromise.bind(this) + .then(this.packVendorHelper) + .then(this.packLocalRequirements), + 'requirements:clean:clean': () => BbPromise.bind(this) .then(this.cleanup) }; diff --git a/requirements.py b/requirements.py index 69b62859..d75cab76 100644 --- a/requirements.py +++ b/requirements.py @@ -7,5 +7,11 @@ '.requirements', ) -if requirements not in sys.path: - sys.path.append(requirements) +local_requirements = os.path.join( + os.path.split(__file__)[0], + '.local_requirements', +) + +for path in [requirements, local_requirements]: + if os.path.isdir(path) and path not in sys.path: + sys.path.insert(1, path)