From 6b8715786e273ef2fcc947597ae87c1019584a9b Mon Sep 17 00:00:00 2001 From: Mark Nielsen Date: Tue, 20 Jun 2023 14:46:51 -0700 Subject: [PATCH] feat(lambda-python): add local bundling option --- .../aws-lambda-python-alpha/README.md | 30 +++++++++++++++++++ .../aws-lambda-python-alpha/lib/bundling.ts | 4 ++- .../aws-lambda-python-alpha/lib/types.ts | 13 +++++++- .../test/bundling.test.ts | 22 ++++++++++++++ 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-lambda-python-alpha/README.md b/packages/@aws-cdk/aws-lambda-python-alpha/README.md index e02462e6e9ea3..e248e5e79cdf4 100644 --- a/packages/@aws-cdk/aws-lambda-python-alpha/README.md +++ b/packages/@aws-cdk/aws-lambda-python-alpha/README.md @@ -233,6 +233,36 @@ new python.PythonFunction(this, 'function', { }); ``` +## Local bundling + +Use `local` to specify a local bundling provider. The provider implements a +method `tryBundle()` which should return `true` if local bundling was performed. +If `false` is returned, Docker bundling will be done: + + ```ts +import * as cdk from 'aws-cdk-lib'; + +class MyBundle implements cdk.ILocalBundling { + public tryBundle(outputDir: string, options: cdk.BundlingOptions) { + const canRunLocally = true // replace with actual logic + if (canRunLocally) { + // perform local bundling here + return true; + } + return false; + } +} + +const entry = '/path/to/function'; +new python.PythonFunction(this, 'function', { + entry, + runtime: Runtime.PYTHON_3_8, + bundling: { + local: new MyBundle() + }, +}); +``` + ## Command hooks It is possible to run additional commands by specifying the `commandHooks` prop: diff --git a/packages/@aws-cdk/aws-lambda-python-alpha/lib/bundling.ts b/packages/@aws-cdk/aws-lambda-python-alpha/lib/bundling.ts index 2590299ca66c4..966fa1c85b57d 100644 --- a/packages/@aws-cdk/aws-lambda-python-alpha/lib/bundling.ts +++ b/packages/@aws-cdk/aws-lambda-python-alpha/lib/bundling.ts @@ -1,6 +1,6 @@ import * as path from 'path'; import { Architecture, AssetCode, Code, Runtime } from 'aws-cdk-lib/aws-lambda'; -import { AssetStaging, BundlingFileAccess, BundlingOptions as CdkBundlingOptions, DockerImage, DockerVolume } from 'aws-cdk-lib/core'; +import { AssetStaging, BundlingFileAccess, BundlingOptions as CdkBundlingOptions, DockerImage, DockerVolume, ILocalBundling } from 'aws-cdk-lib/core'; import { Packaging, DependenciesFile } from './packaging'; import { BundlingOptions, ICommandHooks } from './types'; @@ -73,6 +73,7 @@ export class Bundling implements CdkBundlingOptions { public readonly securityOpt?: string; public readonly network?: string; public readonly bundlingFileAccess?: BundlingFileAccess; + public readonly local?: ILocalBundling; constructor(props: BundlingProps) { const { @@ -114,6 +115,7 @@ export class Bundling implements CdkBundlingOptions { this.securityOpt = props.securityOpt; this.network = props.network; this.bundlingFileAccess = props.bundlingFileAccess; + this.local = props.local; } private createBundlingCommand(options: BundlingCommandOptions): string[] { diff --git a/packages/@aws-cdk/aws-lambda-python-alpha/lib/types.ts b/packages/@aws-cdk/aws-lambda-python-alpha/lib/types.ts index 3c26bd54ab72c..bf339544f3add 100644 --- a/packages/@aws-cdk/aws-lambda-python-alpha/lib/types.ts +++ b/packages/@aws-cdk/aws-lambda-python-alpha/lib/types.ts @@ -1,4 +1,4 @@ -import { AssetHashType, BundlingFileAccess, DockerImage, DockerRunOptions } from 'aws-cdk-lib/core'; +import { AssetHashType, BundlingFileAccess, DockerImage, DockerRunOptions, ILocalBundling } from 'aws-cdk-lib/core'; /** * Options for bundling @@ -98,6 +98,17 @@ export interface BundlingOptions extends DockerRunOptions { * @default - BundlingFileAccess.BIND_MOUNT */ readonly bundlingFileAccess?: BundlingFileAccess; + + /** + * Local bundling provider. + * + * The provider implements a method `tryBundle()` which should return `true` + * if local bundling was performed. If `false` is returned, docker bundling + * will be done. + * + * @default - bundling will only be performed in a Docker container + */ + readonly local?: ILocalBundling; } /** diff --git a/packages/@aws-cdk/aws-lambda-python-alpha/test/bundling.test.ts b/packages/@aws-cdk/aws-lambda-python-alpha/test/bundling.test.ts index 81b3974433185..c52bdfe7a8c42 100644 --- a/packages/@aws-cdk/aws-lambda-python-alpha/test/bundling.test.ts +++ b/packages/@aws-cdk/aws-lambda-python-alpha/test/bundling.test.ts @@ -554,3 +554,25 @@ test('with command hooks', () => { }), })); }); + +test('Local bundling is used', () => { + const entry = path.join(__dirname, 'lambda-handler'); + + const local = { + tryBundle() { + return true; + }, + }; + + Bundling.bundle({ + entry: entry, + runtime: Runtime.PYTHON_3_7, + local, + }); + + expect(Code.fromAsset).toHaveBeenCalledWith(entry, expect.objectContaining({ + bundling: expect.objectContaining({ + local, + }), + })); +});