generated from amazon-archives/__template_Apache-2.0
-
Notifications
You must be signed in to change notification settings - Fork 80
Expand file tree
/
Copy pathsource-builder.ts
More file actions
150 lines (137 loc) · 5.6 KB
/
source-builder.ts
File metadata and controls
150 lines (137 loc) · 5.6 KB
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import * as cxapi from '@aws-cdk/cx-api';
import * as fs from 'fs-extra';
import type { AssemblySourceProps, ICloudAssemblySource } from '../';
import { ContextAwareCloudAssembly, ContextAwareCloudAssemblyProps } from './context-aware-source';
import { execInChildProcess } from './exec';
import { assemblyFromDirectory, changeDir, determineOutputDirectory, guessExecutable, prepareDefaultEnvironment, withContext, withEnv } from './prepare-source';
import { ToolkitServices } from '../../../toolkit/private';
import { Context, ILock, RWLock, Settings } from '../../aws-cdk';
import { ToolkitError } from '../../errors';
import { CODES, debug, error, info } from '../../io/private';
import { AssemblyBuilder } from '../source-builder';
export abstract class CloudAssemblySourceBuilder {
/**
* Helper to provide the CloudAssemblySourceBuilder with required toolkit services
* @deprecated this should move to the toolkit really.
*/
protected abstract sourceBuilderServices(): Promise<ToolkitServices>;
/**
* Create a Cloud Assembly from a Cloud Assembly builder function.
* @param builder the builder function
* @param props additional configuration properties
* @returns the CloudAssembly source
*/
public async fromAssemblyBuilder(
builder: AssemblyBuilder,
props: AssemblySourceProps = {},
): Promise<ICloudAssemblySource> {
const services = await this.sourceBuilderServices();
const context = new Context({ bag: new Settings(props.context ?? {}) });
const contextAssemblyProps: ContextAwareCloudAssemblyProps = {
services,
context,
lookups: props.lookups,
};
return new ContextAwareCloudAssembly(
{
produce: async () => {
const outdir = determineOutputDirectory(props.outdir);
const env = await prepareDefaultEnvironment(services, { outdir });
const assembly = await changeDir(async () =>
withContext(context.all, env, props.synthOptions ?? {}, async (envWithContext, ctx) =>
withEnv(envWithContext, () => builder({
outdir,
context: ctx,
})),
), props.workingDirectory);
if (cxapi.CloudAssembly.isCloudAssembly(assembly)) {
return assembly;
}
return new cxapi.CloudAssembly(assembly.directory);
},
},
contextAssemblyProps,
);
}
/**
* Creates a Cloud Assembly from an existing assembly directory.
* @param directory the directory of a already produced Cloud Assembly.
* @returns the CloudAssembly source
*/
public async fromAssemblyDirectory(directory: string): Promise<ICloudAssemblySource> {
const services: ToolkitServices = await this.sourceBuilderServices();
const contextAssemblyProps: ContextAwareCloudAssemblyProps = {
services,
context: new Context(), // @todo there is probably a difference between contextaware and contextlookup sources
lookups: false,
};
return new ContextAwareCloudAssembly(
{
produce: async () => {
// @todo build
await services.ioHost.notify(debug('--app points to a cloud assembly, so we bypass synth'));
return assemblyFromDirectory(directory, services.ioHost);
},
},
contextAssemblyProps,
);
}
/**
* Use a directory containing an AWS CDK app as source.
* @param props additional configuration properties
* @returns the CloudAssembly source
*/
public async fromCdkApp(app: string, props: AssemblySourceProps = {}): Promise<ICloudAssemblySource> {
const services: ToolkitServices = await this.sourceBuilderServices();
// @todo this definitely needs to read files from the CWD
const context = new Context({ bag: new Settings(props.context ?? {}) });
const contextAssemblyProps: ContextAwareCloudAssemblyProps = {
services,
context,
lookups: props.lookups,
};
return new ContextAwareCloudAssembly(
{
produce: async () => {
let lock: ILock | undefined = undefined;
try {
// @todo build
// const build = this.props.configuration.settings.get(['build']);
// if (build) {
// await execInChildProcess(build, { cwd: props.workingDirectory });
// }
const commandLine = await guessExecutable(app);
const outdir = props.outdir ?? 'cdk.out';
try {
fs.mkdirpSync(outdir);
} catch (e: any) {
throw new ToolkitError(`Could not create output directory at '${outdir}' (${e.message}).`);
}
lock = await new RWLock(outdir).acquireWrite();
const env = await prepareDefaultEnvironment(services, { outdir });
return await withContext(context.all, env, props.synthOptions, async (envWithContext, _ctx) => {
await execInChildProcess(commandLine.join(' '), {
eventPublisher: async (type, line) => {
switch (type) {
case 'data_stdout':
await services.ioHost.notify(info(line, CODES.CDK_ASSEMBLY_I1001));
break;
case 'data_stderr':
await services.ioHost.notify(error(line, CODES.CDK_ASSEMBLY_E1002));
break;
}
},
extraEnv: envWithContext,
cwd: props.workingDirectory,
});
return assemblyFromDirectory(outdir, services.ioHost);
});
} finally {
await lock?.release();
}
},
},
contextAssemblyProps,
);
}
}