diff --git a/README.md b/README.md index 10e73b8..d2f09f9 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,9 @@ custom: - ./requirements.txt globalIncludes: - ./common_files + globalExcludes: + - '**/*.egg-info' + - '**/__pycache__' cleanup: true functions: @@ -130,6 +133,7 @@ The plugin configurations are simple: | requirementsFile | The name of the requirements file used for function-level requirements. All function-level requirements files must use the name specified here. | Yes. Defaults to `requirements.txt` | | globalRequirements | A list of paths to files containing service-level pip requirements. | Yes | | globalIncludes | A list of paths to folders containing service-level code files (i.e. code common to all functions). Only the folders contents will be packaged, not the folder itself. Paths to files are not currently supported. | Yes | +| globalExcludes | A list of paths to exclude from the package. Use glob syntax to specify files or directories to exclude, e.g. `'**/*.egg-info'` | Yes | | useDocker | Boolean indicating whether to package pip dependencies using Docker. Set this to true if your project uses platform-specific compiled libraries like numpy. Requires a [Docker installation](https://www.docker.com/get-docker). | Yes. Defaults to `false` | | dockerImage | The Docker image to use to compile functions if `useDocker` is set to `true`. Must be specified as `repository:tag`. If the image doesn't exist on the system, it will be downloaded. The initial download may take some time. | Yes. Defaults to `lambci/lambda:build-${provider.runtime}` | | containerName | The desired name for the Docker container. | Yes. Defaults to `serverless-package-python-functions` | @@ -138,6 +142,7 @@ The plugin configurations are simple: At the function level, you: - Specify `name` to give your function a name. The plugin uses the function's name as the name of the zip artifact - Use `include` to specify what function-level files you want to include in your artifact. Simply specifying the path to the function's folder will include every file in the folder in the function's zip artifact +- Use `exclude` to specify what function-level files or directories you want to exclude in your artifact. Use glob syntax to specify target content. - Use `artifact` to tell Serverless where to find the zip artifact. The plugin creates the zip artifact for the function at `buildDir`/`name`.zip, so using `${self:custom.pkgPyFuncs.buildDir}/[function-name-here].zip` is advised. At the package level, you may need to: diff --git a/index.js b/index.js index bb8f87c..db3624f 100644 --- a/index.js +++ b/index.js @@ -3,6 +3,7 @@ const BbPromise = require('bluebird'); const _ = require('lodash'); const Fse = require('fs-extra'); +const minimatch = require('minimatch'); const Path = require('path'); const ChildProcess = require('child_process'); const zipper = require('zip-local'); @@ -28,6 +29,7 @@ class PkgPyFuncs { config.buildDir ? this.buildDir = config.buildDir : this.error("No buildDir configuration specified") this.globalRequirements = config.globalRequirements || [] this.globalIncludes = config.globalIncludes || [] + this.globalExcludes = config.globalExcludes || [] config.cleanup === undefined ? this.cleanup = true : this.cleanup = config.cleanup this.useDocker = config.useDocker || false this.dockerImage = config.dockerImage || `lambci/lambda:build-${this.serverless.service.provider.runtime}` @@ -35,6 +37,12 @@ class PkgPyFuncs { this.mountSSH = config.mountSSH || false this.abortOnPackagingErrors = config.abortOnPackagingErrors || false this.dockerServicePath = '/var/task' + this.defaultExcludes = [ + "**/.serverless", + "**/node_modules", + "**/package.json", + "**/package-lock.json" + ] } autoconfigArtifacts() { @@ -70,6 +78,7 @@ class PkgPyFuncs { return { name: target.name, includes: target.package.include, + excludes: target.package.exclude, artifact: target.package.artifact } }) @@ -207,7 +216,20 @@ class PkgPyFuncs { if (this.globalIncludes){ includes = _.concat(includes, this.globalIncludes) } - _.forEach(includes, (item) => { Fse.copySync(item, buildPath) } ) + let excludes = target.excludes || [] + if (this.globalExcludes){ + excludes = _.concat(excludes, this.globalExcludes) + } + + let filter = (src, dest) => { + for(var i = 0; i < excludes.length; i++) { + if (minimatch(src, excludes[i])){ + return false + } + } + return true + } + _.forEach(includes, (item) => { Fse.copySync(item, buildPath, filter) } ) // Install requirements let requirements = [requirementsPath] diff --git a/package-lock.json b/package-lock.json index f4bb204..d1a06f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,11 +9,30 @@ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, "bluebird": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, "fs-extra": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", @@ -50,6 +69,14 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, "pako": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.5.tgz", diff --git a/package.json b/package.json index 6b2d8c7..45efa89 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "bluebird": "^3.5.0", "fs-extra": "^3.0.0", "lodash": "^4.17.11", + "minimatch": "^3.0.4", "upath": "^1.1.0", "readline-sync": "^1.4.10", "zip-local": "^0.3.4"