diff --git a/packages/@aws-cdk/aws-lambda-python/lib/bundling.ts b/packages/@aws-cdk/aws-lambda-python/lib/bundling.ts index 34dd54e3eee98..ddd3e167204c9 100644 --- a/packages/@aws-cdk/aws-lambda-python/lib/bundling.ts +++ b/packages/@aws-cdk/aws-lambda-python/lib/bundling.ts @@ -87,7 +87,7 @@ export class Bundling implements CdkBundlingOptions { if (packaging.dependenciesFile) { bundlingCommands.push(`python -m pip install -r ${DependenciesFile.PIP} -t ${options.outputDir}`); } - bundlingCommands.push(`cp -R ${options.inputDir}/ ${options.outputDir}`); + bundlingCommands.push(`cp -rT ${options.inputDir}/ ${options.outputDir}`); return bundlingCommands; } } diff --git a/packages/@aws-cdk/aws-lambda-python/test/bundling.test.ts b/packages/@aws-cdk/aws-lambda-python/test/bundling.test.ts index e5f91b2ea09b8..4af556b3b9a62 100644 --- a/packages/@aws-cdk/aws-lambda-python/test/bundling.test.ts +++ b/packages/@aws-cdk/aws-lambda-python/test/bundling.test.ts @@ -1,3 +1,4 @@ +import * as fs from 'fs'; import * as path from 'path'; import { Architecture, Code, Runtime } from '@aws-cdk/aws-lambda'; import { DockerImage } from '@aws-cdk/core'; @@ -25,7 +26,7 @@ beforeEach(() => { test('Bundling a function without dependencies', () => { const entry = path.join(__dirname, 'lambda-handler-nodeps'); - Bundling.bundle({ + const assetCode = Bundling.bundle({ entry: entry, runtime: Runtime.PYTHON_3_7, architecture: Architecture.X86_64, @@ -36,7 +37,7 @@ test('Bundling a function without dependencies', () => { bundling: expect.objectContaining({ command: [ 'bash', '-c', - 'cp -R /asset-input/ /asset-output', + 'cp -rT /asset-input/ /asset-output', ], }), })); @@ -47,11 +48,14 @@ test('Bundling a function without dependencies', () => { }), platform: 'linux/amd64', })); + + const files = fs.readdirSync(assetCode.path); + expect(files).toContain('index.py'); }); test('Bundling a function with requirements.txt', () => { const entry = path.join(__dirname, 'lambda-handler'); - Bundling.bundle({ + const assetCode = Bundling.bundle({ entry: entry, runtime: Runtime.PYTHON_3_7, architecture: Architecture.X86_64, @@ -62,10 +66,14 @@ test('Bundling a function with requirements.txt', () => { bundling: expect.objectContaining({ command: [ 'bash', '-c', - 'python -m pip install -r requirements.txt -t /asset-output && cp -R /asset-input/ /asset-output', + 'python -m pip install -r requirements.txt -t /asset-output && cp -rT /asset-input/ /asset-output', ], }), })); + + const files = fs.readdirSync(assetCode.path); + expect(files).toContain('index.py'); + expect(files).toContain('requirements.txt'); }); test('Bundling Python 2.7 with requirements.txt installed', () => { @@ -81,7 +89,7 @@ test('Bundling Python 2.7 with requirements.txt installed', () => { bundling: expect.objectContaining({ command: [ 'bash', '-c', - 'python -m pip install -r requirements.txt -t /asset-output && cp -R /asset-input/ /asset-output', + 'python -m pip install -r requirements.txt -t /asset-output && cp -rT /asset-input/ /asset-output', ], }), })); @@ -101,7 +109,7 @@ test('Bundling a layer with dependencies', () => { bundling: expect.objectContaining({ command: [ 'bash', '-c', - 'python -m pip install -r requirements.txt -t /asset-output/python && cp -R /asset-input/ /asset-output/python', + 'python -m pip install -r requirements.txt -t /asset-output/python && cp -rT /asset-input/ /asset-output/python', ], }), })); @@ -121,7 +129,7 @@ test('Bundling a python code layer', () => { bundling: expect.objectContaining({ command: [ 'bash', '-c', - 'cp -R /asset-input/ /asset-output/python', + 'cp -rT /asset-input/ /asset-output/python', ], }), })); @@ -130,7 +138,7 @@ test('Bundling a python code layer', () => { test('Bundling a function with pipenv dependencies', () => { const entry = path.join(__dirname, 'lambda-handler-pipenv'); - Bundling.bundle({ + const assetCode = Bundling.bundle({ entry: path.join(entry, '.'), runtime: Runtime.PYTHON_3_9, architecture: Architecture.X86_64, @@ -141,16 +149,23 @@ test('Bundling a function with pipenv dependencies', () => { bundling: expect.objectContaining({ command: [ 'bash', '-c', - 'PIPENV_VENV_IN_PROJECT=1 pipenv lock -r > requirements.txt && rm -rf .venv && python -m pip install -r requirements.txt -t /asset-output/python && cp -R /asset-input/ /asset-output/python', + 'PIPENV_VENV_IN_PROJECT=1 pipenv lock -r > requirements.txt && rm -rf .venv && python -m pip install -r requirements.txt -t /asset-output/python && cp -rT /asset-input/ /asset-output/python', ], }), })); + + const files = fs.readdirSync(assetCode.path); + expect(files).toContain('index.py'); + expect(files).toContain('Pipfile'); + expect(files).toContain('Pipfile.lock'); + // Contains hidden files. + expect(files).toContain('.gitignore'); }); test('Bundling a function with poetry dependencies', () => { const entry = path.join(__dirname, 'lambda-handler-poetry'); - Bundling.bundle({ + const assetCode = Bundling.bundle({ entry: path.join(entry, '.'), runtime: Runtime.PYTHON_3_9, architecture: Architecture.X86_64, @@ -161,10 +176,17 @@ test('Bundling a function with poetry dependencies', () => { bundling: expect.objectContaining({ command: [ 'bash', '-c', - 'poetry export --with-credentials --format requirements.txt --output requirements.txt && python -m pip install -r requirements.txt -t /asset-output/python && cp -R /asset-input/ /asset-output/python', + 'poetry export --with-credentials --format requirements.txt --output requirements.txt && python -m pip install -r requirements.txt -t /asset-output/python && cp -rT /asset-input/ /asset-output/python', ], }), })); + + const files = fs.readdirSync(assetCode.path); + expect(files).toContain('index.py'); + expect(files).toContain('pyproject.toml'); + expect(files).toContain('poetry.lock'); + // Contains hidden files. + expect(files).toContain('.gitignore'); }); test('Bundling a function with custom bundling image', () => { @@ -184,7 +206,7 @@ test('Bundling a function with custom bundling image', () => { image, command: [ 'bash', '-c', - 'python -m pip install -r requirements.txt -t /asset-output/python && cp -R /asset-input/ /asset-output/python', + 'python -m pip install -r requirements.txt -t /asset-output/python && cp -rT /asset-input/ /asset-output/python', ], }), }));