Skip to content

Refactor deploy omittion. closes #57 #58

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,21 @@ custom:
```

## Omitting Packages
You can omit a package from deployment by adding `#no-deploy` to the
requirement's line in `requirements.txt`. For example, this will not install
the AWS SDKs that are already installed on Lambda, but will install numpy:
```
numpy
boto3 #no-deploy
botocore #no-deploy
docutils #no-deploy
jmespath #no-deploy
python-dateutil #no-deploy
s3transfer #no-deploy
six #no-deploy
You can omit a package from deployment with the `noDeploy` option. Note that
dependencies of omitted packages must explicitly be omitted too.
For example, this will not install the AWS SDKs that are already installed on
Lambda:
```yaml
custom:
pythonRequirements:
noDeploy:
- boto3
- botocore
- docutils
- jmespath
- python-dateutil
- s3transfer
- six
```

## extra pip arguments
Expand Down
1 change: 1 addition & 0 deletions example/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
requests
six
1 change: 1 addition & 0 deletions example/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ custom:
zip: false
cleanupZipHelper: true
dockerizePip: false
noDeploy: []

package:
exclude:
Expand Down
48 changes: 10 additions & 38 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,41 +41,13 @@ class ServerlessPythonRequirements {
}
};

/**
* parse requirements.txt into .requirements.txt, leaving out #no-deploy lines
* @return {true}
*/
parseRequirements() {
if (!fse.existsSync(path.join(this.serverless.config.servicePath,
'requirements.txt'))) {
return true;
}

this.serverless.cli.log(
`Parsing Python requirements.txt`);

const reqs = fse.readFileSync('requirements.txt').toString().split('\n');

let newReqs = '';
for (const req of reqs) {
if (req.indexOf('#no-deploy') === -1) {
newReqs += `${req}\n`;
}
}
if (!fse.existsSync('.serverless'))
fse.mkdirSync('.serverless');
fse.writeFileSync('.serverless/requirements.txt', newReqs, 'utf8');

return true;
};

/**
* pip install the requirements to the .requirements directory
* @return {Promise}
*/
installRequirements() {
if (!fse.existsSync(path.join(this.serverless.config.servicePath,
'.serverless/requirements.txt'))) {
'requirements.txt'))) {
return BbPromise.resolve();
}

Expand All @@ -88,7 +60,7 @@ class ServerlessPythonRequirements {
let options;
const pipCmd = [
runtime, '-m', 'pip', '--isolated', 'install',
'-t', '.requirements', '-r', '.serverless/requirements.txt',
'-t', '.requirements', '-r', 'requirements.txt',
];
if (this.custom().pipCmdExtraArgs) {
pipCmd.push(...this.custom().pipCmdExtraArgs);
Expand Down Expand Up @@ -148,9 +120,12 @@ class ServerlessPythonRequirements {
linkRequirements() {
if (!this.custom().zip) {
this.serverless.cli.log('Linking required Python packages...');
const noDeploy = new Set(this.custom().noDeploy || []);
fse.readdirSync('.requirements').map((file) => {
this.serverless.service.package.include.push(file);
this.serverless.service.package.include.push(`${file}/**`);
if (noDeploy.has(file))
return;
this.serverless.service.package.include.push(file);
this.serverless.service.package.include.push(`${file}/**`);
try {
fse.symlinkSync(`.requirements/${file}`, `./${file}`);
} catch (exception) {
Expand All @@ -159,11 +134,10 @@ class ServerlessPythonRequirements {
linkDest = fse.readlinkSync(`./${file}`);
} catch (e) {}
if (linkDest !== `.requirements/${file}`)
throw new Error(`Unable to link dependency '${file}' because a file
by the same name exists in this service`);
throw new Error(`Unable to link dependency '${file}' because a file
by the same name exists in this service`);
}
}
);
});
}
}

Expand Down Expand Up @@ -244,7 +218,6 @@ class ServerlessPythonRequirements {

let before = () => BbPromise.bind(this)
.then(this.addVendorHelper)
.then(this.parseRequirements)
.then(this.packRequirements)
.then(this.linkRequirements);

Expand All @@ -270,7 +243,6 @@ class ServerlessPythonRequirements {
'after:deploy:function:packageFunction': after,
'requirements:install:install': () => BbPromise.bind(this)
.then(this.addVendorHelper)
.then(this.parseRequirements)
.then(this.packRequirements),
'requirements:clean:clean': () => BbPromise.bind(this)
.then(this.cleanup)
Expand Down
14 changes: 14 additions & 0 deletions test.bats
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ teardown() {
ls puck/.requirements.zip puck/unzip_requirements.py
}

@test "py3.6 doesn't package six with noDeploy option" {
sed -i'.bak' -e 's/noDeploy:.*/noDeploy: [six]/' serverless.yml
sls package
unzip .serverless/sls-py-req-test.zip -d puck
! ls puck/six
}

@test "py3.6 can package requests with zip & dockerizePip option" {
[ -z "$CIRCLE_BRANCH" ] || skip "Volumes are weird in CircleCI https://circleci.com/docs/2.0/building-docker-images/#mounting-folders"
! uname -sm|grep Linux || groups|grep docker || id -u|egrep '^0$' || skip "can't dockerize on linux if not root & not in docker group"
Expand Down Expand Up @@ -61,6 +68,13 @@ teardown() {
ls puck/.requirements.zip puck/unzip_requirements.py
}

@test "py2.7 doesn't package six with noDeploy option" {
sed -i'.bak' -e 's/runtime: *python3.6/runtime: python2.7/' -e 's/noDeploy:.*/noDeploy: [six]/' serverless.yml
sls package
unzip .serverless/sls-py-req-test.zip -d puck
! ls puck/six
}

@test "py2.7 can package requests with zip & dockerizePip option" {
[ -z "$CIRCLE_BRANCH" ] || skip "Volumes are weird in CircleCI https://circleci.com/docs/2.0/building-docker-images/#mounting-folders"
! uname -sm|grep Linux || groups|grep docker || id -u|egrep '^0$' || skip "can't dockerize on linux if not root & not in docker group"
Expand Down