-
Notifications
You must be signed in to change notification settings - Fork 3.9k
/
bundling.ts
96 lines (80 loc) · 2.36 KB
/
bundling.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import * as fs from 'fs';
import * as path from 'path';
import * as lambda from '@aws-cdk/aws-lambda';
import * as cdk from '@aws-cdk/core';
/**
* Dependency files to exclude from the asset hash.
*/
export const DEPENDENCY_EXCLUDES = ['*.pyc'];
/**
* The location in the image that the bundler image caches dependencies.
*/
export const BUNDLER_DEPENDENCIES_CACHE = '/var/dependencies';
/**
* Options for bundling
*/
export interface BundlingOptions {
/**
* Entry path
*/
readonly entry: string;
/**
* The runtime of the lambda function
*/
readonly runtime: lambda.Runtime;
/**
* Output path suffix ('python' for a layer, '.' otherwise)
*/
readonly outputPathSuffix: string;
}
/**
* Produce bundled Lambda asset code
*/
export function bundle(options: BundlingOptions): lambda.AssetCode {
const { entry, runtime, outputPathSuffix } = options;
const hasDeps = hasDependencies(entry);
const depsCommand = chain([
hasDeps ? `rsync -r ${BUNDLER_DEPENDENCIES_CACHE}/. ${cdk.AssetStaging.BUNDLING_OUTPUT_DIR}/${outputPathSuffix}` : '',
`rsync -r . ${cdk.AssetStaging.BUNDLING_OUTPUT_DIR}/${outputPathSuffix}`,
]);
// Determine which dockerfile to use. When dependencies are present, we use a
// Dockerfile that can create a cacheable layer. We can't use this Dockerfile
// if there aren't dependencies or the Dockerfile will complain about missing
// sources.
const dockerfile = hasDeps
? 'Dockerfile.dependencies'
: 'Dockerfile';
const image = cdk.BundlingDockerImage.fromAsset(entry, {
buildArgs: {
IMAGE: runtime.bundlingDockerImage.image,
},
file: path.join(__dirname, dockerfile),
});
return lambda.Code.fromAsset(entry, {
assetHashType: cdk.AssetHashType.BUNDLE,
exclude: DEPENDENCY_EXCLUDES,
bundling: {
image,
command: ['bash', '-c', depsCommand],
},
});
}
/**
* Checks to see if the `entry` directory contains a type of dependency that
* we know how to install.
*/
export function hasDependencies(entry: string): boolean {
if (fs.existsSync(path.join(entry, 'Pipfile'))) {
return true;
}
if (fs.existsSync(path.join(entry, 'poetry.lock'))) {
return true;
}
if (fs.existsSync(path.join(entry, 'requirements.txt'))) {
return true;
}
return false;
}
function chain(commands: string[]): string {
return commands.filter(c => !!c).join(' && ');
}