From 5a637a2af91bfd83990e2fedcaaa7c2e005f66b6 Mon Sep 17 00:00:00 2001 From: naoyasugita <sugita6878@gmail.com> Date: Sun, 12 Feb 2023 12:21:16 +0900 Subject: [PATCH 1/7] feat: ref noDeploy option when use layers --- lib/layer.js | 5 +++-- lib/zipTree.js | 32 +++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/lib/layer.js b/lib/layer.js index 6fe9ca4c..569c425d 100644 --- a/lib/layer.js +++ b/lib/layer.js @@ -2,7 +2,7 @@ const BbPromise = require('bluebird'); const fse = require('fs-extra'); const path = require('path'); const JSZip = require('jszip'); -const { writeZip, addTree } = require('./zipTree'); +const { writeZip, addTreeNoDeploy } = require('./zipTree'); const { sha256Path, getRequirementsLayerPath } = require('./shared'); BbPromise.promisifyAll(fse); @@ -39,9 +39,10 @@ function zipRequirements() { } else { const rootZip = new JSZip(); const runtimepath = 'python'; + const noDeploy = new Set(this.options.noDeploy || []); promises.push( - addTree(rootZip.folder(runtimepath), src).then(() => + addTreeNoDeploy(rootZip.folder(runtimepath), src, noDeploy).then(() => writeZip(rootZip, zipCachePath) ) ); diff --git a/lib/zipTree.js b/lib/zipTree.js index 1654f665..4ad7b086 100644 --- a/lib/zipTree.js +++ b/lib/zipTree.js @@ -32,6 +32,36 @@ function addTree(zip, src) { .then(() => zip); // Original zip for chaining. } +/** + * Add a directory recursively to a zip file. Files in src will be added to the top folder of zip. + * @param {JSZip} zip a zip object in the folder you want to add files to. + * @param {string} src the source folder. + * @param {Object} noDeploy the source folder. + * @return {Promise} a promise offering the original JSZip object. + */ +function addTreeNoDeploy(zip, src, noDeploy) { + const srcN = path.normalize(src); + + return fse + .readdirAsync(srcN) + .filter(name => !noDeploy.has(name)) + .map((name) => { + const srcPath = path.join(srcN, name); + + return fse.statAsync(srcPath).then((stat) => { + if (stat.isDirectory()) { + return addTreeNoDeploy(zip.folder(name), srcPath, noDeploy); + } else { + const opts = { date: stat.mtime, unixPermissions: stat.mode }; + return fse + .readFileAsync(srcPath) + .then((data) => zip.file(name, data, opts)); + } + }); + }) + .then(() => zip); // Original zip for chaining. +} + /** * Write zip contents to a file. * @param {JSZip} zip the zip object @@ -81,4 +111,4 @@ function zipFile(zip, zipPath, bufferPromise, fileOpts) { .then(() => zip); } -module.exports = { addTree, writeZip, zipFile }; +module.exports = { addTree, writeZip, zipFile , addTreeNoDeploy }; From 17f7f3bfd7cab7e5aabb10d7537a66ac8c7e3ee4 Mon Sep 17 00:00:00 2001 From: naoyasugita <sugita6878@gmail.com> Date: Sun, 12 Feb 2023 12:25:33 +0900 Subject: [PATCH 2/7] fix: docstring --- lib/zipTree.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/zipTree.js b/lib/zipTree.js index 4ad7b086..307fda37 100644 --- a/lib/zipTree.js +++ b/lib/zipTree.js @@ -36,7 +36,7 @@ function addTree(zip, src) { * Add a directory recursively to a zip file. Files in src will be added to the top folder of zip. * @param {JSZip} zip a zip object in the folder you want to add files to. * @param {string} src the source folder. - * @param {Object} noDeploy the source folder. + * @param {Object} noDeploy * @return {Promise} a promise offering the original JSZip object. */ function addTreeNoDeploy(zip, src, noDeploy) { From e1272237a141a27c4f74ecbfd423338a0eee5b8f Mon Sep 17 00:00:00 2001 From: naoyasugita <sugita6878@gmail.com> Date: Thu, 3 Aug 2023 16:18:10 +0900 Subject: [PATCH 3/7] fix: Add noDeploy parameter to addTree() --- lib/layer.js | 4 ++-- lib/zip.js | 5 +++-- lib/zipTree.js | 36 ++++-------------------------------- 3 files changed, 9 insertions(+), 36 deletions(-) diff --git a/lib/layer.js b/lib/layer.js index 569c425d..f9b7f3d2 100644 --- a/lib/layer.js +++ b/lib/layer.js @@ -2,7 +2,7 @@ const BbPromise = require('bluebird'); const fse = require('fs-extra'); const path = require('path'); const JSZip = require('jszip'); -const { writeZip, addTreeNoDeploy } = require('./zipTree'); +const { writeZip, addTree } = require('./zipTree'); const { sha256Path, getRequirementsLayerPath } = require('./shared'); BbPromise.promisifyAll(fse); @@ -42,7 +42,7 @@ function zipRequirements() { const noDeploy = new Set(this.options.noDeploy || []); promises.push( - addTreeNoDeploy(rootZip.folder(runtimepath), src, noDeploy).then(() => + addTree(rootZip.folder(runtimepath), src, noDeploy).then(() => writeZip(rootZip, zipCachePath) ) ); diff --git a/lib/zip.js b/lib/zip.js index 4b652f98..99caa911 100644 --- a/lib/zip.js +++ b/lib/zip.js @@ -112,6 +112,7 @@ function removeVendorHelper() { */ function packRequirements() { if (this.options.zip) { + const noDeploy = new Set(this.options.noDeploy || []); if (this.serverless.service.package.individually) { return BbPromise.resolve(this.targetFuncs) .map((f) => { @@ -137,7 +138,7 @@ function packRequirements() { ); } f.package.patterns.push(`${f.module}/.requirements.zip`); - return addTree(new JSZip(), `.serverless/${f.module}/requirements`) + return addTree(new JSZip(), `.serverless/${f.module}/requirements`, noDeploy) .then((zip) => writeZip(zip, `${f.module}/.requirements.zip`)) .finally(() => packProgress && packProgress.remove()); }); @@ -149,7 +150,7 @@ function packRequirements() { this.serverless.cli.log('Zipping required Python packages...'); } this.serverless.service.package.patterns.push('.requirements.zip'); - return addTree(new JSZip(), '.serverless/requirements') + return addTree(new JSZip(), '.serverless/requirements', noDeploy) .then((zip) => writeZip(zip, path.join(this.servicePath, '.requirements.zip')) ) diff --git a/lib/zipTree.js b/lib/zipTree.js index 307fda37..d1163740 100644 --- a/lib/zipTree.js +++ b/lib/zipTree.js @@ -8,38 +8,10 @@ BbPromise.promisifyAll(fse); * Add a directory recursively to a zip file. Files in src will be added to the top folder of zip. * @param {JSZip} zip a zip object in the folder you want to add files to. * @param {string} src the source folder. + * @param {object} noDeploy the package to be omitted * @return {Promise} a promise offering the original JSZip object. */ -function addTree(zip, src) { - const srcN = path.normalize(src); - - return fse - .readdirAsync(srcN) - .map((name) => { - const srcPath = path.join(srcN, name); - - return fse.statAsync(srcPath).then((stat) => { - if (stat.isDirectory()) { - return addTree(zip.folder(name), srcPath); - } else { - const opts = { date: stat.mtime, unixPermissions: stat.mode }; - return fse - .readFileAsync(srcPath) - .then((data) => zip.file(name, data, opts)); - } - }); - }) - .then(() => zip); // Original zip for chaining. -} - -/** - * Add a directory recursively to a zip file. Files in src will be added to the top folder of zip. - * @param {JSZip} zip a zip object in the folder you want to add files to. - * @param {string} src the source folder. - * @param {Object} noDeploy - * @return {Promise} a promise offering the original JSZip object. - */ -function addTreeNoDeploy(zip, src, noDeploy) { +function addTree(zip, src, noDeploy) { const srcN = path.normalize(src); return fse @@ -50,7 +22,7 @@ function addTreeNoDeploy(zip, src, noDeploy) { return fse.statAsync(srcPath).then((stat) => { if (stat.isDirectory()) { - return addTreeNoDeploy(zip.folder(name), srcPath, noDeploy); + return addTree(zip.folder(name), srcPath, noDeploy); } else { const opts = { date: stat.mtime, unixPermissions: stat.mode }; return fse @@ -111,4 +83,4 @@ function zipFile(zip, zipPath, bufferPromise, fileOpts) { .then(() => zip); } -module.exports = { addTree, writeZip, zipFile , addTreeNoDeploy }; +module.exports = { addTree, writeZip, zipFile }; From d12ca22c5ee5ae855390c2f4bd1f8c47189e0294 Mon Sep 17 00:00:00 2001 From: naoyasugita <sugita6878@gmail.com> Date: Thu, 3 Aug 2023 17:37:07 +0900 Subject: [PATCH 4/7] style: Prettify --- lib/zip.js | 6 +++++- lib/zipTree.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/zip.js b/lib/zip.js index 99caa911..cf03fce1 100644 --- a/lib/zip.js +++ b/lib/zip.js @@ -138,7 +138,11 @@ function packRequirements() { ); } f.package.patterns.push(`${f.module}/.requirements.zip`); - return addTree(new JSZip(), `.serverless/${f.module}/requirements`, noDeploy) + return addTree( + new JSZip(), + `.serverless/${f.module}/requirements`, + noDeploy + ) .then((zip) => writeZip(zip, `${f.module}/.requirements.zip`)) .finally(() => packProgress && packProgress.remove()); }); diff --git a/lib/zipTree.js b/lib/zipTree.js index d1163740..32414c31 100644 --- a/lib/zipTree.js +++ b/lib/zipTree.js @@ -16,7 +16,7 @@ function addTree(zip, src, noDeploy) { return fse .readdirAsync(srcN) - .filter(name => !noDeploy.has(name)) + .filter((name) => !noDeploy.has(name)) .map((name) => { const srcPath = path.join(srcN, name); From d9f483ae28444835684f720e16b02d86cd5044bc Mon Sep 17 00:00:00 2001 From: naoyasugita <sugita6878@gmail.com> Date: Thu, 3 Aug 2023 20:53:32 +0900 Subject: [PATCH 5/7] test: noDeploy option when use layers --- test.js | 11 +++++++++ tests/base/serverless.yml | 3 +++ tests/layer_nodeploy/_slimPatterns.yml | 2 ++ tests/layer_nodeploy/handler.py | 5 +++++ tests/layer_nodeploy/package.json | 14 ++++++++++++ tests/layer_nodeploy/pyproject.toml | 17 ++++++++++++++ tests/layer_nodeploy/serverless.yml | 31 ++++++++++++++++++++++++++ 7 files changed, 83 insertions(+) create mode 100644 tests/layer_nodeploy/_slimPatterns.yml create mode 100644 tests/layer_nodeploy/handler.py create mode 100644 tests/layer_nodeploy/package.json create mode 100644 tests/layer_nodeploy/pyproject.toml create mode 100644 tests/layer_nodeploy/serverless.yml diff --git a/test.js b/test.js index c7232a6e..cb438db1 100644 --- a/test.js +++ b/test.js @@ -1703,3 +1703,14 @@ test('poetry py3.7 only installs optional packages specified in onlyGroups', asy t.true(zipfiles.includes(`boto3${sep}__init__.py`), 'boto3 is packaged'); t.end(); }); + +test("enable layer option doesn't package bottle with noDeploy option", async (t) => { + process.chdir('tests/layer_nodeploy'); + const path = npm(['pack', '../..']); + npm(['i', path]); + sls(['package'], { env: { noDeploy: ['bottle'] } }); + const zipfiles = await listZipFiles('.serverless/sls-py-req-test.zip'); + t.true(zipfiles.includes(`flask${sep}__init__.py`), 'flask is packaged'); + t.false(zipfiles.includes(`bottle.py`), 'bottle is NOT packaged'); + t.end(); +}); diff --git a/tests/base/serverless.yml b/tests/base/serverless.yml index ef48e901..40c333fe 100644 --- a/tests/base/serverless.yml +++ b/tests/base/serverless.yml @@ -21,6 +21,9 @@ custom: useStaticCache: ${env:useStaticCache, self:custom.defaults.useStaticCache} useDownloadCache: ${env:useDownloadCache, self:custom.defaults.useDownloadCache} cacheLocation: ${env:cacheLocation, ''} + layer: true + noDeploy: + - 'bottle' defaults: slim: false slimPatterns: false diff --git a/tests/layer_nodeploy/_slimPatterns.yml b/tests/layer_nodeploy/_slimPatterns.yml new file mode 100644 index 00000000..443af9a0 --- /dev/null +++ b/tests/layer_nodeploy/_slimPatterns.yml @@ -0,0 +1,2 @@ +slimPatterns: + - '**/__main__.py' diff --git a/tests/layer_nodeploy/handler.py b/tests/layer_nodeploy/handler.py new file mode 100644 index 00000000..5e2e67ff --- /dev/null +++ b/tests/layer_nodeploy/handler.py @@ -0,0 +1,5 @@ +import requests + + +def hello(event, context): + return requests.get('https://httpbin.org/get').json() diff --git a/tests/layer_nodeploy/package.json b/tests/layer_nodeploy/package.json new file mode 100644 index 00000000..38630491 --- /dev/null +++ b/tests/layer_nodeploy/package.json @@ -0,0 +1,14 @@ +{ + "name": "example", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "serverless-python-requirements": "file:serverless-python-requirements-5.3.1.tgz" + } +} diff --git a/tests/layer_nodeploy/pyproject.toml b/tests/layer_nodeploy/pyproject.toml new file mode 100644 index 00000000..b813968a --- /dev/null +++ b/tests/layer_nodeploy/pyproject.toml @@ -0,0 +1,17 @@ +[tool.poetry] +name = "poetry" +version = "0.1.0" +description = "" +authors = ["Your Name <you@example.com>"] + +[tool.poetry.dependencies] +python = "^3.6" +Flask = "^1.0" +bottle = {git = "https://git@github.com/bottlepy/bottle.git", tag = "0.12.16"} +boto3 = "^1.9" + +[tool.poetry.dev-dependencies] + +[build-system] +requires = ["poetry>=0.12"] +build-backend = "poetry.masonry.api" diff --git a/tests/layer_nodeploy/serverless.yml b/tests/layer_nodeploy/serverless.yml new file mode 100644 index 00000000..2d032acd --- /dev/null +++ b/tests/layer_nodeploy/serverless.yml @@ -0,0 +1,31 @@ +service: sls-py-req-test + +provider: + name: aws + runtime: python3.7 + +plugins: + - serverless-python-requirements +custom: + pythonRequirements: + zip: ${env:zip, self:custom.defaults.zip} + slim: ${env:slim, self:custom.defaults.slim} + slimPatterns: ${file(./slimPatterns.yml):slimPatterns, self:custom.defaults.slimPatterns} + slimPatternsAppendDefaults: ${env:slimPatternsAppendDefaults, self:custom.defaults.slimPatternsAppendDefaults} + dockerizePip: ${env:dockerizePip, self:custom.defaults.dockerizePip} + requirePoetryLockFile: ${env:requirePoetryLockFile, false} + defaults: + zip: false + slimPatterns: false + slimPatternsAppendDefaults: true + slim: false + dockerizePip: false + +package: + patterns: + - '!**/*' + - 'handler.py' + +functions: + hello: + handler: handler.hello From 2f9547d70b9beab99fc7e472f530c996d82a732b Mon Sep 17 00:00:00 2001 From: naoyasugita <sugita6878@gmail.com> Date: Thu, 3 Aug 2023 20:57:23 +0900 Subject: [PATCH 6/7] fix: pythonRequirements option --- tests/base/serverless.yml | 3 --- tests/layer_nodeploy/serverless.yml | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/base/serverless.yml b/tests/base/serverless.yml index 40c333fe..ef48e901 100644 --- a/tests/base/serverless.yml +++ b/tests/base/serverless.yml @@ -21,9 +21,6 @@ custom: useStaticCache: ${env:useStaticCache, self:custom.defaults.useStaticCache} useDownloadCache: ${env:useDownloadCache, self:custom.defaults.useDownloadCache} cacheLocation: ${env:cacheLocation, ''} - layer: true - noDeploy: - - 'bottle' defaults: slim: false slimPatterns: false diff --git a/tests/layer_nodeploy/serverless.yml b/tests/layer_nodeploy/serverless.yml index 2d032acd..a2c3648f 100644 --- a/tests/layer_nodeploy/serverless.yml +++ b/tests/layer_nodeploy/serverless.yml @@ -14,6 +14,9 @@ custom: slimPatternsAppendDefaults: ${env:slimPatternsAppendDefaults, self:custom.defaults.slimPatternsAppendDefaults} dockerizePip: ${env:dockerizePip, self:custom.defaults.dockerizePip} requirePoetryLockFile: ${env:requirePoetryLockFile, false} + layer: true + noDeploy: + - 'bottle' defaults: zip: false slimPatterns: false From 880db03ae3b79df86c38e93b61e8c8e045c396e4 Mon Sep 17 00:00:00 2001 From: naoyasugita <sugita6878@gmail.com> Date: Thu, 3 Aug 2023 21:00:32 +0900 Subject: [PATCH 7/7] fix: tests/layer_nodeploy package version --- tests/layer_nodeploy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/layer_nodeploy/package.json b/tests/layer_nodeploy/package.json index 38630491..781a4259 100644 --- a/tests/layer_nodeploy/package.json +++ b/tests/layer_nodeploy/package.json @@ -9,6 +9,6 @@ "author": "", "license": "ISC", "dependencies": { - "serverless-python-requirements": "file:serverless-python-requirements-5.3.1.tgz" + "serverless-python-requirements": "file:serverless-python-requirements-6.0.0.tgz" } }