From b81502e710bb72ab3291332e7c4720183554d10f Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 4 Jun 2019 02:13:36 +0300 Subject: [PATCH 01/17] refactor(core): Misc cleanups to App-related APIs Ensure documentation coverage and clean up of the various APIs. Fixes #1891 BREAKING CHANGE: * **core:** `StackProps.autoDeploy` has been removed and replaced by `StackProps.hide` (with negated logic). * **core:** `ISynthesizable.synthesize` now accepts an `ISynthesisSession` which contains the `CloudAssemblyBuilder` object. * **cx-api:** Multiple changes to the cloud assembly APIs to reduce surface area and clean up. --- packages/@aws-cdk/assert/lib/inspector.ts | 5 +- packages/@aws-cdk/assets/lib/staging.ts | 9 +- packages/@aws-cdk/assets/test/test.asset.ts | 5 +- packages/@aws-cdk/cdk/lib/app.ts | 48 ++++-- packages/@aws-cdk/cdk/lib/cfn-element.ts | 7 +- packages/@aws-cdk/cdk/lib/stack.ts | 41 ++--- packages/@aws-cdk/cdk/lib/synthesis.ts | 15 +- packages/@aws-cdk/cdk/test/test.app.ts | 6 +- packages/@aws-cdk/cdk/test/test.context.ts | 2 +- packages/@aws-cdk/cdk/test/test.synthesis.ts | 23 ++- .../@aws-cdk/cx-api/lib/cloud-artifact.ts | 147 ++++++++++++++---- .../@aws-cdk/cx-api/lib/cloud-assembly.ts | 100 +++++++++--- .../cx-api/lib/cloudformation-artifact.ts | 71 ++++----- packages/@aws-cdk/cx-api/lib/metadata.ts | 12 ++ .../cx-api/test/cloud-assembly.test.ts | 22 +-- packages/aws-cdk/bin/cdk.ts | 2 +- packages/aws-cdk/lib/api/cxapp/stacks.ts | 30 ++-- .../cloudformation/stack-activity-monitor.ts | 11 +- packages/aws-cdk/lib/diff.ts | 12 +- packages/aws-cdk/test/api/test.stacks.ts | 10 +- packages/aws-cdk/test/util.ts | 4 +- 21 files changed, 388 insertions(+), 194 deletions(-) diff --git a/packages/@aws-cdk/assert/lib/inspector.ts b/packages/@aws-cdk/assert/lib/inspector.ts index ee446ab95b28a..e450c2e20ee39 100644 --- a/packages/@aws-cdk/assert/lib/inspector.ts +++ b/packages/@aws-cdk/assert/lib/inspector.ts @@ -54,9 +54,10 @@ export class StackPathInspector extends Inspector { // The names of paths in metadata in tests are very ill-defined. Try with the full path first, // then try with the stack name preprended for backwards compat with most tests that happen to give // their stack an ID that's the same as the stack name. - const md = this.stack.metadata[this.path] || this.stack.metadata[`/${this.stack.name}${this.path}`]; + const metadata = this.stack.manifest.metadata || {}; + const md = metadata[this.path] || metadata[`/${this.stack.name}${this.path}`]; if (md === undefined) { return undefined; } - const resourceMd = md.find(entry => entry.type === 'aws:cdk:logicalId'); + const resourceMd = md.find(entry => entry.type === api.LOGICAL_ID_METADATA_KEY); if (resourceMd === undefined) { return undefined; } const logicalId = resourceMd.data; return this.stack.template.Resources[logicalId]; diff --git a/packages/@aws-cdk/assets/lib/staging.ts b/packages/@aws-cdk/assets/lib/staging.ts index 173fe73374fa7..f630c1e0772b6 100644 --- a/packages/@aws-cdk/assets/lib/staging.ts +++ b/packages/@aws-cdk/assets/lib/staging.ts @@ -1,4 +1,4 @@ -import { Construct } from '@aws-cdk/cdk'; +import { Construct, ISynthesisSession, ISynthesizable } from '@aws-cdk/cdk'; import cxapi = require('@aws-cdk/cx-api'); import fs = require('fs'); import path = require('path'); @@ -26,7 +26,7 @@ export interface StagingProps extends CopyOptions { * The file/directory are staged based on their content hash (fingerprint). This * means that only if content was changed, copy will happen. */ -export class Staging extends Construct { +export class Staging extends Construct implements ISynthesizable { /** * The path to the asset (stringinfied token). @@ -66,12 +66,13 @@ export class Staging extends Construct { } } - protected synthesize(session: cxapi.CloudAssemblyBuilder) { + public synthesize(session: ISynthesisSession) { + const assembly = session.assembly; if (!this.relativePath) { return; } - const targetPath = path.join(session.outdir, this.relativePath); + const targetPath = path.join(assembly.outdir, this.relativePath); // asset already staged if (fs.existsSync(targetPath)) { diff --git a/packages/@aws-cdk/assets/test/test.asset.ts b/packages/@aws-cdk/assets/test/test.asset.ts index 53a3a42020d5c..d752c56b5a735 100644 --- a/packages/@aws-cdk/assets/test/test.asset.ts +++ b/packages/@aws-cdk/assets/test/test.asset.ts @@ -58,7 +58,8 @@ export = { }); const synth = app.run().getStack(stack.name); - test.deepEqual(synth.metadata['/my-stack/MyAsset'][0].data, { + const meta = synth.manifest.metadata || {}; + test.deepEqual(meta['/my-stack/MyAsset'][0].data, { path: 'asset.6b84b87243a4a01c592d78e1fd3855c4bfef39328cd0a450cc97e81717fea2a2', id: "mystackMyAssetD6B1B593", packaging: "zip", @@ -343,7 +344,7 @@ export = { const session = app.run(); const artifact = session.getStack(stack.name); - const md = Object.values(artifact.metadata)[0][0].data; + const md = Object.values(artifact.manifest.metadata || {})[0][0].data; test.deepEqual(md.path, 'asset.6b84b87243a4a01c592d78e1fd3855c4bfef39328cd0a450cc97e81717fea2a2'); test.done(); } diff --git a/packages/@aws-cdk/cdk/lib/app.ts b/packages/@aws-cdk/cdk/lib/app.ts index 79d021493f310..42a001d585ce1 100644 --- a/packages/@aws-cdk/cdk/lib/app.ts +++ b/packages/@aws-cdk/cdk/lib/app.ts @@ -7,7 +7,7 @@ import { Synthesizer } from './synthesis'; const APP_SYMBOL = Symbol.for('@aws-cdk/cdk.App'); /** - * Custom construction properties for a CDK program + * Initialization props for apps. */ export interface AppProps { /** @@ -15,7 +15,7 @@ export interface AppProps { * * If you set this, you don't have to call `run()` anymore. * - * @default true if running via CDK toolkit (CDK_OUTDIR is set), false otherwise + * @default true if running via CDK toolkit (`CDK_OUTDIR` is set), false otherwise */ readonly autoRun?: boolean; @@ -29,29 +29,48 @@ export interface AppProps { /** * Include stack traces in construct metadata entries. - * @default true stack traces are included + * @default true stack traces are included unless `aws:cdk:disable-stack-trace` is set in the context. */ readonly stackTraces?: boolean; /** * Include runtime versioning information in cloud assembly manifest - * @default true runtime info is included + * @default true runtime info is included unless `aws:cdk:disable-runtime-info` is set in the context. */ readonly runtimeInfo?: boolean; /** - * Additional context values for the application + * Additional context values for the application. * - * @default No additional context + * Context can be read from any construct using `node.getContext(key)`. + * + * @default - no additional context */ readonly context?: { [key: string]: string }; } /** - * Represents a CDK program. + * A construct which represents an entire CDK app. This construct is normally + * the root of the construct tree. + * + * You would normally define an `App` instance in your program's entrypoint, + * then define constructs where the app is used as the parent scope. + * + * After all the child constructs are defined within the app, you should call + * `app.synth()` which will emit a "cloud assembly" from this app into the + * directory specified by `outdir`. Cloud assemblies includes artifacts such as + * CloudFormation templates and assets that are needed to deploy this app into + * the AWS cloud. + * + * @see https://docs.aws.amazon.com/cdk/latest/guide/apps_and_stacks.html */ export class App extends Construct { + /** + * Checks if an object is an instance of the `App` class. + * @returns `true` if `obj` is an `App`. + * @param obj The object to evaluate + */ public static isApp(obj: any): obj is App { return APP_SYMBOL in obj; } @@ -62,7 +81,7 @@ export class App extends Construct { /** * Initializes a CDK application. - * @param request Optional toolkit request (e.g. for tests) + * @param props initialization properties */ constructor(props: AppProps = {}) { super(undefined as any, ''); @@ -84,20 +103,19 @@ export class App extends Construct { this.outdir = props.outdir || process.env[cxapi.OUTDIR_ENV]; const autoRun = props.autoRun !== undefined ? props.autoRun : cxapi.OUTDIR_ENV in process.env; - if (autoRun) { - // run() guarantuees it will only execute once, so a default of 'true' doesn't bite manual calling - // of the function. + // run() guarantuees it will only execute once, so a default of 'true' + // doesn't bite manual calling of the function. process.once('beforeExit', () => this.run()); } } /** - * Runs the program. Output is written to output directory as specified in the - * request. + * Synthesizes a cloud assembly for this app. Emits it to the directory + * specified by `outdir`. * - * @returns a `CloudAssembly` which includes all the synthesized artifacts - * such as CloudFormation templates and assets. + * @returns a `CloudAssembly` which can be used to inspect synthesized + * artifacts such as CloudFormation templates and assets. */ public run(): CloudAssembly { // this app has already been executed, no-op for you diff --git a/packages/@aws-cdk/cdk/lib/cfn-element.ts b/packages/@aws-cdk/cdk/lib/cfn-element.ts index c5bd71e24b2fd..468a78441a55c 100644 --- a/packages/@aws-cdk/cdk/lib/cfn-element.ts +++ b/packages/@aws-cdk/cdk/lib/cfn-element.ts @@ -1,8 +1,7 @@ +import cxapi = require('@aws-cdk/cx-api'); import { Construct, IConstruct, PATH_SEP } from "./construct"; import { Token } from './token'; -const LOGICAL_ID_MD = 'aws:cdk:logicalId'; - /** * An element of a CloudFormation stack. */ @@ -43,7 +42,7 @@ export abstract class CfnElement extends Construct { constructor(scope: Construct, id: string) { super(scope, id); - this.node.addMetadata(LOGICAL_ID_MD, new (require("./token").Token)(() => this.logicalId), this.constructor); + this.node.addMetadata(cxapi.LOGICAL_ID_METADATA_KEY, new (require("./token").Token)(() => this.logicalId), this.constructor); this._logicalId = this.node.stack.logicalIds.getLogicalId(this); this.logicalId = new Token(() => this._logicalId, `${notTooLong(this.node.path)}.LogicalID`).toString(); @@ -63,7 +62,7 @@ export abstract class CfnElement extends Construct { * node +internal+ entries filtered. */ public get creationStackTrace(): string[] | undefined { - const trace = this.node.metadata.find(md => md.type === LOGICAL_ID_MD)!.trace; + const trace = this.node.metadata.find(md => md.type === cxapi.LOGICAL_ID_METADATA_KEY)!.trace; if (!trace) { return undefined; } diff --git a/packages/@aws-cdk/cdk/lib/stack.ts b/packages/@aws-cdk/cdk/lib/stack.ts index 41d3626c57fe0..07bbb61e009db 100644 --- a/packages/@aws-cdk/cdk/lib/stack.ts +++ b/packages/@aws-cdk/cdk/lib/stack.ts @@ -6,7 +6,9 @@ import { CfnParameter } from './cfn-parameter'; import { Construct, IConstruct, PATH_SEP } from './construct'; import { Environment } from './environment'; import { HashedAddressingScheme, IAddressingScheme, LogicalIDs } from './logical-id'; +import { ISynthesisSession } from './synthesis'; import { makeUniqueId } from './uniqueid'; + export interface StackProps { /** * The AWS environment (account/region) where this stack will be deployed. @@ -31,15 +33,16 @@ export interface StackProps { readonly namingScheme?: IAddressingScheme; /** - * Should the Stack be deployed when running `cdk deploy` without arguments - * (and listed when running `cdk synth` without arguments). - * Setting this to `false` is useful when you have a Stack in your CDK app - * that you don't want to deploy using the CDK toolkit - - * for example, because you're planning on deploying it through CodePipeline. + * Indicates if this stack is hidden, which means that it won't be + * automatically deployed when running `cdk deploy` without arguments. + * + * Setting this to `true` is useful when you have a stack in your CDK app + * which you don't want to deploy using the CDK toolkit. For example, because + * you're planning on deploying it through a deployment pipeline. * - * @default true + * @default false */ - readonly autoDeploy?: boolean; + readonly hidden?: boolean; /** * Stack tags that will be applied to all the taggable resources and the stack itself. @@ -116,15 +119,16 @@ export class Stack extends Construct implements ITaggable { public readonly name: string; /** - * Should the Stack be deployed when running `cdk deploy` without arguments - * (and listed when running `cdk synth` without arguments). - * Setting this to `false` is useful when you have a Stack in your CDK app - * that you don't want to deploy using the CDK toolkit - - * for example, because you're planning on deploying it through CodePipeline. + * Indicates if this stack is hidden, which means that it won't be + * automatically deployed when running `cdk deploy` without arguments. + * + * Setting this to `true` is useful when you have a stack in your CDK app + * which you don't want to deploy using the CDK toolkit. For example, because + * you're planning on deploying it through a deployment pipeline. * - * By default, this is `true`. + * By default, all stacks are visible (this will be false). */ - public readonly autoDeploy: boolean; + public readonly hidden: boolean; /** * Other stacks this stack depends on @@ -159,9 +163,9 @@ export class Stack extends Construct implements ITaggable { this.configuredEnv = props.env || {}; this.env = this.parseEnvironment(props.env); - this.logicalIds = new LogicalIDs(props && props.namingScheme ? props.namingScheme : new HashedAddressingScheme()); + this.logicalIds = new LogicalIDs(props.namingScheme ? props.namingScheme : new HashedAddressingScheme()); this.name = props.stackName !== undefined ? props.stackName : this.calculateStackName(); - this.autoDeploy = props && props.autoDeploy === false ? false : true; + this.hidden = props.hidden === undefined ? false : true; this.tags = new TagManager(TagType.KeyValue, "aws:cdk:stack", props.tags); if (!Stack.VALID_STACK_NAME_REGEX.test(this.name)) { @@ -509,7 +513,8 @@ export class Stack extends Construct implements ITaggable { } } - protected synthesize(builder: cxapi.CloudAssemblyBuilder): void { + protected synthesize(session: ISynthesisSession): void { + const builder = session.assembly; const template = `${this.name}.template.json`; // write the CloudFormation template as a JSON file @@ -529,7 +534,7 @@ export class Stack extends Construct implements ITaggable { type: cxapi.ArtifactType.AwsCloudFormationStack, environment: this.environment, properties, - autoDeploy: this.autoDeploy ? undefined : false, + hidden: this.hidden ? true : undefined, // omit if stack is visible dependencies: deps.length > 0 ? deps : undefined, metadata: Object.keys(meta).length > 0 ? meta : undefined, missing: this.missingContext && Object.keys(this.missingContext).length > 0 ? this.missingContext : undefined diff --git a/packages/@aws-cdk/cdk/lib/synthesis.ts b/packages/@aws-cdk/cdk/lib/synthesis.ts index 32a684683b6f2..baa25cc6913aa 100644 --- a/packages/@aws-cdk/cdk/lib/synthesis.ts +++ b/packages/@aws-cdk/cdk/lib/synthesis.ts @@ -1,8 +1,15 @@ import { BuildOptions, CloudAssembly, CloudAssemblyBuilder } from '@aws-cdk/cx-api'; import { ConstructOrder, IConstruct } from './construct'; +export interface ISynthesisSession { + /** + * The cloud assembly being synthesized. + */ + assembly: CloudAssemblyBuilder; +} + export interface ISynthesizable { - synthesize(session: CloudAssemblyBuilder): void; + synthesize(session: ISynthesisSession): void; } export interface SynthesisOptions extends BuildOptions { @@ -21,7 +28,7 @@ export interface SynthesisOptions extends BuildOptions { export class Synthesizer { public synthesize(root: IConstruct, options: SynthesisOptions = { }): CloudAssembly { - const session = new CloudAssemblyBuilder(options.outdir); + const builder = new CloudAssemblyBuilder(options.outdir); // the three holy phases of synthesis: prepare, validate and synthesize @@ -41,12 +48,12 @@ export class Synthesizer { // synthesize (leaves first) for (const c of root.node.findAll(ConstructOrder.PostOrder)) { if (isSynthesizable(c)) { - c.synthesize(session); + c.synthesize({ assembly: builder }); } } // write session manifest and lock store - return session.build(options); + return builder.build(options); } } diff --git a/packages/@aws-cdk/cdk/test/test.app.ts b/packages/@aws-cdk/cdk/test/test.app.ts index 77ee96c813bb1..8845eb9348031 100644 --- a/packages/@aws-cdk/cdk/test/test.app.ts +++ b/packages/@aws-cdk/cdk/test/test.app.ts @@ -60,7 +60,7 @@ export = { test.deepEqual(stack1.template, { Resources: { s1c1: { Type: 'DummyResource', Properties: { Prop1: 'Prop1' } }, s1c2: { Type: 'DummyResource', Properties: { Foo: 123 } } } }); - test.deepEqual(stack1.metadata, { + test.deepEqual(stack1.manifest.metadata, { '/stack1': [{ type: 'meta', data: 111 }], '/stack1/s1c1': [{ type: 'aws:cdk:logicalId', data: 's1c1' }], '/stack1/s1c2': @@ -77,7 +77,7 @@ export = { { s2c1: { Type: 'DummyResource', Properties: { Prog2: 'Prog2' } }, s1c2r1D1791C01: { Type: 'ResourceType1' }, s1c2r25F685FFF: { Type: 'ResourceType2' } } }); - test.deepEqual(stack2.metadata, { + test.deepEqual(stack2.manifest.metadata, { '/stack2/s2c1': [{ type: 'aws:cdk:logicalId', data: 's2c1' }], '/stack2/s1c2': [{ type: 'meta', data: { key: 'value' } }], '/stack2/s1c2/r1': @@ -193,7 +193,7 @@ export = { new MyStack(app, 'MyStack'); }); - test.deepEqual(response.stacks[0].missing, { + test.deepEqual(response.missing, { "missing-context-key": { provider: 'fake', props: { diff --git a/packages/@aws-cdk/cdk/test/test.context.ts b/packages/@aws-cdk/cdk/test/test.context.ts index d701a725153f1..b11dd432f0b7f 100644 --- a/packages/@aws-cdk/cdk/test/test.context.ts +++ b/packages/@aws-cdk/cdk/test/test.context.ts @@ -102,7 +102,7 @@ export = { const assembly = app.run(); const output = assembly.getStack('test-stack'); - const metadata = output.metadata; + const metadata = output.manifest.metadata || {}; const azError: cxapi.MetadataEntry | undefined = metadata['/test-stack'].find(x => x.type === cxapi.ERROR_METADATA_KEY); const ssmError: cxapi.MetadataEntry | undefined = metadata['/test-stack/ChildConstruct'].find(x => x.type === cxapi.ERROR_METADATA_KEY); diff --git a/packages/@aws-cdk/cdk/test/test.synthesis.ts b/packages/@aws-cdk/cdk/test/test.synthesis.ts index 9b6f8e64f4bb1..00716cb1a2e65 100644 --- a/packages/@aws-cdk/cdk/test/test.synthesis.ts +++ b/packages/@aws-cdk/cdk/test/test.synthesis.ts @@ -5,7 +5,7 @@ import { Test } from 'nodeunit'; import os = require('os'); import path = require('path'); import cdk = require('../lib'); -import { Construct, Synthesizer } from '../lib'; +import { Construct, ISynthesisSession, Synthesizer } from '../lib'; function createModernApp() { return new cdk.App({ @@ -53,9 +53,9 @@ export = { const stack = new cdk.Stack(app, 'one-stack'); class MyConstruct extends cdk.Construct implements cdk.ISynthesizable { - public synthesize(s: cxapi.CloudAssemblyBuilder) { - writeJson(s.outdir, 'foo.json', { bar: 123 }); - s.addArtifact('my-random-construct', { + public synthesize(s: ISynthesisSession) { + writeJson(s.assembly.outdir, 'foo.json', { bar: 123 }); + s.assembly.addArtifact('my-random-construct', { type: cxapi.ArtifactType.AwsCloudFormationStack, environment: 'aws://12345/bar', properties: { @@ -118,7 +118,13 @@ export = { session.addArtifact('art', { type: cxapi.ArtifactType.AwsCloudFormationStack, - properties: { templateFile: 'hey.json' }, + properties: { + templateFile: 'hey.json', + parameters: { + paramId: 'paramValue', + paramId2: 'paramValue2' + } + }, environment: 'aws://unknown-account/us-east-1' }); @@ -134,7 +140,8 @@ export = { test.deepEqual(calls, [ 'prepare', 'validate', 'synthesize' ]); const stack = assembly.getStack('art'); test.deepEqual(stack.template, { hello: 123 }); - test.deepEqual(stack.properties, { templateFile: 'hey.json' }); + test.deepEqual(stack.templateFile, 'hey.json'); + test.deepEqual(stack.parameters, { paramId: 'paramValue', paramId2: 'paramValue2' }); test.deepEqual(stack.environment, { region: 'us-east-1', account: 'unknown-account', name: 'aws://unknown-account/us-east-1' }); test.done(); }, @@ -150,8 +157,8 @@ export = { // THEN const session = app.run(); - const props = session.getStack('my-stack').properties; - test.deepEqual(props.parameters, { + const artifact = session.getStack('my-stack'); + test.deepEqual(artifact.parameters, { MyParam: 'Foo' }); test.done(); diff --git a/packages/@aws-cdk/cx-api/lib/cloud-artifact.ts b/packages/@aws-cdk/cx-api/lib/cloud-artifact.ts index 159b00ac161be..21a1652bfe79a 100644 --- a/packages/@aws-cdk/cx-api/lib/cloud-artifact.ts +++ b/packages/@aws-cdk/cx-api/lib/cloud-artifact.ts @@ -1,64 +1,141 @@ import { CloudAssembly, MissingContext } from './cloud-assembly'; import { Environment, EnvironmentUtils } from './environment'; -import { ERROR_METADATA_KEY, INFO_METADATA_KEY, MetadataEntry, SynthesisMessage, SynthesisMessageLevel, WARNING_METADATA_KEY } from './metadata'; - +import { + ERROR_METADATA_KEY, + INFO_METADATA_KEY, + MetadataEntry, + MetadataEntryResult, + SynthesisMessage, + SynthesisMessageLevel, + WARNING_METADATA_KEY } from './metadata'; + +/** + * Type of cloud artifact. + */ export enum ArtifactType { - None = 'none', + None = 'none', // required due to a jsii bug + + /** + * The artifact is an AWS CloudFormation stack. + */ AwsCloudFormationStack = 'aws:cloudformation:stack', } -export interface Artifact { +/** + * A manifest for a single artifact within the cloud assembly. + */ +export interface ArtifactManifest { + /** + * The type of artifact. + */ readonly type: ArtifactType; + + /** + * The environment into which this artifact is deployed. + */ readonly environment: string; // format: aws://account/region + + /** + * Associated metadata. + */ readonly metadata?: { [path: string]: MetadataEntry[] }; + + /** + * IDs of artifacts that must be deployed before this artifact. + */ readonly dependencies?: string[]; + + /** + * Any missing context information. + */ readonly missing?: { [key: string]: MissingContext }; + + /** + * The set of properties for this artifact (depends on type) + */ readonly properties?: { [name: string]: any }; - readonly autoDeploy?: boolean; + + /** + * True if this artifact should be be explicitly deployed or is it a "hidden" artifact. + */ + readonly hidden?: boolean; } +/** + * Artifact properties for CloudFormation stacks. + */ export interface AwsCloudFormationStackProperties { + /** + * A file relative to the assembly root which contains the CloudFormation template for this stack. + */ readonly templateFile: string; + + /** + * Values for CloudFormation stack parameters that should be passed when the stack is deployed. + */ readonly parameters?: { [id: string]: string }; } +/** + * Represents an artifact within a cloud assembly. + */ export class CloudArtifact { - public static from(assembly: CloudAssembly, name: string, artifact: Artifact): CloudArtifact { + /** + * Returns a subclass of `CloudArtifact` based on the artifact type defined in the artifact manifest. + * @param assembly The cloud assembly from which to load the artifact + * @param id The artifact ID + * @param artifact The artifact manifest + */ + public static from(assembly: CloudAssembly, id: string, artifact: ArtifactManifest): CloudArtifact { switch (artifact.type) { case ArtifactType.AwsCloudFormationStack: - return new CloudFormationStackArtifact(assembly, name, artifact); + return new CloudFormationStackArtifact(assembly, id, artifact); default: throw new Error(`unsupported artifact type: ${artifact.type}`); } } - public readonly type: ArtifactType; - public readonly missing: { [key: string]: MissingContext }; - public readonly autoDeploy: boolean; + /** + * The artifact's manifest + */ + public readonly manifest: ArtifactManifest; + + /** + * The set of messages extracted from the artifact's metadata. + */ public readonly messages: SynthesisMessage[]; + + /** + * The environment into which to deploy this artifact. + */ public readonly environment: Environment; - public readonly metadata: { [path: string]: MetadataEntry[] }; - public readonly dependsIDs: string[]; - public readonly properties: { [name: string]: any }; - - private _deps?: CloudArtifact[]; // cache - - constructor(public readonly assembly: CloudAssembly, public readonly id: string, artifact: Artifact) { - this.missing = artifact.missing || { }; - this.type = artifact.type; - this.environment = EnvironmentUtils.parse(artifact.environment); - this.autoDeploy = artifact.autoDeploy === undefined ? true : artifact.autoDeploy; - this.metadata = artifact.metadata || { }; + + /** + * IDs of all dependencies. Used when topologically sorting the artifacts within the cloud assembly. + * @internal + */ + public readonly _dependencyIDs: string[]; + + /** + * Cache of resolved dependencies. + */ + private _deps?: CloudArtifact[]; + + protected constructor(public readonly assembly: CloudAssembly, public readonly id: string, manifest: ArtifactManifest) { + this.manifest = manifest; + this.environment = EnvironmentUtils.parse(manifest.environment); this.messages = this.renderMessages(); - this.dependsIDs = artifact.dependencies || []; - this.properties = artifact.properties || { }; + this._dependencyIDs = manifest.dependencies || []; } - public get depends(): CloudArtifact[] { + /** + * Returns all the artifacts that this artifact depends on. + */ + public get dependencies(): CloudArtifact[] { if (this._deps) { return this._deps; } - this._deps = this.dependsIDs.map(id => { + this._deps = this._dependencyIDs.map(id => { const dep = this.assembly.artifacts.find(a => a.id === id); if (!dep) { throw new Error(`Artifact ${this.id} depends on non-existing artifact ${id}`); @@ -69,10 +146,26 @@ export class CloudArtifact { return this._deps; } + /** + * @returns all the metadata entries of a specific type in this artifact. + * @param type + */ + public findMetadataByType(type: string) { + const result = new Array(); + for (const path of Object.keys(this.manifest.metadata || {})) { + for (const entry of (this.manifest.metadata || {})[path]) { + if (entry.type === type) { + result.push({ path, ...entry }); + } + } + } + return result; + } + private renderMessages() { const messages = new Array(); - for (const [ id, metadata ] of Object.entries(this.metadata)) { + for (const [ id, metadata ] of Object.entries(this.manifest.metadata || { })) { for (const entry of metadata) { let level: SynthesisMessageLevel; switch (entry.type) { diff --git a/packages/@aws-cdk/cx-api/lib/cloud-assembly.ts b/packages/@aws-cdk/cx-api/lib/cloud-assembly.ts index f4c0f9c037c83..8aa3416a6731c 100644 --- a/packages/@aws-cdk/cx-api/lib/cloud-assembly.ts +++ b/packages/@aws-cdk/cx-api/lib/cloud-assembly.ts @@ -1,11 +1,14 @@ import fs = require('fs'); import os = require('os'); import path = require('path'); -import { Artifact, CloudArtifact } from './cloud-artifact'; +import { ArtifactManifest, CloudArtifact } from './cloud-artifact'; import { CloudFormationStackArtifact } from './cloudformation-artifact'; import { topologicalSort } from './toposort'; import { CLOUD_ASSEMBLY_VERSION, verifyManifestVersion } from './versioning'; +/** + * A manifest which describes the cloud assembly. + */ export interface AssemblyManifest { /** * Protocol version @@ -15,7 +18,7 @@ export interface AssemblyManifest { /** * The set of artifacts in this assembly. */ - readonly artifacts?: { [id: string]: Artifact }; + readonly artifacts?: { [id: string]: ArtifactManifest }; /** * Runtime information. @@ -28,15 +31,47 @@ export interface AssemblyManifest { */ const MANIFEST_FILE = 'manifest.json'; +/** + * Represents a deployable cloud application. + */ export class CloudAssembly { - public readonly artifacts: CloudArtifact[]; + /** + * The root directory of the cloud assembly. + */ + public readonly directory: string; + + /** + * The schema version of the assembly manifest. + */ public readonly version: string; + + /** + * All artifacts included in this assembly. + */ + public readonly artifacts: CloudArtifact[]; + + /** + * The set of missing context information (or `undefined` if there is no missing context). + */ public readonly missing?: { [key: string]: MissingContext }; + + /** + * Runtime information such as module versions used to synthesize this assembly. + */ public readonly runtime: RuntimeInfo; + + /** + * The raw assembly manifest. + */ public readonly manifest: AssemblyManifest; - constructor(public readonly directory: string) { - this.manifest = this.readJson(MANIFEST_FILE); + /** + * Reads a cloud assembly from the specified directory. + * @param directory The root directory of the assembly. + */ + constructor(directory: string) { + this.directory = directory; + this.manifest = JSON.parse(fs.readFileSync(path.join(directory, MANIFEST_FILE), 'UTF-8')); this.version = this.manifest.version; verifyManifestVersion(this.version); @@ -49,27 +84,37 @@ export class CloudAssembly { this.validateDeps(); } + /** + * Attempts to find an artifact with a specific identity. + * @returns A `CloudArtifact` object or `undefined` if the artifact does not exist in this assembly. + * @param id The artifact ID + */ public tryGetArtifact(id: string): CloudArtifact | undefined { return this.stacks.find(a => a.id === id); } - public getStack(id: string): CloudFormationStackArtifact { - const artifact = this.tryGetArtifact(id); + /** + * Returns a CloudFormation stack artifact from this assembly. + * @param stackName the name of the CloudFormation stack. + * @throws if there is no stack artifact by that name + * @returns a `CloudFormationStackArtifact` object. + */ + public getStack(stackName: string): CloudFormationStackArtifact { + const artifact = this.tryGetArtifact(stackName); if (!artifact) { - throw new Error(`Unable to find artifact with id "${id}"`); + throw new Error(`Unable to find artifact with id "${stackName}"`); } if (!(artifact instanceof CloudFormationStackArtifact)) { - throw new Error(`Artifact ${id} is not a CloudFormation stack`); + throw new Error(`Artifact ${stackName} is not a CloudFormation stack`); } return artifact; } - public readJson(filePath: string) { - return JSON.parse(fs.readFileSync(path.join(this.directory, filePath), 'utf-8')); - } - + /** + * @returns all the CloudFormation stack artifacts that are included in this assembly. + */ public get stacks(): CloudFormationStackArtifact[] { const result = new Array(); for (const a of this.artifacts) { @@ -82,7 +127,7 @@ export class CloudAssembly { private validateDeps() { for (const artifact of this.artifacts) { - ignore(artifact.depends); + ignore(artifact.dependencies); } } @@ -92,13 +137,13 @@ export class CloudAssembly { result.push(CloudArtifact.from(this, name, artifact)); } - return topologicalSort(result, x => x.id, x => x.dependsIDs); + return topologicalSort(result, x => x.id, x => x._dependencyIDs); } private renderMissing() { const missing: { [key: string]: MissingContext } = { }; - for (const artifact of this.artifacts) { - for (const [ key, m ] of Object.entries(artifact.missing)) { + for (const artifact of Object.values(this.manifest.artifacts || {})) { + for (const [ key, m ] of Object.entries(artifact.missing || {})) { missing[key] = m; } } @@ -107,11 +152,21 @@ export class CloudAssembly { } } +/** + * Can be used to build a cloud assembly. + */ export class CloudAssemblyBuilder { + /** + * The root directory of the resulting cloud assembly. + */ public readonly outdir: string; - private readonly artifacts: { [id: string]: Artifact } = { }; + private readonly artifacts: { [id: string]: ArtifactManifest } = { }; + /** + * Initializes a cloud assembly builder. + * @param outdir The output directory, uses temporary directory if undefined + */ constructor(outdir?: string) { this.outdir = outdir || fs.mkdtempSync(path.join(os.tmpdir(), 'cdk.out')); @@ -129,8 +184,13 @@ export class CloudAssemblyBuilder { } } - public addArtifact(name: string, artifact: Artifact) { - this.artifacts[name] = filterUndefined(artifact); + /** + * Adds an artifact into the cloud assembly. + * @param id The ID of the artifact. + * @param manifest The artifact manifest + */ + public addArtifact(id: string, manifest: ArtifactManifest) { + this.artifacts[id] = filterUndefined(manifest); } public build(options: BuildOptions = { }): CloudAssembly { diff --git a/packages/@aws-cdk/cx-api/lib/cloudformation-artifact.ts b/packages/@aws-cdk/cx-api/lib/cloudformation-artifact.ts index ff113472cbfb1..551d92cc7015d 100644 --- a/packages/@aws-cdk/cx-api/lib/cloudformation-artifact.ts +++ b/packages/@aws-cdk/cx-api/lib/cloudformation-artifact.ts @@ -1,55 +1,52 @@ +import fs = require('fs'); +import path = require('path'); import { ASSET_METADATA, AssetMetadataEntry } from './assets'; -import { Artifact, AwsCloudFormationStackProperties, CloudArtifact } from './cloud-artifact'; +import { ArtifactManifest, AwsCloudFormationStackProperties, CloudArtifact } from './cloud-artifact'; import { CloudAssembly } from './cloud-assembly'; export class CloudFormationStackArtifact extends CloudArtifact { + /** + * The CloudFormation template for this stack. + */ public readonly template: any; + + /** + * The file name of the template. + */ + public readonly templateFile: string; + + /** + * The original name as defined in the CDK app. + */ public readonly originalName: string; - public readonly logicalIdToPathMap: { [logicalId: string]: string }; + + /** + * Any assets associated with this stack. + */ public readonly assets: AssetMetadataEntry[]; + /** + * CloudFormation parameters to pass to the stack. + */ + public readonly parameters: { [id: string]: string }; + + /** + * The name of this stack. This is read/write and can be used to rename the stack. + */ public name: string; - constructor(assembly: CloudAssembly, name: string, artifact: Artifact) { + constructor(assembly: CloudAssembly, name: string, artifact: ArtifactManifest) { super(assembly, name, artifact); if (!artifact.properties || !artifact.properties.templateFile) { throw new Error(`Invalid CloudFormation stack artifact. Missing "templateFile" property in cloud assembly manifest`); } + const properties = (this.manifest.properties || {}) as AwsCloudFormationStackProperties; + this.templateFile = properties.templateFile; + this.parameters = properties.parameters || { }; - const properties = this.properties as AwsCloudFormationStackProperties; - this.template = this.assembly.readJson(properties.templateFile); - this.originalName = name; - this.name = this.originalName; - this.logicalIdToPathMap = this.buildLogicalToPathMap(); - this.assets = this.buildAssets(); - } - - private buildAssets() { - const assets = new Array(); - - for (const k of Object.keys(this.metadata)) { - for (const entry of this.metadata[k]) { - if (entry.type === ASSET_METADATA) { - assets.push(entry.data); - } - } - } - - return assets; - } - - private buildLogicalToPathMap() { - const map: { [id: string]: string } = {}; - for (const cpath of Object.keys(this.metadata)) { - const md = this.metadata[cpath]; - for (const e of md) { - if (e.type === 'aws:cdk:logicalId') { - const logical = e.data; - map[logical] = cpath; - } - } - } - return map; + this.name = this.originalName = name; + this.template = JSON.parse(fs.readFileSync(path.join(this.assembly.directory, this.templateFile), 'utf-8')); + this.assets = this.findMetadataByType(ASSET_METADATA).map(e => e.data); } } diff --git a/packages/@aws-cdk/cx-api/lib/metadata.ts b/packages/@aws-cdk/cx-api/lib/metadata.ts index 49957c3d1403e..4eec14a69f3ce 100644 --- a/packages/@aws-cdk/cx-api/lib/metadata.ts +++ b/packages/@aws-cdk/cx-api/lib/metadata.ts @@ -19,6 +19,11 @@ export const ERROR_METADATA_KEY = 'aws:cdk:error'; */ export const PATH_METADATA_KEY = 'aws:cdk:path'; +/** + * Represents the CloudFormation logical ID of a resource at a certain path. + */ +export const LOGICAL_ID_METADATA_KEY = 'aws:cdk:logicalId'; + /** * Tag metadata key. */ @@ -49,6 +54,13 @@ export interface MetadataEntry { readonly trace?: string[]; } +export interface MetadataEntryResult extends MetadataEntry { + /** + * The path in which this entry was defined. + */ + readonly path: string; +} + /** * Metadata associated with the objects in the stack's Construct tree */ diff --git a/packages/@aws-cdk/cx-api/test/cloud-assembly.test.ts b/packages/@aws-cdk/cx-api/test/cloud-assembly.test.ts index 41d11d12094f4..4736659cdede2 100644 --- a/packages/@aws-cdk/cx-api/test/cloud-assembly.test.ts +++ b/packages/@aws-cdk/cx-api/test/cloud-assembly.test.ts @@ -24,16 +24,15 @@ test('assembly a single cloudformation stack', () => { const stack = assembly.stacks[0]; expect(stack.assets).toHaveLength(0); - expect(stack.autoDeploy).toBeTruthy(); - expect(stack.depends).toEqual([]); + expect(stack.manifest.hidden).toBeFalsy(); + expect(stack.dependencies).toEqual([]); expect(stack.environment).toEqual({ account: '37736633', region: 'us-region-1', name: 'aws://37736633/us-region-1' }); expect(stack.template).toEqual({ Resources: { MyBucket: { Type: "AWS::S3::Bucket" } } }); expect(stack.messages).toEqual([]); - expect(stack.metadata).toEqual({}); - expect(stack.missing).toEqual({}); + expect(stack.manifest.metadata).toEqual(undefined); + expect(stack.manifest.missing).toEqual(undefined); expect(stack.originalName).toEqual('MyStackName'); expect(stack.name).toEqual('MyStackName'); - expect(stack.logicalIdToPathMap).toEqual({}); }); test('assembly with missing context', () => { @@ -72,21 +71,16 @@ test('assets', () => { expect(assembly.stacks[0].assets).toMatchSnapshot(); }); -test('logical id to path map', () => { - const assembly = new CloudAssembly(path.join(FIXTURES, 'logical-id-map')); - expect(assembly.stacks[0].logicalIdToPathMap).toEqual({ logicalIdOfFooBar: '/foo/bar' }); -}); - test('dependencies', () => { const assembly = new CloudAssembly(path.join(FIXTURES, 'depends')); expect(assembly.stacks).toHaveLength(4); // expect stacks to be listed in topological order expect(assembly.stacks.map(s => s.name)).toEqual([ 'StackA', 'StackD', 'StackC', 'StackB' ]); - expect(assembly.stacks[0].depends).toEqual([]); - expect(assembly.stacks[1].depends).toEqual([]); - expect(assembly.stacks[2].depends.map(x => x.id)).toEqual([ 'StackD' ]); - expect(assembly.stacks[3].depends.map(x => x.id)).toEqual([ 'StackC', 'StackD' ]); + expect(assembly.stacks[0].dependencies).toEqual([]); + expect(assembly.stacks[1].dependencies).toEqual([]); + expect(assembly.stacks[2].dependencies.map(x => x.id)).toEqual([ 'StackD' ]); + expect(assembly.stacks[3].dependencies.map(x => x.id)).toEqual([ 'StackC', 'StackD' ]); }); test('fails for invalid dependencies', () => { diff --git a/packages/aws-cdk/bin/cdk.ts b/packages/aws-cdk/bin/cdk.ts index dc65005ad76c3..8c5b259fdc23f 100644 --- a/packages/aws-cdk/bin/cdk.ts +++ b/packages/aws-cdk/bin/cdk.ts @@ -227,7 +227,7 @@ async function initCommandLine() { async function cliMetadata(stackName: string) { const s = await appStacks.synthesizeStack(stackName); - return s.metadata; + return s.manifest.metadata || {}; } /** diff --git a/packages/aws-cdk/lib/api/cxapp/stacks.ts b/packages/aws-cdk/lib/api/cxapp/stacks.ts index f0691bc85edc9..f1341bcbaadf3 100644 --- a/packages/aws-cdk/lib/api/cxapp/stacks.ts +++ b/packages/aws-cdk/lib/api/cxapp/stacks.ts @@ -91,10 +91,10 @@ export class AppStacks { if (selectors.length === 0) { // remove non-auto deployed Stacks - const autoDeployedStacks = stacks.filter(s => s.autoDeploy); - debug('Stack name not specified, so defaulting to all available stacks: ' + listStackNames(autoDeployedStacks)); - this.applyRenames(autoDeployedStacks); - return autoDeployedStacks; + const visibleStacks = stacks.filter(s => !s.manifest.hidden); + debug('Stack name not specified, so defaulting to all available stacks: ' + listStackNames(visibleStacks)); + this.applyRenames(visibleStacks); + return visibleStacks; } const allStacks = new Map(); @@ -158,12 +158,8 @@ export class AppStacks { */ public async synthesizeStack(stackName: string): Promise { const resp = await this.synthesizeStacks(); - const stack = resp.stacks.find(s => s.name === stackName); - if (!stack) { - throw new Error(`Stack ${stackName} not found`); - } + const stack = resp.getStack(stackName); this.applyRenames([stack]); - return stack; } @@ -235,18 +231,10 @@ export class AppStacks { } /** - * Returns and array with the tags available in the stack metadata. + * @returns an array with the tags available in the stack metadata. */ public getTagsFromStackMetadata(stack: cxapi.CloudFormationStackArtifact): Tag[] { - for (const id of Object.keys(stack.metadata)) { - const metadata = stack.metadata[id]; - for (const entry of metadata) { - if (entry.type === cxapi.STACK_TAGS_METADATA_KEY) { - return entry.data; - } - } - } - return []; + return stack.findMetadataByType(cxapi.STACK_TAGS_METADATA_KEY).map(x => x.data); } /** @@ -342,7 +330,7 @@ function includeDownstreamStacks( for (const [name, stack] of allStacks) { // Select this stack if it's not selected yet AND it depends on a stack that's in the selected set - if (!selectedStacks.has(name) && (stack.depends || []).some(dep => selectedStacks.has(dep.id))) { + if (!selectedStacks.has(name) && (stack.dependencies || []).some(dep => selectedStacks.has(dep.id))) { selectedStacks.set(name, stack); added.push(name); madeProgress = true; @@ -370,7 +358,7 @@ function includeUpstreamStacks( for (const stack of selectedStacks.values()) { // Select an additional stack if it's not selected yet and a dependency of a selected stack (and exists, obviously) - for (const dependencyName of stack.depends.map(x => x.id)) { + for (const dependencyName of stack.dependencies.map(x => x.id)) { if (!selectedStacks.has(dependencyName) && allStacks.has(dependencyName)) { added.push(dependencyName); selectedStacks.set(dependencyName, allStacks.get(dependencyName)!); diff --git a/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts b/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts index f54a6a7261914..f103b3bf3a26e 100644 --- a/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts +++ b/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts @@ -237,12 +237,15 @@ export class StackActivityMonitor { } private findMetadataFor(logicalId: string | undefined): { entry: cxapi.MetadataEntry, path: string } | undefined { - const metadata = this.stack.metadata; + const metadata = this.stack.manifest.metadata; if (!logicalId || !metadata) { return undefined; } for (const path of Object.keys(metadata)) { - const entry = metadata[path].filter(e => e.type === 'aws:cdk:logicalId') - .find(e => e.data === logicalId); - if (entry) { return { entry, path }; } + const entry = metadata[path] + .filter(e => e.type === cxapi.LOGICAL_ID_METADATA_KEY) + .find(e => e.data === logicalId); + if (entry) { + return { entry, path }; + } } return undefined; } diff --git a/packages/aws-cdk/lib/diff.ts b/packages/aws-cdk/lib/diff.ts index 35711733bd6da..989f8db59429c 100644 --- a/packages/aws-cdk/lib/diff.ts +++ b/packages/aws-cdk/lib/diff.ts @@ -39,7 +39,7 @@ export function printStackDiff( } if (!diff.isEmpty) { - cfnDiff.formatDifferences(stream || process.stderr, diff, newTemplate.logicalIdToPathMap, context); + cfnDiff.formatDifferences(stream || process.stderr, diff, buildLogicalToPathMap(newTemplate), context); } else { print(colors.green('There were no differences')); } @@ -68,7 +68,7 @@ export function printSecurityDiff(oldTemplate: any, newTemplate: cxapi.CloudForm warning(`This deployment will make potentially sensitive changes according to your current security approval level (--require-approval ${requireApproval}).`); warning(`Please confirm you intend to make the following modifications:\n`); - cfnDiff.formatSecurityChanges(process.stdout, diff, newTemplate.logicalIdToPathMap); + cfnDiff.formatSecurityChanges(process.stdout, diff, buildLogicalToPathMap(newTemplate)); return true; } return false; @@ -88,3 +88,11 @@ function difRequiresApproval(diff: cfnDiff.TemplateDiff, requireApproval: Requir default: throw new Error(`Unrecognized approval level: ${requireApproval}`); } } + +function buildLogicalToPathMap(stack: cxapi.CloudFormationStackArtifact) { + const map: { [id: string]: string } = {}; + for (const md of stack.findMetadataByType(cxapi.LOGICAL_ID_METADATA_KEY)) { + map[md.data] = md.path; + } + return map; +} diff --git a/packages/aws-cdk/test/api/test.stacks.ts b/packages/aws-cdk/test/api/test.stacks.ts index fcce58ded3223..6977a5ddc0ba4 100644 --- a/packages/aws-cdk/test/api/test.stacks.ts +++ b/packages/aws-cdk/test/api/test.stacks.ts @@ -12,7 +12,7 @@ const FIXED_RESULT = testAssembly({ }, { stackName: 'witherrors', - autoDeploy: true, + hidden: false, template: { resource: 'errorresource' }, metadata: { '/resource': [ @@ -86,7 +86,7 @@ export = { { stackName: 'NotAutoDeployedStack', template: { resource: 'Resource' }, - autoDeploy: false, + hidden: true, }, ]); @@ -105,7 +105,7 @@ export = { { stackName: 'NotAutoDeployedStack', template: { resource: 'Resource' }, - autoDeploy: false, + hidden: true, }, ]); @@ -124,11 +124,11 @@ export = { { stackName: 'NotAutoDeployedStack', template: { resource: 'Resource' }, - autoDeploy: false, + hidden: true, }, { stackName: 'AutoDeployedStack', - autoDeploy: true, + hidden: false, depends: [ 'NotAutoDeployedStack' ], template: { resource: 'Resource' }, }, diff --git a/packages/aws-cdk/test/util.ts b/packages/aws-cdk/test/util.ts index 0e413a1da1312..60238ee581c64 100644 --- a/packages/aws-cdk/test/util.ts +++ b/packages/aws-cdk/test/util.ts @@ -5,7 +5,7 @@ import path = require('path'); export interface TestStackArtifact { stackName: string; template: any; - autoDeploy?: boolean; + hidden?: boolean; depends?: string[]; metadata?: cxapi.StackMetadata; assets?: cxapi.AssetMetadataEntry[]; @@ -29,7 +29,7 @@ export function testAssembly(...stacks: TestStackArtifact[]): cxapi.CloudAssembl builder.addArtifact(stack.stackName, { type: cxapi.ArtifactType.AwsCloudFormationStack, environment: 'aws://12345/here', - autoDeploy: stack.autoDeploy, + hidden: stack.hidden, dependencies: stack.depends, metadata, properties: { From 7ab5fcbbcd9cf9f8819ae76916d7fff9a5ba3d1e Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 4 Jun 2019 11:43:40 +0300 Subject: [PATCH 02/17] Additional changes BREAKING CHANGE: - `StackProps.autoDeploy` renamed to `entrypoint` (still true by default). - CLI must be upgraded to 0.34.0 (cx protocol changes) --- .../@aws-cdk/app-delivery/test/integ.cicd.ts | 2 +- packages/@aws-cdk/assert/lib/synth-utils.ts | 6 +- .../@aws-cdk/assert/test/test.assertions.ts | 2 +- .../assets-docker/test/integ.assets-docker.ts | 2 +- .../assets-docker/test/test.image-asset.ts | 2 +- packages/@aws-cdk/assets/lib/staging.ts | 4 +- .../assets/test/integ.assets.directory.lit.ts | 2 +- .../assets/test/integ.assets.file.lit.ts | 2 +- .../test/integ.assets.permissions.lit.ts | 2 +- .../assets/test/integ.assets.refs.lit.ts | 2 +- .../assets/test/integ.multi-assets.ts | 2 +- packages/@aws-cdk/assets/test/test.asset.ts | 10 +- .../test/integ.restapi.books.ts | 2 +- .../test/integ.restapi.defaults.ts | 2 +- .../aws-apigateway/test/integ.restapi.ts | 2 +- .../aws-apigateway/test/test.restapi.ts | 2 +- .../test/integ.amazonlinux2.ts | 2 +- .../test/integ.asg-w-classic-loadbalancer.ts | 2 +- .../aws-autoscaling/test/integ.asg-w-elbv2.ts | 2 +- .../test/integ.custom-scaling.ts | 2 +- .../test/integ.external-role.ts | 2 +- .../test/integ.spot-instances.ts | 2 +- .../test/integ.aws-custom-resource.ts | 2 +- .../test/integ.trivial-lambda-resource.ts | 2 +- .../test/integ.cloudfront-bucket-logging.ts | 2 +- .../test/integ.cloudfront-custom.ts | 2 +- .../test/integ.cloudfront-empty-root.ts | 2 +- .../test/integ.cloudfront-ipv6-disabled.ts | 2 +- .../test/integ.cloudfront-security-policy.ts | 2 +- .../aws-cloudfront/test/integ.cloudfront.ts | 2 +- .../test/integ.cloudtrail.lit.ts | 2 +- .../test/integ.alarm-and-dashboard.ts | 2 +- .../aws-codebuild/test/integ.caching.ts | 2 +- .../aws-codebuild/test/integ.defaults.lit.ts | 2 +- .../test/integ.docker-asset.lit.ts | 2 +- .../aws-codebuild/test/integ.ecr.lit.ts | 2 +- .../aws-codebuild/test/integ.github.ts | 2 +- .../test/integ.project-bucket.ts | 2 +- ...teg.project-secondary-sources-artifacts.ts | 2 +- .../aws-codebuild/test/integ.project-shell.ts | 2 +- .../aws-codebuild/test/integ.project-vpc.ts | 2 +- .../test/integ.codecommit-events.ts | 2 +- .../test/lambda/integ.deployment-group.ts | 2 +- .../test/server/integ.deployment-group.ts | 2 +- .../test/integ.cfn-template-from-repo.lit.ts | 2 +- .../test/integ.lambda-pipeline.ts | 2 +- .../test/integ.pipeline-alexa-deploy.ts | 2 +- .../test/integ.pipeline-cfn-cross-region.ts | 2 +- .../integ.pipeline-cfn-wtih-action-role.ts | 2 +- .../test/integ.pipeline-cfn.ts | 2 +- ...line-code-build-multiple-inputs-outputs.ts | 2 +- .../test/integ.pipeline-code-commit-build.ts | 2 +- .../test/integ.pipeline-code-commit.ts | 2 +- .../test/integ.pipeline-code-deploy.ts | 2 +- .../test/integ.pipeline-ecr-source.ts | 2 +- .../test/integ.pipeline-ecs-deploy.ts | 2 +- .../test/integ.pipeline-events.ts | 2 +- .../test/integ.pipeline-jenkins.ts | 2 +- .../test/integ.pipeline-manual-approval.ts | 2 +- .../test/integ.pipeline-s3-deploy.ts | 2 +- .../aws-config/test/integ.rule.lit.ts | 2 +- .../@aws-cdk/aws-dynamodb-global/README.md | 2 +- .../test/integ.dynamodb.global.ts | 2 +- .../test/integ.autoscaling.lit.ts | 2 +- .../test/integ.dynamodb.ondemand.ts | 2 +- .../aws-dynamodb/test/integ.dynamodb.ts | 2 +- .../@aws-cdk/aws-ec2/lib/security-group.ts | 8 +- packages/@aws-cdk/aws-ec2/lib/vpc.ts | 10 +- .../test/integ.import-default-vpc.lit.ts | 2 +- .../aws-ec2/test/integ.share-vpcs.lit.ts | 2 +- .../aws-ec2/test/integ.vpc-endpoint.lit.ts | 2 +- packages/@aws-cdk/aws-ec2/test/integ.vpc.ts | 2 +- packages/@aws-cdk/aws-ec2/test/integ.vpn.ts | 2 +- packages/@aws-cdk/aws-ecr/test/integ.basic.ts | 2 +- .../test/ec2/integ.scheduled-ecs-task.lit.ts | 2 +- .../test/fargate/integ.asset-image.ts | 2 +- .../aws-ecs-patterns/test/fargate/integ.l3.ts | 2 +- .../aws-ecs/test/ec2/integ.lb-awsvpc-nw.ts | 2 +- .../aws-ecs/test/ec2/integ.lb-bridge-nw.ts | 2 +- .../aws-ecs/test/ec2/integ.sd-awsvpc-nw.ts | 2 +- .../aws-ecs/test/ec2/integ.sd-bridge-nw.ts | 2 +- .../test/fargate/integ.lb-awsvpc-nw.ts | 2 +- .../test/example.ssh-into-nodes.lit.ts | 2 +- .../aws-eks/test/integ.eks-cluster.lit.ts | 2 +- .../test/integ.elb.ts | 2 +- .../test/integ.alb.ts | 2 +- .../test/integ.nlb.ts | 2 +- .../test/codebuild/integ.project-events.ts | 2 +- .../integ.pipeline-event-target.ts | 2 +- .../test/ecs/integ.event-ec2-task.lit.ts | 2 +- .../test/ecs/integ.event-fargate-task.ts | 2 +- .../test/lambda/integ.events.ts | 2 +- .../test/sns/integ.sns-event-rule-target.ts | 2 +- packages/@aws-cdk/aws-events/lib/input.ts | 2 +- .../@aws-cdk/aws-events/test/test.rule.ts | 2 +- .../@aws-cdk/aws-glue/test/integ.table.ts | 2 +- .../aws-iam/test/integ.composite-principal.ts | 2 +- packages/@aws-cdk/aws-iam/test/integ.group.ts | 2 +- .../@aws-cdk/aws-iam/test/integ.policy.ts | 2 +- packages/@aws-cdk/aws-iam/test/integ.role.ts | 2 +- packages/@aws-cdk/aws-iam/test/integ.user.ts | 2 +- .../aws-iam/test/integ.users-and-groups.ts | 2 +- packages/@aws-cdk/aws-iam/test/test.policy.ts | 4 +- .../@aws-cdk/aws-kinesis/test/test.stream.ts | 2 +- .../aws-kms/test/integ.key-sharing.lit.ts | 2 +- packages/@aws-cdk/aws-kms/test/integ.key.ts | 2 +- .../test/integ.dynamodb.ts | 2 +- .../test/integ.kinesis.ts | 2 +- .../aws-lambda-event-sources/test/integ.s3.ts | 2 +- .../test/integ.sns.ts | 2 +- .../test/integ.sqs.ts | 2 +- .../aws-lambda/test/integ.assets.file.ts | 2 +- .../aws-lambda/test/integ.assets.lit.ts | 2 +- .../@aws-cdk/aws-lambda/test/integ.lambda.ts | 2 +- .../test/integ.layer-version.lit.ts | 2 +- .../aws-lambda/test/integ.log-retention.ts | 2 +- .../aws-lambda/test/integ.vpc-lambda.ts | 2 +- .../@aws-cdk/aws-lambda/test/test.code.ts | 2 +- .../aws-logs/test/integ.metricfilter.lit.ts | 2 +- .../test/integ.cluster-rotation.lit.ts | 2 +- .../@aws-cdk/aws-rds/test/integ.cluster.ts | 2 +- .../aws-rds/test/integ.instance.lit.ts | 2 +- .../test/integ.alb-alias-target.ts | 2 +- .../test/integ.cloudfront-alias-target.ts | 2 +- .../aws-route53/test/integ.route53.ts | 2 +- .../test/integ.bucket-deployment.ts | 2 +- .../test/integ.notifications.ts | 2 +- .../test/lambda/integ.bucket-notifications.ts | 2 +- .../sns/integ.sns-bucket-notifications.ts | 2 +- .../test/sqs/integ.bucket-notifications.ts | 2 +- .../aws-s3/test/integ.bucket-sharing.lit.ts | 2 +- .../aws-s3/test/integ.bucket.domain-name.ts | 2 +- packages/@aws-cdk/aws-s3/test/integ.bucket.ts | 2 +- .../aws-s3/test/integ.bucket.url.lit.ts | 2 +- .../@aws-cdk/aws-s3/test/integ.lifecycle.ts | 2 +- .../test/example.app-with-secret.lit.ts | 2 +- .../test/integ.secret.lit.ts | 2 +- .../integ.service-with-cname-record.lit.ts | 2 +- .../integ.service-with-http-namespace.lit.ts | 2 +- ....service-with-private-dns-namespace.lit.ts | 2 +- ...g.service-with-public-dns-namespace.lit.ts | 2 +- .../@aws-cdk/aws-ses/test/integ.receipt.ts | 2 +- .../@aws-cdk/aws-sns/test/integ.sns-lambda.ts | 2 +- .../aws-sns/test/integ.sns-sqs.lit.ts | 2 +- packages/@aws-cdk/aws-sns/test/integ.sns.ts | 2 +- packages/@aws-cdk/aws-sqs/test/integ.sqs.ts | 2 +- .../test/integ.parameter-store-string.lit.ts | 2 +- .../aws-ssm/test/integ.parameter.lit.ts | 2 +- .../aws-stepfunctions-tasks/lib/json-path.ts | 6 +- .../test/integ.ec2-task.ts | 2 +- .../test/integ.fargate-task.ts | 2 +- .../test/integ.job-poller.ts | 2 +- packages/@aws-cdk/cdk/lib/app.ts | 17 +-- packages/@aws-cdk/cdk/lib/cfn-element.ts | 12 +- packages/@aws-cdk/cdk/lib/cfn-reference.ts | 2 +- packages/@aws-cdk/cdk/lib/construct.ts | 141 ++++++++++++++---- packages/@aws-cdk/cdk/lib/context.ts | 11 +- packages/@aws-cdk/cdk/lib/index.ts | 1 - packages/@aws-cdk/cdk/lib/reference.ts | 4 +- packages/@aws-cdk/cdk/lib/stack.ts | 84 +++++------ packages/@aws-cdk/cdk/lib/synthesis.ts | 65 -------- packages/@aws-cdk/cdk/test/test.app.ts | 30 ++-- packages/@aws-cdk/cdk/test/test.context.ts | 14 +- packages/@aws-cdk/cdk/test/test.stack.ts | 8 +- packages/@aws-cdk/cdk/test/test.synthesis.ts | 48 +++--- packages/@aws-cdk/cdk/test/test.tag-aspect.ts | 1 - .../@aws-cdk/cx-api/lib/cloud-artifact.ts | 18 +-- .../@aws-cdk/cx-api/lib/cloud-assembly.ts | 76 +++++++--- packages/@aws-cdk/cx-api/lib/versioning.ts | 2 +- .../__snapshots__/cloud-assembly.test.js.snap | 23 ++- .../test/cloud-assembly-builder.test.ts | 23 ++- .../cx-api/test/cloud-assembly.test.ts | 15 +- .../cx-api/test/fixtures/assets/manifest.json | 2 +- .../test/fixtures/depends/manifest.json | 2 +- .../cx-api/test/fixtures/empty/manifest.json | 2 +- .../invalid-artifact-type/manifest.json | 2 +- .../fixtures/invalid-depends/manifest.json | 2 +- .../fixtures/invalid-env-format/manifest.json | 2 +- .../fixtures/logical-id-map/manifest.json | 2 +- .../test/fixtures/messages/manifest.json | 2 +- .../fixtures/missing-context/manifest.json | 10 +- .../fixtures/multiple-stacks/manifest.json | 2 +- .../test/fixtures/single-stack/manifest.json | 2 +- .../stack-without-params/manifest.json | 2 +- packages/aws-cdk/lib/api/cxapp/stacks.ts | 12 +- .../aws-cdk/lib/context-providers/index.ts | 7 +- packages/aws-cdk/test/api/test.stacks.ts | 9 +- packages/aws-cdk/test/util.ts | 9 +- 188 files changed, 532 insertions(+), 470 deletions(-) delete mode 100644 packages/@aws-cdk/cdk/lib/synthesis.ts diff --git a/packages/@aws-cdk/app-delivery/test/integ.cicd.ts b/packages/@aws-cdk/app-delivery/test/integ.cicd.ts index e0263b6c3633d..594e494eb03ef 100644 --- a/packages/@aws-cdk/app-delivery/test/integ.cicd.ts +++ b/packages/@aws-cdk/app-delivery/test/integ.cicd.ts @@ -38,4 +38,4 @@ new cicd.PipelineDeployStackAction(stack, 'DeployStack', { capabilities: cfn.CloudFormationCapabilities.None, }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/assert/lib/synth-utils.ts b/packages/@aws-cdk/assert/lib/synth-utils.ts index f8575848ce53a..37a7a2818e841 100644 --- a/packages/@aws-cdk/assert/lib/synth-utils.ts +++ b/packages/@aws-cdk/assert/lib/synth-utils.ts @@ -1,4 +1,4 @@ -import { Stack, SynthesisOptions, Synthesizer } from '@aws-cdk/cdk'; +import { ConstructNode, Stack, SynthesisOptions } from '@aws-cdk/cdk'; import cxapi = require('@aws-cdk/cx-api'); export class SynthUtils { @@ -7,8 +7,8 @@ export class SynthUtils { */ public static synthesize(stack: Stack, options: SynthesisOptions = { }): cxapi.CloudFormationStackArtifact { // always synthesize against the root (be it an App or whatever) so all artifacts will be included - const synth = new Synthesizer(); - const assembly = synth.synthesize(stack.node.root, options); + const root = stack.node.root; + const assembly = ConstructNode.synth(root.node, options); return assembly.getStack(stack.name); } diff --git a/packages/@aws-cdk/assert/test/test.assertions.ts b/packages/@aws-cdk/assert/test/test.assertions.ts index 755cf07b912fe..168dd6c6a56f6 100644 --- a/packages/@aws-cdk/assert/test/test.assertions.ts +++ b/packages/@aws-cdk/assert/test/test.assertions.ts @@ -209,7 +209,7 @@ function synthesizedStack(fn: (stack: cdk.Stack) => void): cx.CloudFormationStac const stack = new cdk.Stack(app, 'TestStack'); fn(stack); - const assembly = app.run(); + const assembly = app.synth(); return assembly.getStack(stack.name); } diff --git a/packages/@aws-cdk/assets-docker/test/integ.assets-docker.ts b/packages/@aws-cdk/assets-docker/test/integ.assets-docker.ts index 91fe6afbd384c..667d4c3bedcd6 100644 --- a/packages/@aws-cdk/assets-docker/test/integ.assets-docker.ts +++ b/packages/@aws-cdk/assets-docker/test/integ.assets-docker.ts @@ -12,4 +12,4 @@ const asset = new assets.DockerImageAsset(stack, 'DockerImage', { new cdk.CfnOutput(stack, 'ArtifactHash', { value: asset.artifactHash }); new cdk.CfnOutput(stack, 'ImageUri', { value: asset.imageUri }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/assets-docker/test/test.image-asset.ts b/packages/@aws-cdk/assets-docker/test/test.image-asset.ts index e77a9fc1083c9..53fad403b0b2a 100644 --- a/packages/@aws-cdk/assets-docker/test/test.image-asset.ts +++ b/packages/@aws-cdk/assets-docker/test/test.image-asset.ts @@ -172,7 +172,7 @@ export = { directory: path.join(__dirname, 'demo-image') }); - const session = app.run(); + const session = app.synth(); test.ok(fs.existsSync(path.join(session.directory, 'asset.1a17a141505ac69144931fe263d130f4612251caa4bbbdaf68a44ed0f405439c/Dockerfile'))); test.ok(fs.existsSync(path.join(session.directory, 'asset.1a17a141505ac69144931fe263d130f4612251caa4bbbdaf68a44ed0f405439c/index.py'))); diff --git a/packages/@aws-cdk/assets/lib/staging.ts b/packages/@aws-cdk/assets/lib/staging.ts index f630c1e0772b6..a851bc02f0026 100644 --- a/packages/@aws-cdk/assets/lib/staging.ts +++ b/packages/@aws-cdk/assets/lib/staging.ts @@ -1,4 +1,4 @@ -import { Construct, ISynthesisSession, ISynthesizable } from '@aws-cdk/cdk'; +import { Construct, ISynthesisSession } from '@aws-cdk/cdk'; import cxapi = require('@aws-cdk/cx-api'); import fs = require('fs'); import path = require('path'); @@ -26,7 +26,7 @@ export interface StagingProps extends CopyOptions { * The file/directory are staged based on their content hash (fingerprint). This * means that only if content was changed, copy will happen. */ -export class Staging extends Construct implements ISynthesizable { +export class Staging extends Construct { /** * The path to the asset (stringinfied token). diff --git a/packages/@aws-cdk/assets/test/integ.assets.directory.lit.ts b/packages/@aws-cdk/assets/test/integ.assets.directory.lit.ts index c40a17e30852c..38d070cc46110 100644 --- a/packages/@aws-cdk/assets/test/integ.assets.directory.lit.ts +++ b/packages/@aws-cdk/assets/test/integ.assets.directory.lit.ts @@ -20,4 +20,4 @@ class TestStack extends cdk.Stack { const app = new cdk.App(); new TestStack(app, 'aws-cdk-asset-test'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/assets/test/integ.assets.file.lit.ts b/packages/@aws-cdk/assets/test/integ.assets.file.lit.ts index 2e404ae70612c..f9d230c6878b9 100644 --- a/packages/@aws-cdk/assets/test/integ.assets.file.lit.ts +++ b/packages/@aws-cdk/assets/test/integ.assets.file.lit.ts @@ -20,4 +20,4 @@ class TestStack extends cdk.Stack { const app = new cdk.App(); new TestStack(app, 'aws-cdk-asset-file-test'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/assets/test/integ.assets.permissions.lit.ts b/packages/@aws-cdk/assets/test/integ.assets.permissions.lit.ts index b42dfc87c4e98..276dfe61f20f4 100644 --- a/packages/@aws-cdk/assets/test/integ.assets.permissions.lit.ts +++ b/packages/@aws-cdk/assets/test/integ.assets.permissions.lit.ts @@ -20,4 +20,4 @@ class TestStack extends cdk.Stack { const app = new cdk.App(); new TestStack(app, 'aws-cdk-asset-refs'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/assets/test/integ.assets.refs.lit.ts b/packages/@aws-cdk/assets/test/integ.assets.refs.lit.ts index ec7bb79953163..cbeaf595754e2 100644 --- a/packages/@aws-cdk/assets/test/integ.assets.refs.lit.ts +++ b/packages/@aws-cdk/assets/test/integ.assets.refs.lit.ts @@ -24,4 +24,4 @@ class TestStack extends cdk.Stack { const app = new cdk.App(); new TestStack(app, 'aws-cdk-asset-refs'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/assets/test/integ.multi-assets.ts b/packages/@aws-cdk/assets/test/integ.multi-assets.ts index e18a0cd48e660..214a593700642 100644 --- a/packages/@aws-cdk/assets/test/integ.multi-assets.ts +++ b/packages/@aws-cdk/assets/test/integ.multi-assets.ts @@ -24,4 +24,4 @@ class TestStack extends cdk.Stack { const app = new cdk.App(); new TestStack(app, 'aws-cdk-multi-assets'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/assets/test/test.asset.ts b/packages/@aws-cdk/assets/test/test.asset.ts index d752c56b5a735..72100dc0bbad8 100644 --- a/packages/@aws-cdk/assets/test/test.asset.ts +++ b/packages/@aws-cdk/assets/test/test.asset.ts @@ -29,7 +29,7 @@ export = { test.ok(entry, 'found metadata entry'); // verify that now the template contains parameters for this asset - const session = app.run(); + const session = app.synth(); test.deepEqual(stack.node.resolve(entry!.data), { path: SAMPLE_ASSET_DIR, @@ -57,7 +57,7 @@ export = { path: dirPath }); - const synth = app.run().getStack(stack.name); + const synth = app.synth().getStack(stack.name); const meta = synth.manifest.metadata || {}; test.deepEqual(meta['/my-stack/MyAsset'][0].data, { path: 'asset.6b84b87243a4a01c592d78e1fd3855c4bfef39328cd0a450cc97e81717fea2a2', @@ -249,7 +249,7 @@ export = { }); // THEN - app.run(); + app.synth(); test.ok(fs.existsSync(tempdir)); test.ok(fs.existsSync(path.join(tempdir, 'asset.a7a79cdf84b802ea8b198059ff899cffc095a1b9606e919f98e05bf80779756b.zip'))); test.done(); @@ -269,7 +269,7 @@ export = { }); // THEN - app.run(); + app.synth(); test.ok(fs.existsSync(tempdir)); const hash = 'asset.6b84b87243a4a01c592d78e1fd3855c4bfef39328cd0a450cc97e81717fea2a2'; test.ok(fs.existsSync(path.join(tempdir, hash, 'sample-asset-file.txt'))); @@ -341,7 +341,7 @@ export = { new ZipDirectoryAsset(stack, 'MyAsset', { path: SAMPLE_ASSET_DIR }); // WHEN - const session = app.run(); + const session = app.synth(); const artifact = session.getStack(stack.name); const md = Object.values(artifact.manifest.metadata || {})[0][0].data; diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.ts b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.ts index 93c6ca50713c0..3a7b951c31e96 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.ts +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.ts @@ -69,4 +69,4 @@ function helloCode(_event: any, _context: any, callback: any) { }); } -new BookApp().run(); +new BookApp().synth(); diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.defaults.ts b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.defaults.ts index da9b1d89c2eba..03ffbe7cd9b8b 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.defaults.ts +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.defaults.ts @@ -10,4 +10,4 @@ const api = new apigateway.RestApi(stack, 'my-api'); // at least one method is required api.root.addMethod('GET'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.ts b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.ts index 57562329ebc98..2e40a9c82add2 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.ts +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.ts @@ -82,4 +82,4 @@ const app = new cdk.App(); new Test(app, 'test-apigateway-restapi'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-apigateway/test/test.restapi.ts b/packages/@aws-cdk/aws-apigateway/test/test.restapi.ts index 31b1714e697b2..ef30cbbdc93c0 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.restapi.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.restapi.ts @@ -131,7 +131,7 @@ export = { api.root.addResource('bar').addResource('goo'); // THEN - test.throws(() => app.run(), /The REST API doesn't contain any methods/); + test.throws(() => app.synth(), /The REST API doesn't contain any methods/); test.done(); }, diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.ts b/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.ts index 2b392e6972482..d812205407785 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.amazonlinux2.ts @@ -16,4 +16,4 @@ new autoscaling.AutoScalingGroup(stack, 'Fleet', { machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AmazonLinux2 }), }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-classic-loadbalancer.ts b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-classic-loadbalancer.ts index 85d5210e197dd..458f420512b2e 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-classic-loadbalancer.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-classic-loadbalancer.ts @@ -28,4 +28,4 @@ const lb = new elb.LoadBalancer(stack, 'LB', { lb.addTarget(asg); lb.addListener({ externalPort: 80 }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.ts b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.ts index b5baca4dfa4b0..e9e30f9712e3e 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.asg-w-elbv2.ts @@ -37,4 +37,4 @@ asg.scaleOnRequestCount('AModestLoad', { targetRequestsPerSecond: 1 }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.custom-scaling.ts b/packages/@aws-cdk/aws-autoscaling/test/integ.custom-scaling.ts index aaa40c64d2c3c..ab7d14ef6cdc0 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.custom-scaling.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.custom-scaling.ts @@ -30,4 +30,4 @@ asg.scaleOnCpuUtilization('KeepCPUReasonable', { targetUtilizationPercent: 50 }); -app.run(); \ No newline at end of file +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.external-role.ts b/packages/@aws-cdk/aws-autoscaling/test/integ.external-role.ts index 30a695e896203..25748bd083fd0 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.external-role.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.external-role.ts @@ -25,4 +25,4 @@ const app = new cdk.App(); new TestStack(app, 'integ-iam-external-role'); -app.run(); \ No newline at end of file +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-autoscaling/test/integ.spot-instances.ts b/packages/@aws-cdk/aws-autoscaling/test/integ.spot-instances.ts index 8b9875a4cadc5..e57731e277472 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/integ.spot-instances.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/integ.spot-instances.ts @@ -17,4 +17,4 @@ new autoscaling.AutoScalingGroup(stack, 'Fleet', { spotPrice: '0.20' }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.aws-custom-resource.ts b/packages/@aws-cdk/aws-cloudformation/test/integ.aws-custom-resource.ts index 92d707ebc1ea6..68afd7bf24081 100644 --- a/packages/@aws-cdk/aws-cloudformation/test/integ.aws-custom-resource.ts +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.aws-custom-resource.ts @@ -45,4 +45,4 @@ new cdk.CfnOutput(stack, 'MessageId', { value: snsPublish.getData('MessageId') } new cdk.CfnOutput(stack, 'TopicArn', { value: listTopics.getData('Topics.0.TopicArn') }); new cdk.CfnOutput(stack, 'ParameterValue', { value: getParameter.getData('Parameter.Value') }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-cloudformation/test/integ.trivial-lambda-resource.ts b/packages/@aws-cdk/aws-cloudformation/test/integ.trivial-lambda-resource.ts index 8fa9c26f171c0..acc41d471a5b7 100644 --- a/packages/@aws-cdk/aws-cloudformation/test/integ.trivial-lambda-resource.ts +++ b/packages/@aws-cdk/aws-cloudformation/test/integ.trivial-lambda-resource.ts @@ -59,4 +59,4 @@ const app = new cdk.App(); new SucceedingStack(app, 'SucceedingStack'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-bucket-logging.ts b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-bucket-logging.ts index 6653e7dd402a2..02404fe3cf435 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-bucket-logging.ts +++ b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-bucket-logging.ts @@ -52,4 +52,4 @@ new cloudfront.CloudFrontWebDistribution(stack, 'AnAmazingWebsiteProbably2', { loggingConfig: {} }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-custom.ts b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-custom.ts index 5a8e4b636738b..774a26d394f9a 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-custom.ts +++ b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-custom.ts @@ -24,4 +24,4 @@ new cloudfront.CloudFrontWebDistribution(stack, 'AnAmazingWebsiteProbably', { ] }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-empty-root.ts b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-empty-root.ts index 88addd15e43f1..5650e26bf402a 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-empty-root.ts +++ b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-empty-root.ts @@ -25,4 +25,4 @@ new cloudfront.CloudFrontWebDistribution(stack, 'AnAmazingWebsiteProbably', { defaultRootObject: '' }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-ipv6-disabled.ts b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-ipv6-disabled.ts index 3c21aa31dfa53..6f488abca5ea7 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-ipv6-disabled.ts +++ b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-ipv6-disabled.ts @@ -23,4 +23,4 @@ new cloudfront.CloudFrontWebDistribution(stack, 'MyDistribution', { enableIpV6: false }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-security-policy.ts b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-security-policy.ts index 5cf28d1164a3e..7857fe03c6cb4 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-security-policy.ts +++ b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront-security-policy.ts @@ -30,4 +30,4 @@ new cloudfront.CloudFrontWebDistribution(stack, 'AnAmazingWebsiteProbably', { } }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront.ts b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront.ts index 969565641784e..655600e34fb07 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront.ts +++ b/packages/@aws-cdk/aws-cloudfront/test/integ.cloudfront.ts @@ -22,4 +22,4 @@ new cloudfront.CloudFrontWebDistribution(stack, 'MyDistribution', { ] }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail.lit.ts b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail.lit.ts index ebc80d0fa5b71..0f87444828aba 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail.lit.ts +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail.lit.ts @@ -10,4 +10,4 @@ const bucket = new s3.Bucket(stack, 'Bucket', { removalPolicy: cdk.RemovalPolicy const trail = new cloudtrail.Trail(stack, 'Trail'); trail.addS3EventSelector([bucket.arnForObjects('')]); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.ts b/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.ts index 79b53ac3392e7..8f62afdb4bd9e 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.ts +++ b/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.ts @@ -50,4 +50,4 @@ dashboard.add(new cloudwatch.SingleValueWidget({ metrics: [metric] })); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codebuild/test/integ.caching.ts b/packages/@aws-cdk/aws-codebuild/test/integ.caching.ts index a381a88f36eb8..506db0bd746ec 100644 --- a/packages/@aws-cdk/aws-codebuild/test/integ.caching.ts +++ b/packages/@aws-cdk/aws-codebuild/test/integ.caching.ts @@ -24,4 +24,4 @@ new codebuild.Project(stack, 'MyProject', { } }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codebuild/test/integ.defaults.lit.ts b/packages/@aws-cdk/aws-codebuild/test/integ.defaults.lit.ts index 563213dcd7003..5ed599c0a6430 100644 --- a/packages/@aws-cdk/aws-codebuild/test/integ.defaults.lit.ts +++ b/packages/@aws-cdk/aws-codebuild/test/integ.defaults.lit.ts @@ -26,4 +26,4 @@ const app = new cdk.App(); new TestStack(app, 'codebuild-default-project'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codebuild/test/integ.docker-asset.lit.ts b/packages/@aws-cdk/aws-codebuild/test/integ.docker-asset.lit.ts index ad0f38b10e22e..a40a36d5b1bfc 100644 --- a/packages/@aws-cdk/aws-codebuild/test/integ.docker-asset.lit.ts +++ b/packages/@aws-cdk/aws-codebuild/test/integ.docker-asset.lit.ts @@ -30,4 +30,4 @@ const app = new cdk.App(); new TestStack(app, 'test-codebuild-docker-asset'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codebuild/test/integ.ecr.lit.ts b/packages/@aws-cdk/aws-codebuild/test/integ.ecr.lit.ts index 8d8105bbfb6e3..18fcca37d71f7 100644 --- a/packages/@aws-cdk/aws-codebuild/test/integ.ecr.lit.ts +++ b/packages/@aws-cdk/aws-codebuild/test/integ.ecr.lit.ts @@ -30,4 +30,4 @@ const app = new cdk.App(); new TestStack(app, 'test-codebuild-docker-asset'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codebuild/test/integ.github.ts b/packages/@aws-cdk/aws-codebuild/test/integ.github.ts index e9784a5d2c507..955f88bbf1a54 100644 --- a/packages/@aws-cdk/aws-codebuild/test/integ.github.ts +++ b/packages/@aws-cdk/aws-codebuild/test/integ.github.ts @@ -20,4 +20,4 @@ const app = new cdk.App(); new TestStack(app, 'test-codebuild-github'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codebuild/test/integ.project-bucket.ts b/packages/@aws-cdk/aws-codebuild/test/integ.project-bucket.ts index 196c1257bccc2..93383eb9eef38 100644 --- a/packages/@aws-cdk/aws-codebuild/test/integ.project-bucket.ts +++ b/packages/@aws-cdk/aws-codebuild/test/integ.project-bucket.ts @@ -21,4 +21,4 @@ new codebuild.Project(stack, 'MyProject', { } }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codebuild/test/integ.project-secondary-sources-artifacts.ts b/packages/@aws-cdk/aws-codebuild/test/integ.project-secondary-sources-artifacts.ts index 6e8767a17021b..ab78972787c82 100644 --- a/packages/@aws-cdk/aws-codebuild/test/integ.project-secondary-sources-artifacts.ts +++ b/packages/@aws-cdk/aws-codebuild/test/integ.project-secondary-sources-artifacts.ts @@ -31,4 +31,4 @@ new codebuild.Project(stack, 'MyProject', { ], }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codebuild/test/integ.project-shell.ts b/packages/@aws-cdk/aws-codebuild/test/integ.project-shell.ts index db8a43325917d..1f00f2953829a 100644 --- a/packages/@aws-cdk/aws-codebuild/test/integ.project-shell.ts +++ b/packages/@aws-cdk/aws-codebuild/test/integ.project-shell.ts @@ -11,4 +11,4 @@ new Project(stack, 'MyProject', { buildScriptAsset: new assets.ZipDirectoryAsset(stack, 'Bundle', { path: 'script_bundle' }) }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codebuild/test/integ.project-vpc.ts b/packages/@aws-cdk/aws-codebuild/test/integ.project-vpc.ts index d941f885aee82..9d118d04ed81b 100644 --- a/packages/@aws-cdk/aws-codebuild/test/integ.project-vpc.ts +++ b/packages/@aws-cdk/aws-codebuild/test/integ.project-vpc.ts @@ -23,4 +23,4 @@ new Project(stack, 'MyProject', { vpc }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codecommit/test/integ.codecommit-events.ts b/packages/@aws-cdk/aws-codecommit/test/integ.codecommit-events.ts index 654dde70c1684..9e576c0f6a36a 100644 --- a/packages/@aws-cdk/aws-codecommit/test/integ.codecommit-events.ts +++ b/packages/@aws-cdk/aws-codecommit/test/integ.codecommit-events.ts @@ -19,4 +19,4 @@ repo.onReferenceCreated('OnReferenceCreated', { } }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codedeploy/test/lambda/integ.deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/test/lambda/integ.deployment-group.ts index 1090f9f8501a7..100da59cc5957 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/lambda/integ.deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/lambda/integ.deployment-group.ts @@ -45,4 +45,4 @@ new codedeploy.LambdaDeploymentGroup(stack, 'BlueGreenDeployment', { postHook }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codedeploy/test/server/integ.deployment-group.ts b/packages/@aws-cdk/aws-codedeploy/test/server/integ.deployment-group.ts index 449057cba245f..ebda4e4675cb7 100644 --- a/packages/@aws-cdk/aws-codedeploy/test/server/integ.deployment-group.ts +++ b/packages/@aws-cdk/aws-codedeploy/test/server/integ.deployment-group.ts @@ -42,4 +42,4 @@ new codedeploy.ServerDeploymentGroup(stack, 'CodeDeployGroup', { }, }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.ts index d6353d859c165..fc9b186042021 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.cfn-template-from-repo.lit.ts @@ -59,4 +59,4 @@ new codepipeline.Pipeline(stack, 'Pipeline', { }); /// !hide -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-pipeline.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-pipeline.ts index 53a549106db6b..d4b12653a69b2 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-pipeline.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-pipeline.ts @@ -42,4 +42,4 @@ lambdaStage.addAction(new cpactions.LambdaInvokeAction({ lambda: lambdaFun, })); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-alexa-deploy.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-alexa-deploy.ts index bfca75294541e..2070499dc672f 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-alexa-deploy.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-alexa-deploy.ts @@ -45,4 +45,4 @@ new codepipeline.Pipeline(stack, 'Pipeline', { ], }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-cross-region.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-cross-region.ts index d2c732fd5dbb4..7c29963c50039 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-cross-region.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-cross-region.ts @@ -47,4 +47,4 @@ new codepipeline.Pipeline(stack, 'MyPipeline', { ], }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-wtih-action-role.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-wtih-action-role.ts index fcd1ea207f0ee..56cdf3ba9130e 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-wtih-action-role.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn-wtih-action-role.ts @@ -57,4 +57,4 @@ pipeline.addToRolePolicy(new iam.PolicyStatement() .addAllResources() ); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn.ts index d4dc7d8ba41d8..6810fbbffc99b 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-cfn.ts @@ -65,4 +65,4 @@ pipeline.addStage({ ], }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.ts index b274dddbcf260..697c2a118832a 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-build-multiple-inputs-outputs.ts @@ -75,4 +75,4 @@ pipeline.addStage({ ], }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.ts index 05c8462fcc7e3..684adf25b73f1 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-commit-build.ts @@ -50,4 +50,4 @@ new codepipeline.Pipeline(stack, 'Pipeline', { ], }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-commit.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-commit.ts index deee3932e021a..33cb7a4326848 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-commit.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-commit.ts @@ -30,4 +30,4 @@ new codepipeline.Pipeline(stack, 'Pipeline', { ], }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-deploy.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-deploy.ts index 9ffd1d43a3d9c..7dc68544e5c69 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-deploy.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-code-deploy.ts @@ -48,4 +48,4 @@ deployStage.addAction(new cpactions.CodeDeployServerDeployAction({ input: sourceOutput, })); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecr-source.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecr-source.ts index d79e8c01aa752..93c78ad25cfa7 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecr-source.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecr-source.ts @@ -26,4 +26,4 @@ sourceStage.addAction(new cpactions.EcrSourceAction({ const approveStage = pipeline.addStage({ name: 'Approve' }); approveStage.addAction(new cpactions.ManualApprovalAction({ actionName: 'ManualApproval' })); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecs-deploy.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecs-deploy.ts index a33ee05eaee79..0dd51f1c806a1 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecs-deploy.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-ecs-deploy.ts @@ -107,4 +107,4 @@ new codepipeline.Pipeline(stack, 'MyPipeline', { ], }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-events.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-events.ts index 30b2ce6cb3b33..2b4ad4118d0f5 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-events.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-events.ts @@ -60,4 +60,4 @@ sourceAction.onStateChange('OnActionStateChange', new targets.SnsTopic(topic)).a detail: { state: [ 'STARTED' ] } }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-jenkins.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-jenkins.ts index a6ebbea5628e0..c5e5bafab7058 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-jenkins.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-jenkins.ts @@ -61,4 +61,4 @@ pipeline.addStage({ ], }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-manual-approval.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-manual-approval.ts index c3016ceb68738..146c3b215438c 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-manual-approval.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-manual-approval.ts @@ -35,4 +35,4 @@ new codepipeline.Pipeline(stack, 'Pipeline', { ], }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-s3-deploy.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-s3-deploy.ts index 6e71aa1562fd0..60175d7d456e2 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-s3-deploy.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.pipeline-s3-deploy.ts @@ -40,4 +40,4 @@ new codepipeline.Pipeline(stack, 'Pipeline', { ], }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-config/test/integ.rule.lit.ts b/packages/@aws-cdk/aws-config/test/integ.rule.lit.ts index 0dc7480879ee0..59117767f4ea8 100644 --- a/packages/@aws-cdk/aws-config/test/integ.rule.lit.ts +++ b/packages/@aws-cdk/aws-config/test/integ.rule.lit.ts @@ -40,4 +40,4 @@ class ConfigStack extends cdk.Stack { } new ConfigStack(app, 'aws-cdk-config-rule-integ'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-dynamodb-global/README.md b/packages/@aws-cdk/aws-dynamodb-global/README.md index 3190adaf2ecf1..a13ea69802b26 100644 --- a/packages/@aws-cdk/aws-dynamodb-global/README.md +++ b/packages/@aws-cdk/aws-dynamodb-global/README.md @@ -15,7 +15,7 @@ new GlobalTable(app, 'globdynamodb', { tableName: 'GlobalTable', regions: [ "us-east-1", "us-east-2", "us-west-2" ] }); -app.run(); +app.synth(); ``` ## Implementation Notes diff --git a/packages/@aws-cdk/aws-dynamodb-global/test/integ.dynamodb.global.ts b/packages/@aws-cdk/aws-dynamodb-global/test/integ.dynamodb.global.ts index f557f6e6c1077..7497b17245e78 100644 --- a/packages/@aws-cdk/aws-dynamodb-global/test/integ.dynamodb.global.ts +++ b/packages/@aws-cdk/aws-dynamodb-global/test/integ.dynamodb.global.ts @@ -8,4 +8,4 @@ new GlobalTable(app, 'globdynamodbinteg', { tableName: 'integrationtest', regions: [ "us-east-1", "us-east-2", "us-west-2" ] }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.autoscaling.lit.ts b/packages/@aws-cdk/aws-dynamodb/test/integ.autoscaling.lit.ts index 2fdd3915057c5..b7f4fae16e119 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.autoscaling.lit.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.autoscaling.lit.ts @@ -27,4 +27,4 @@ readScaling.scaleOnSchedule('ScaleDownAtNight', { }); /// !hide -app.run(); \ No newline at end of file +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ondemand.ts b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ondemand.ts index 3eabf76ffd2b3..9341d2a7968ce 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ondemand.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ondemand.ts @@ -126,4 +126,4 @@ tableWithLocalSecondaryIndex.addLocalSecondaryIndex({ sortKey: LSI_SORT_KEY }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts index 0152f631e7feb..3e6cadf15ea92 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts @@ -127,4 +127,4 @@ const user = new iam.User(stack, 'User'); table.grantReadData(user); tableWithGlobalAndLocalSecondaryIndex.grantReadData(user); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-ec2/lib/security-group.ts b/packages/@aws-cdk/aws-ec2/lib/security-group.ts index 0a5ea2ce16fd5..4ff6120715b49 100644 --- a/packages/@aws-cdk/aws-ec2/lib/security-group.ts +++ b/packages/@aws-cdk/aws-ec2/lib/security-group.ts @@ -4,7 +4,7 @@ import { CfnSecurityGroup, CfnSecurityGroupEgress, CfnSecurityGroupIngress } fro import { IPortRange, ISecurityGroupRule } from './security-group-rule'; import { IVpc } from './vpc'; -const isSecurityGroupSymbol = Symbol.for('aws-cdk:isSecurityGroup'); +const SECURITY_GROUP_SYMBOL = Symbol.for('aws-cdk:isSecurityGroup'); export interface ISecurityGroup extends IResource, ISecurityGroupRule, IConnectable { /** @@ -43,8 +43,8 @@ abstract class SecurityGroupBase extends Resource implements ISecurityGroup { /** * Return whether the indicated object is a security group */ - public static isSecurityGroup(construct: any): construct is SecurityGroupBase { - return (construct as any)[isSecurityGroupSymbol] === true; + public static isSecurityGroup(x: any): x is SecurityGroupBase { + return SECURITY_GROUP_SYMBOL in x; } public abstract readonly securityGroupId: string; @@ -60,7 +60,7 @@ abstract class SecurityGroupBase extends Resource implements ISecurityGroup { constructor(scope: Construct, id: string) { super(scope, id); - Object.defineProperty(this, isSecurityGroupSymbol, { value: true }); + Object.defineProperty(this, SECURITY_GROUP_SYMBOL, { value: true }); } public get uniqueId() { diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc.ts b/packages/@aws-cdk/aws-ec2/lib/vpc.ts index 4d070293caff2..f1b6af01bcac8 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc.ts @@ -9,6 +9,8 @@ import { InterfaceVpcEndpoint, InterfaceVpcEndpointOptions } from './vpc-endpoin import { VpcLookupOptions, VpcNetworkProvider } from './vpc-network-provider'; import { VpnConnection, VpnConnectionOptions, VpnConnectionType } from './vpn'; +const VPC_SUBNET_SYMBOL = Symbol.for('@aws-cdk/aws-ec2.VpcSubnet'); + export interface ISubnet extends IResource { /** * The Availability Zone the subnet is located in @@ -1047,8 +1049,6 @@ export interface SubnetProps { readonly mapPublicIpOnLaunch?: boolean; } -const IS_VPC_SUBNET = Symbol.for('@aws-cdk/aws-ec2.VpcSubnet'); - /** * Represents a new VPC subnet resource * @@ -1056,8 +1056,8 @@ const IS_VPC_SUBNET = Symbol.for('@aws-cdk/aws-ec2.VpcSubnet'); */ export class Subnet extends cdk.Resource implements ISubnet { - public static isVpcSubnet(o: any): o is Subnet { - return IS_VPC_SUBNET in o; + public static isVpcSubnet(x: any): x is Subnet { + return VPC_SUBNET_SYMBOL in x; } public static fromSubnetAttributes(scope: cdk.Construct, id: string, attrs: SubnetAttributes): ISubnet { @@ -1109,7 +1109,7 @@ export class Subnet extends cdk.Resource implements ISubnet { constructor(scope: cdk.Construct, id: string, props: SubnetProps) { super(scope, id); - Object.defineProperty(this, IS_VPC_SUBNET, { value: true }); + Object.defineProperty(this, VPC_SUBNET_SYMBOL, { value: true }); this.node.apply(new cdk.Tag(NAME_TAG, this.node.path)); diff --git a/packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts b/packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts index 4448cabe06e63..5f6b11de067c7 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts @@ -21,4 +21,4 @@ new ec2.SecurityGroup(stack, 'SecurityGroup', { new cdk.CfnOutput(stack, 'PublicSubnets', { value: 'ids:' + vpc.publicSubnets.map(s => s.subnetId).join(',') }); new cdk.CfnOutput(stack, 'PrivateSubnets', { value: 'ids:' + vpc.privateSubnets.map(s => s.subnetId).join(',') }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-ec2/test/integ.share-vpcs.lit.ts b/packages/@aws-cdk/aws-ec2/test/integ.share-vpcs.lit.ts index c41c7c576493c..f8372de4cacaf 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.share-vpcs.lit.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.share-vpcs.lit.ts @@ -53,4 +53,4 @@ const stack2 = new Stack2(app, 'Stack2', { Array.isArray(stack2); -app.run(); \ No newline at end of file +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint.lit.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint.lit.ts index 0de5e4720fe57..b558dfce5bd64 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint.lit.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc-endpoint.lit.ts @@ -44,4 +44,4 @@ class VpcEndpointStack extends cdk.Stack { } new VpcEndpointStack(app, 'aws-cdk-ec2-vpc-endpoint'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpc.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpc.ts index 103fadda5ae64..b10c05f6ac4a9 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpc.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpc.ts @@ -22,4 +22,4 @@ for (const rule of rules) { sg.addIngressRule(new ec2.AnyIPv4(), rule); } -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-ec2/test/integ.vpn.ts b/packages/@aws-cdk/aws-ec2/test/integ.vpn.ts index dd1bd34526fc0..88b750521fd28 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.vpn.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.vpn.ts @@ -26,4 +26,4 @@ vpc.addVpnConnection('Static', { // Static routing ] }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-ecr/test/integ.basic.ts b/packages/@aws-cdk/aws-ecr/test/integ.basic.ts index deb72bdcf5887..d913cb77d323e 100644 --- a/packages/@aws-cdk/aws-ecr/test/integ.basic.ts +++ b/packages/@aws-cdk/aws-ecr/test/integ.basic.ts @@ -11,4 +11,4 @@ new cdk.CfnOutput(stack, 'RepositoryURI', { value: repo.repositoryUri }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/ec2/integ.scheduled-ecs-task.lit.ts b/packages/@aws-cdk/aws-ecs-patterns/test/ec2/integ.scheduled-ecs-task.lit.ts index 16c7a3ea0c639..91e8777fce627 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/ec2/integ.scheduled-ecs-task.lit.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/test/ec2/integ.scheduled-ecs-task.lit.ts @@ -33,4 +33,4 @@ class EventStack extends cdk.Stack { } new EventStack(app, 'aws-ecs-integ-ecs'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.asset-image.ts b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.asset-image.ts index d370f0cb4c2df..3e1f7ab5b35c5 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.asset-image.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.asset-image.ts @@ -25,4 +25,4 @@ const fargateService = new ecsPatterns.LoadBalancedFargateService(stack, "Fargat // CfnOutput the DNS where you can access your service new cdk.CfnOutput(stack, 'LoadBalancerDNS', { value: fargateService.loadBalancer.loadBalancerDnsName }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3.ts b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3.ts index 223b55621cd22..7bb538c4a09fb 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3.ts @@ -17,4 +17,4 @@ new ecsPatterns.LoadBalancedFargateService(stack, 'L3', { image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.ts b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.ts index 7b6508d8a3eae..c4dbf378c848f 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.ts +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-awsvpc-nw.ts @@ -42,4 +42,4 @@ listener.addTargets('ECS', { new cdk.CfnOutput(stack, 'LoadBalancerDNS', { value: lb.loadBalancerDnsName, }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.ts b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.ts index edc41d6893259..c09cf9f14f1ee 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.ts +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.lb-bridge-nw.ts @@ -44,4 +44,4 @@ listener.addTargets('ECS', { new cdk.CfnOutput(stack, 'LoadBalancerDNS', { value: lb.loadBalancerDnsName, }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-awsvpc-nw.ts b/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-awsvpc-nw.ts index 33248c93ef306..410e72a4d2dfa 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-awsvpc-nw.ts +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-awsvpc-nw.ts @@ -44,4 +44,4 @@ new ecs.Ec2Service(stack, "FrontendService", { } }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-bridge-nw.ts b/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-bridge-nw.ts index 3845637bbdca3..63aec63f1f896 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-bridge-nw.ts +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-bridge-nw.ts @@ -42,4 +42,4 @@ new ecs.Ec2Service(stack, "FrontendService", { } }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-ecs/test/fargate/integ.lb-awsvpc-nw.ts b/packages/@aws-cdk/aws-ecs/test/fargate/integ.lb-awsvpc-nw.ts index cbdd41cd40a04..43d9c3edcb968 100644 --- a/packages/@aws-cdk/aws-ecs/test/fargate/integ.lb-awsvpc-nw.ts +++ b/packages/@aws-cdk/aws-ecs/test/fargate/integ.lb-awsvpc-nw.ts @@ -42,4 +42,4 @@ listener.addTargets('Fargate', { new cdk.CfnOutput(stack, 'LoadBalancerDNS', { value: lb.loadBalancerDnsName, }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-eks/test/example.ssh-into-nodes.lit.ts b/packages/@aws-cdk/aws-eks/test/example.ssh-into-nodes.lit.ts index d0ff91ed29e01..5d3c275b9e88b 100644 --- a/packages/@aws-cdk/aws-eks/test/example.ssh-into-nodes.lit.ts +++ b/packages/@aws-cdk/aws-eks/test/example.ssh-into-nodes.lit.ts @@ -29,4 +29,4 @@ const app = new cdk.App(); new EksClusterStack(app, 'eks-integ-test'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.lit.ts b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.lit.ts index 0c33f9e28544b..aabdb7a5ffd19 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.lit.ts +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.lit.ts @@ -25,4 +25,4 @@ const app = new cdk.App(); new EksClusterStack(app, 'eks-integ-test'); -app.run(); \ No newline at end of file +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.ts b/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.ts index 04496c4f351e5..6c09efc21375b 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancing/test/integ.elb.ts @@ -23,4 +23,4 @@ new elb.LoadBalancer(stack, 'LB', { targets: [] }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.ts index e02fa524a5bdc..db93b586f3d57 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.alb.ts @@ -41,4 +41,4 @@ group2.metricTargetResponseTime().newAlarm(stack, 'ResponseTimeHigh2', { evaluationPeriods: 2, }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.nlb.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.nlb.ts index d55917a2275a4..ddb45ba047259 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.nlb.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/integ.nlb.ts @@ -28,4 +28,4 @@ group.node.addDependency(...vpc.internetDependencies); // The target's security group must allow being routed by the LB and the clients. -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-events-targets/test/codebuild/integ.project-events.ts b/packages/@aws-cdk/aws-events-targets/test/codebuild/integ.project-events.ts index 06b0231f42b6e..4aca4a5d1a73a 100644 --- a/packages/@aws-cdk/aws-events-targets/test/codebuild/integ.project-events.ts +++ b/packages/@aws-cdk/aws-events-targets/test/codebuild/integ.project-events.ts @@ -46,4 +46,4 @@ onCommitRule.addTarget(new targets.SnsTopic(topic, { ) })); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-events-targets/test/codepipeline/integ.pipeline-event-target.ts b/packages/@aws-cdk/aws-events-targets/test/codepipeline/integ.pipeline-event-target.ts index 36c15e999eedf..8ba9c871fccf5 100644 --- a/packages/@aws-cdk/aws-events-targets/test/codepipeline/integ.pipeline-event-target.ts +++ b/packages/@aws-cdk/aws-events-targets/test/codepipeline/integ.pipeline-event-target.ts @@ -47,4 +47,4 @@ new events.Rule(stack, 'rule', { targets: [new targets.CodePipeline(pipeline)] }); -app.run(); \ No newline at end of file +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-events-targets/test/ecs/integ.event-ec2-task.lit.ts b/packages/@aws-cdk/aws-events-targets/test/ecs/integ.event-ec2-task.lit.ts index ab9499e8abbdc..9b5ee8fccfbff 100644 --- a/packages/@aws-cdk/aws-events-targets/test/ecs/integ.event-ec2-task.lit.ts +++ b/packages/@aws-cdk/aws-events-targets/test/ecs/integ.event-ec2-task.lit.ts @@ -52,4 +52,4 @@ class EventStack extends cdk.Stack { } new EventStack(app, 'aws-ecs-integ-ecs'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-events-targets/test/ecs/integ.event-fargate-task.ts b/packages/@aws-cdk/aws-events-targets/test/ecs/integ.event-fargate-task.ts index 730e134e53e18..8c286054620e1 100644 --- a/packages/@aws-cdk/aws-events-targets/test/ecs/integ.event-fargate-task.ts +++ b/packages/@aws-cdk/aws-events-targets/test/ecs/integ.event-fargate-task.ts @@ -48,4 +48,4 @@ class EventStack extends cdk.Stack { } new EventStack(app, 'aws-ecs-integ-fargate'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-events-targets/test/lambda/integ.events.ts b/packages/@aws-cdk/aws-events-targets/test/lambda/integ.events.ts index 28794ae97cc24..b733892b0e8e1 100644 --- a/packages/@aws-cdk/aws-events-targets/test/lambda/integ.events.ts +++ b/packages/@aws-cdk/aws-events-targets/test/lambda/integ.events.ts @@ -19,7 +19,7 @@ timer.addTarget(new targets.LambdaFunction(fn)); const timer2 = new events.Rule(stack, 'Timer2', { scheduleExpression: 'rate(2 minutes)' }); timer2.addTarget(new targets.LambdaFunction(fn)); -app.run(); +app.synth(); // tslint:disable:no-console function handler(event: any, _context: any, callback: any) { diff --git a/packages/@aws-cdk/aws-events-targets/test/sns/integ.sns-event-rule-target.ts b/packages/@aws-cdk/aws-events-targets/test/sns/integ.sns-event-rule-target.ts index 81fe6e95c5a48..f33fe16ab064d 100644 --- a/packages/@aws-cdk/aws-events-targets/test/sns/integ.sns-event-rule-target.ts +++ b/packages/@aws-cdk/aws-events-targets/test/sns/integ.sns-event-rule-target.ts @@ -23,4 +23,4 @@ topic.subscribeQueue(queue); event.addTarget(new targets.SnsTopic(topic)); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-events/lib/input.ts b/packages/@aws-cdk/aws-events/lib/input.ts index b3ed4dddb7020..077b9892bde15 100644 --- a/packages/@aws-cdk/aws-events/lib/input.ts +++ b/packages/@aws-cdk/aws-events/lib/input.ts @@ -284,7 +284,7 @@ enum InputType { } function isEventField(x: any): x is EventField { - return typeof x === 'object' && x !== null && x[EVENT_FIELD_SYMBOL]; + return EVENT_FIELD_SYMBOL in x; } const EVENT_FIELD_SYMBOL = Symbol.for('@aws-cdk/aws-events.EventField'); diff --git a/packages/@aws-cdk/aws-events/test/test.rule.ts b/packages/@aws-cdk/aws-events/test/test.rule.ts index a03ec7c1ab1ba..8c4a4351b9bc8 100644 --- a/packages/@aws-cdk/aws-events/test/test.rule.ts +++ b/packages/@aws-cdk/aws-events/test/test.rule.ts @@ -97,7 +97,7 @@ export = { const app = new cdk.App(); const stack = new cdk.Stack(app, 'MyStack'); new Rule(stack, 'Rule'); - test.throws(() => app.run(), /Either 'eventPattern' or 'scheduleExpression' must be defined/); + test.throws(() => app.synth(), /Either 'eventPattern' or 'scheduleExpression' must be defined/); test.done(); }, diff --git a/packages/@aws-cdk/aws-glue/test/integ.table.ts b/packages/@aws-cdk/aws-glue/test/integ.table.ts index 055eda3fad323..c624aa8ec75cd 100644 --- a/packages/@aws-cdk/aws-glue/test/integ.table.ts +++ b/packages/@aws-cdk/aws-glue/test/integ.table.ts @@ -78,4 +78,4 @@ const user = new iam.User(stack, 'MyUser'); ordinaryTable.grantReadWrite(user); encryptedTable.grantReadWrite(user); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-iam/test/integ.composite-principal.ts b/packages/@aws-cdk/aws-iam/test/integ.composite-principal.ts index e8de39a7c300d..cd41126ebcd23 100644 --- a/packages/@aws-cdk/aws-iam/test/integ.composite-principal.ts +++ b/packages/@aws-cdk/aws-iam/test/integ.composite-principal.ts @@ -18,4 +18,4 @@ const app = new cdk.App(); new TestStack(app, 'iam-integ-composite-principal'); -app.run(); \ No newline at end of file +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-iam/test/integ.group.ts b/packages/@aws-cdk/aws-iam/test/integ.group.ts index 0946283d97390..3ed8b78e95b25 100644 --- a/packages/@aws-cdk/aws-iam/test/integ.group.ts +++ b/packages/@aws-cdk/aws-iam/test/integ.group.ts @@ -9,4 +9,4 @@ const stack = new Stack(app, 'integ-iam-role-1'); new Group(stack, 'MyGroup'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-iam/test/integ.policy.ts b/packages/@aws-cdk/aws-iam/test/integ.policy.ts index 5d66f6eaa37b2..9d23de82c9cdb 100644 --- a/packages/@aws-cdk/aws-iam/test/integ.policy.ts +++ b/packages/@aws-cdk/aws-iam/test/integ.policy.ts @@ -16,4 +16,4 @@ const policy2 = new Policy(stack, 'GoodbyePolicy'); policy2.addStatement(new PolicyStatement().addResource('*').addAction('lambda:InvokeFunction')); policy2.attachToUser(user); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-iam/test/integ.role.ts b/packages/@aws-cdk/aws-iam/test/integ.role.ts index f3074a389aeac..ee548b53d1f1b 100644 --- a/packages/@aws-cdk/aws-iam/test/integ.role.ts +++ b/packages/@aws-cdk/aws-iam/test/integ.role.ts @@ -21,4 +21,4 @@ new Role(stack, 'TestRole2', { externalId: 'supply-me', }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-iam/test/integ.user.ts b/packages/@aws-cdk/aws-iam/test/integ.user.ts index e21c468177554..6870ac52ea550 100644 --- a/packages/@aws-cdk/aws-iam/test/integ.user.ts +++ b/packages/@aws-cdk/aws-iam/test/integ.user.ts @@ -11,4 +11,4 @@ new User(stack, 'MyUser', { passwordResetRequired: true }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-iam/test/integ.users-and-groups.ts b/packages/@aws-cdk/aws-iam/test/integ.users-and-groups.ts index 3cb7b94c10c93..4b0260fde84f1 100644 --- a/packages/@aws-cdk/aws-iam/test/integ.users-and-groups.ts +++ b/packages/@aws-cdk/aws-iam/test/integ.users-and-groups.ts @@ -18,4 +18,4 @@ const policy = new Policy(stack, 'MyPolicy'); policy.attachToGroup(g1); policy.addStatement(new PolicyStatement().addResource(g2.groupArn).addAction('iam:*')); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-iam/test/test.policy.ts b/packages/@aws-cdk/aws-iam/test/test.policy.ts index 3d990a834decf..bf54cdd94e2d8 100644 --- a/packages/@aws-cdk/aws-iam/test/test.policy.ts +++ b/packages/@aws-cdk/aws-iam/test/test.policy.ts @@ -10,7 +10,7 @@ export = { const stack = new Stack(app, 'MyStack'); new Policy(stack, 'MyPolicy'); - test.throws(() => app.run(), /Policy is empty/); + test.throws(() => app.synth(), /Policy is empty/); test.done(); }, @@ -250,7 +250,7 @@ export = { const app = new App(); const stack = new Stack(app, 'MyStack'); new Policy(stack, 'MyPolicy'); - test.throws(() => app.run(), /Policy must be attached to at least one principal: user, group or role/); + test.throws(() => app.synth(), /Policy must be attached to at least one principal: user, group or role/); test.done(); }, diff --git a/packages/@aws-cdk/aws-kinesis/test/test.stream.ts b/packages/@aws-cdk/aws-kinesis/test/test.stream.ts index 8995244dcf6f5..14d8261b86eeb 100644 --- a/packages/@aws-cdk/aws-kinesis/test/test.stream.ts +++ b/packages/@aws-cdk/aws-kinesis/test/test.stream.ts @@ -945,7 +945,7 @@ export = { const user = new iam.User(stackB, 'UserWhoNeedsAccess'); streamFromStackA.grantRead(user); - test.throws(() => app.run(), /'stackB' depends on 'stackA'/); + test.throws(() => app.synth(), /'stackB' depends on 'stackA'/); test.done(); } } diff --git a/packages/@aws-cdk/aws-kms/test/integ.key-sharing.lit.ts b/packages/@aws-cdk/aws-kms/test/integ.key-sharing.lit.ts index 7f7a9811ac384..8889a2902f929 100644 --- a/packages/@aws-cdk/aws-kms/test/integ.key-sharing.lit.ts +++ b/packages/@aws-cdk/aws-kms/test/integ.key-sharing.lit.ts @@ -37,4 +37,4 @@ const keyStack = new KeyStack(app, 'KeyStack'); new UseStack(app, 'UseStack', { key: keyStack.key }); /// !hide -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-kms/test/integ.key.ts b/packages/@aws-cdk/aws-kms/test/integ.key.ts index 2fae5e51054dc..a1dcfd66a757a 100644 --- a/packages/@aws-cdk/aws-kms/test/integ.key.ts +++ b/packages/@aws-cdk/aws-kms/test/integ.key.ts @@ -15,4 +15,4 @@ key.addToResourcePolicy(new PolicyStatement() key.addAlias('alias/bar'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-lambda-event-sources/test/integ.dynamodb.ts b/packages/@aws-cdk/aws-lambda-event-sources/test/integ.dynamodb.ts index d50cc58e2cbb5..83246fb51e9bd 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/test/integ.dynamodb.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/test/integ.dynamodb.ts @@ -26,4 +26,4 @@ class DynamoEventSourceTest extends cdk.Stack { const app = new cdk.App(); new DynamoEventSourceTest(app, 'lambda-event-source-dynamodb'); -app.run(); \ No newline at end of file +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda-event-sources/test/integ.kinesis.ts b/packages/@aws-cdk/aws-lambda-event-sources/test/integ.kinesis.ts index bf2e352fca95f..56ade188b85ce 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/test/integ.kinesis.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/test/integ.kinesis.ts @@ -19,4 +19,4 @@ class KinesisEventSourceTest extends cdk.Stack { const app = new cdk.App(); new KinesisEventSourceTest(app, 'lambda-event-source-kinesis'); -app.run(); \ No newline at end of file +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda-event-sources/test/integ.s3.ts b/packages/@aws-cdk/aws-lambda-event-sources/test/integ.s3.ts index e94a832cf3a13..15cf4291712cd 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/test/integ.s3.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/test/integ.s3.ts @@ -21,4 +21,4 @@ class S3EventSourceTest extends cdk.Stack { const app = new cdk.App(); new S3EventSourceTest(app, 'lambda-event-source-s3'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-lambda-event-sources/test/integ.sns.ts b/packages/@aws-cdk/aws-lambda-event-sources/test/integ.sns.ts index 261f825611a5b..0964f992a157e 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/test/integ.sns.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/test/integ.sns.ts @@ -16,4 +16,4 @@ class SqsEventSourceTest extends cdk.Stack { const app = new cdk.App(); new SqsEventSourceTest(app, 'lambda-event-source-sns'); -app.run(); \ No newline at end of file +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda-event-sources/test/integ.sqs.ts b/packages/@aws-cdk/aws-lambda-event-sources/test/integ.sqs.ts index 42f5157b60af8..3d9589f2669e0 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/test/integ.sqs.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/test/integ.sqs.ts @@ -18,4 +18,4 @@ class SqsEventSourceTest extends cdk.Stack { const app = new cdk.App(); new SqsEventSourceTest(app, 'lambda-event-source-sqs'); -app.run(); \ No newline at end of file +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/test/integ.assets.file.ts b/packages/@aws-cdk/aws-lambda/test/integ.assets.file.ts index e9ad0745198cc..1d2ea17399f18 100644 --- a/packages/@aws-cdk/aws-lambda/test/integ.assets.file.ts +++ b/packages/@aws-cdk/aws-lambda/test/integ.assets.file.ts @@ -20,4 +20,4 @@ const app = new cdk.App(); new TestStack(app, 'lambda-test-assets-file'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-lambda/test/integ.assets.lit.ts b/packages/@aws-cdk/aws-lambda/test/integ.assets.lit.ts index 56c3eab4a86bd..d82e249645fce 100644 --- a/packages/@aws-cdk/aws-lambda/test/integ.assets.lit.ts +++ b/packages/@aws-cdk/aws-lambda/test/integ.assets.lit.ts @@ -20,4 +20,4 @@ const app = new cdk.App(); new TestStack(app, 'lambda-test-assets'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-lambda/test/integ.lambda.ts b/packages/@aws-cdk/aws-lambda/test/integ.lambda.ts index c5d5979197641..4a0830b6ddaf8 100644 --- a/packages/@aws-cdk/aws-lambda/test/integ.lambda.ts +++ b/packages/@aws-cdk/aws-lambda/test/integ.lambda.ts @@ -24,4 +24,4 @@ alias.addPermission('AliasPermission', { principal: new iam.ServicePrincipal('cloudformation.amazonaws.com') }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-lambda/test/integ.layer-version.lit.ts b/packages/@aws-cdk/aws-lambda/test/integ.layer-version.lit.ts index 3d79d80a89d95..b79c4957eafd9 100644 --- a/packages/@aws-cdk/aws-lambda/test/integ.layer-version.lit.ts +++ b/packages/@aws-cdk/aws-lambda/test/integ.layer-version.lit.ts @@ -31,4 +31,4 @@ new lambda.Function(stack, 'MyLayeredLambda', { }); /// !hide -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-lambda/test/integ.log-retention.ts b/packages/@aws-cdk/aws-lambda/test/integ.log-retention.ts index 08475cc79d5b8..cc52b278fb857 100644 --- a/packages/@aws-cdk/aws-lambda/test/integ.log-retention.ts +++ b/packages/@aws-cdk/aws-lambda/test/integ.log-retention.ts @@ -27,4 +27,4 @@ new lambda.Function(stack, 'OneYear', { logRetentionDays: logs.RetentionDays.OneYear }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-lambda/test/integ.vpc-lambda.ts b/packages/@aws-cdk/aws-lambda/test/integ.vpc-lambda.ts index 74e4d365922b6..d554bd91f73a9 100644 --- a/packages/@aws-cdk/aws-lambda/test/integ.vpc-lambda.ts +++ b/packages/@aws-cdk/aws-lambda/test/integ.vpc-lambda.ts @@ -14,4 +14,4 @@ new lambda.Function(stack, 'MyLambda', { vpc }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-lambda/test/test.code.ts b/packages/@aws-cdk/aws-lambda/test/test.code.ts index f89e226222286..824ca6dc3c2a0 100644 --- a/packages/@aws-cdk/aws-lambda/test/test.code.ts +++ b/packages/@aws-cdk/aws-lambda/test/test.code.ts @@ -63,7 +63,7 @@ export = { }); // THEN - const assembly = app.run(); + const assembly = app.synth(); const synthesized = assembly.stacks[0]; // Func1 has an asset, Func2 does not diff --git a/packages/@aws-cdk/aws-logs/test/integ.metricfilter.lit.ts b/packages/@aws-cdk/aws-logs/test/integ.metricfilter.lit.ts index 1b48dce9e0e45..9e585ec0a8b69 100644 --- a/packages/@aws-cdk/aws-logs/test/integ.metricfilter.lit.ts +++ b/packages/@aws-cdk/aws-logs/test/integ.metricfilter.lit.ts @@ -23,4 +23,4 @@ class MetricFilterIntegStack extends Stack { const app = new App(); new MetricFilterIntegStack(app, 'aws-cdk-metricfilter-integ'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.ts b/packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.ts index ed1a0772820d2..f9713e93f2f68 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.ts +++ b/packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.ts @@ -22,4 +22,4 @@ const cluster = new rds.DatabaseCluster(stack, 'Database', { cluster.addRotationSingleUser('Rotation'); /// !hide -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-rds/test/integ.cluster.ts b/packages/@aws-cdk/aws-rds/test/integ.cluster.ts index 5e24f1370df2f..50e0ea3c51f72 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.cluster.ts +++ b/packages/@aws-cdk/aws-rds/test/integ.cluster.ts @@ -36,4 +36,4 @@ const cluster = new DatabaseCluster(stack, 'Database', { cluster.connections.allowDefaultPortFromAnyIpv4('Open to the world'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-rds/test/integ.instance.lit.ts b/packages/@aws-cdk/aws-rds/test/integ.instance.lit.ts index a8f1143dc96aa..5229eb8cf3b41 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.instance.lit.ts +++ b/packages/@aws-cdk/aws-rds/test/integ.instance.lit.ts @@ -101,4 +101,4 @@ class DatabaseInstanceStack extends cdk.Stack { } new DatabaseInstanceStack(app, 'aws-cdk-rds-instance'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-route53-targets/test/integ.alb-alias-target.ts b/packages/@aws-cdk/aws-route53-targets/test/integ.alb-alias-target.ts index 37245fdaeba80..b909c7f6c99fe 100644 --- a/packages/@aws-cdk/aws-route53-targets/test/integ.alb-alias-target.ts +++ b/packages/@aws-cdk/aws-route53-targets/test/integ.alb-alias-target.ts @@ -25,4 +25,4 @@ new route53.AliasRecord(zone, 'Alias', { target: new targets.LoadBalancerTarget(lb) }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-route53-targets/test/integ.cloudfront-alias-target.ts b/packages/@aws-cdk/aws-route53-targets/test/integ.cloudfront-alias-target.ts index e384dd9558cff..2d659f62aa9f0 100644 --- a/packages/@aws-cdk/aws-route53-targets/test/integ.cloudfront-alias-target.ts +++ b/packages/@aws-cdk/aws-route53-targets/test/integ.cloudfront-alias-target.ts @@ -31,4 +31,4 @@ new route53.AliasRecord(zone, 'Alias', { target: new targets.CloudFrontTarget(distribution) }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-route53/test/integ.route53.ts b/packages/@aws-cdk/aws-route53/test/integ.route53.ts index 625357e5717b6..1c916099623fd 100644 --- a/packages/@aws-cdk/aws-route53/test/integ.route53.ts +++ b/packages/@aws-cdk/aws-route53/test/integ.route53.ts @@ -36,4 +36,4 @@ new CnameRecord(stack, 'CNAME', { new cdk.CfnOutput(stack, 'PrivateZoneId', { value: privateZone.hostedZoneId }); new cdk.CfnOutput(stack, 'PublicZoneId', { value: publicZone.hostedZoneId }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-s3-deployment/test/integ.bucket-deployment.ts b/packages/@aws-cdk/aws-s3-deployment/test/integ.bucket-deployment.ts index bee9f00872a27..7af6ff11e2ca6 100644 --- a/packages/@aws-cdk/aws-s3-deployment/test/integ.bucket-deployment.ts +++ b/packages/@aws-cdk/aws-s3-deployment/test/integ.bucket-deployment.ts @@ -34,4 +34,4 @@ const app = new cdk.App(); new TestBucketDeployment(app, 'test-bucket-deployments-1'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-s3-notifications/test/integ.notifications.ts b/packages/@aws-cdk/aws-s3-notifications/test/integ.notifications.ts index b8531ee378f7d..8b6199d400c0d 100644 --- a/packages/@aws-cdk/aws-s3-notifications/test/integ.notifications.ts +++ b/packages/@aws-cdk/aws-s3-notifications/test/integ.notifications.ts @@ -22,4 +22,4 @@ const bucket2 = new s3.Bucket(stack, 'Bucket2', { }); bucket2.addObjectRemovedNotification(new s3n.SnsDestination(topic3), { prefix: 'foo' }, { suffix: 'foo/bar' }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-s3-notifications/test/lambda/integ.bucket-notifications.ts b/packages/@aws-cdk/aws-s3-notifications/test/lambda/integ.bucket-notifications.ts index 35f4143ea4c55..0e06439a087be 100644 --- a/packages/@aws-cdk/aws-s3-notifications/test/lambda/integ.bucket-notifications.ts +++ b/packages/@aws-cdk/aws-s3-notifications/test/lambda/integ.bucket-notifications.ts @@ -24,7 +24,7 @@ const bucketB = new s3.Bucket(stack, 'YourBucket', { bucketA.addObjectCreatedNotification(new s3n.LambdaDestination(fn), { suffix: '.png' }); bucketB.addEventNotification(s3.EventType.ObjectRemoved, new s3n.LambdaDestination(fn)); -app.run(); +app.synth(); // tslint:disable:no-console function handler(event: any, _context: any, callback: any) { diff --git a/packages/@aws-cdk/aws-s3-notifications/test/sns/integ.sns-bucket-notifications.ts b/packages/@aws-cdk/aws-s3-notifications/test/sns/integ.sns-bucket-notifications.ts index c6d32712b88f8..725a67e816379 100644 --- a/packages/@aws-cdk/aws-s3-notifications/test/sns/integ.sns-bucket-notifications.ts +++ b/packages/@aws-cdk/aws-s3-notifications/test/sns/integ.sns-bucket-notifications.ts @@ -23,4 +23,4 @@ const app = new cdk.App(); new MyStack(app, 'sns-bucket-notifications'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-s3-notifications/test/sqs/integ.bucket-notifications.ts b/packages/@aws-cdk/aws-s3-notifications/test/sqs/integ.bucket-notifications.ts index 62cc5c66b7083..ce0dec65408bd 100644 --- a/packages/@aws-cdk/aws-s3-notifications/test/sqs/integ.bucket-notifications.ts +++ b/packages/@aws-cdk/aws-s3-notifications/test/sqs/integ.bucket-notifications.ts @@ -22,4 +22,4 @@ bucket2.addObjectCreatedNotification(new s3n.SqsDestination(queue), { suffix: '. const encryptedQueue = new sqs.Queue(stack, 'EncryptedQueue', { encryption: sqs.QueueEncryption.Kms }); bucket1.addObjectRemovedNotification(new s3n.SqsDestination(encryptedQueue)); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-s3/test/integ.bucket-sharing.lit.ts b/packages/@aws-cdk/aws-s3/test/integ.bucket-sharing.lit.ts index bb2d807cf55ec..e85dadbab971c 100644 --- a/packages/@aws-cdk/aws-s3/test/integ.bucket-sharing.lit.ts +++ b/packages/@aws-cdk/aws-s3/test/integ.bucket-sharing.lit.ts @@ -42,4 +42,4 @@ const producer = new Producer(app, 'ProducerStack'); new Consumer(app, 'ConsumerStack', { userBucket: producer.myBucket }); /// !hide -app.run(); \ No newline at end of file +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-s3/test/integ.bucket.domain-name.ts b/packages/@aws-cdk/aws-s3/test/integ.bucket.domain-name.ts index 73fa1f408e891..7303819c8ed9a 100644 --- a/packages/@aws-cdk/aws-s3/test/integ.bucket.domain-name.ts +++ b/packages/@aws-cdk/aws-s3/test/integ.bucket.domain-name.ts @@ -21,4 +21,4 @@ class TestStack extends cdk.Stack { const app = new cdk.App(); new TestStack(app, 'aws-cdk-s3-urls'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-s3/test/integ.bucket.ts b/packages/@aws-cdk/aws-s3/test/integ.bucket.ts index af085760cc6c0..5d88247867de3 100644 --- a/packages/@aws-cdk/aws-s3/test/integ.bucket.ts +++ b/packages/@aws-cdk/aws-s3/test/integ.bucket.ts @@ -21,4 +21,4 @@ const user = new iam.User(stack, 'MyUser'); bucket.grantReadWrite(user); otherwiseEncryptedBucket.grantRead(user); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-s3/test/integ.bucket.url.lit.ts b/packages/@aws-cdk/aws-s3/test/integ.bucket.url.lit.ts index 32928a0083537..2ee89c31a1d1b 100644 --- a/packages/@aws-cdk/aws-s3/test/integ.bucket.url.lit.ts +++ b/packages/@aws-cdk/aws-s3/test/integ.bucket.url.lit.ts @@ -18,4 +18,4 @@ class TestStack extends cdk.Stack { const app = new cdk.App(); new TestStack(app, 'aws-cdk-s3-urls'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-s3/test/integ.lifecycle.ts b/packages/@aws-cdk/aws-s3/test/integ.lifecycle.ts index 954e975330fc0..e0658c3d99662 100644 --- a/packages/@aws-cdk/aws-s3/test/integ.lifecycle.ts +++ b/packages/@aws-cdk/aws-s3/test/integ.lifecycle.ts @@ -13,4 +13,4 @@ new Bucket(stack, 'MyBucket', { removalPolicy: RemovalPolicy.Destroy }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-secretsmanager/test/example.app-with-secret.lit.ts b/packages/@aws-cdk/aws-secretsmanager/test/example.app-with-secret.lit.ts index 3959fcbd86761..2b8bfd3d91ae1 100644 --- a/packages/@aws-cdk/aws-secretsmanager/test/example.app-with-secret.lit.ts +++ b/packages/@aws-cdk/aws-secretsmanager/test/example.app-with-secret.lit.ts @@ -23,4 +23,4 @@ class ExampleStack extends cdk.Stack { const app = new cdk.App(); new ExampleStack(app, 'aws-cdk-secret-integ'); -app.run(); \ No newline at end of file +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-secretsmanager/test/integ.secret.lit.ts b/packages/@aws-cdk/aws-secretsmanager/test/integ.secret.lit.ts index 4553d0042c87f..b0acc87da93e0 100644 --- a/packages/@aws-cdk/aws-secretsmanager/test/integ.secret.lit.ts +++ b/packages/@aws-cdk/aws-secretsmanager/test/integ.secret.lit.ts @@ -35,4 +35,4 @@ class SecretsManagerStack extends cdk.Stack { const app = new cdk.App(); new SecretsManagerStack(app, 'Integ-SecretsManager-Secret'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-cname-record.lit.ts b/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-cname-record.lit.ts index 9a5e541ed7aff..58b0adba8b412 100644 --- a/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-cname-record.lit.ts +++ b/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-cname-record.lit.ts @@ -18,4 +18,4 @@ service.registerCnameInstance('CnameInstance', { instanceCname: 'service.pizza', }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-http-namespace.lit.ts b/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-http-namespace.lit.ts index 0f4466f31c759..372a4cc8b8560 100644 --- a/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-http-namespace.lit.ts +++ b/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-http-namespace.lit.ts @@ -28,4 +28,4 @@ service2.registerIpInstance('IpInstance', { ipv4: '54.239.25.192', }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-private-dns-namespace.lit.ts b/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-private-dns-namespace.lit.ts index 94de74f9e2dec..d785f0d960713 100644 --- a/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-private-dns-namespace.lit.ts +++ b/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-private-dns-namespace.lit.ts @@ -23,4 +23,4 @@ const loadbalancer = new elbv2.ApplicationLoadBalancer(stack, 'LB', { vpc, inter service.registerLoadBalancer("Loadbalancer", loadbalancer); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-public-dns-namespace.lit.ts b/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-public-dns-namespace.lit.ts index a63a4358c2ee6..43a997827b6d4 100644 --- a/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-public-dns-namespace.lit.ts +++ b/packages/@aws-cdk/aws-servicediscovery/test/integ.service-with-public-dns-namespace.lit.ts @@ -24,4 +24,4 @@ service.registerIpInstance('IpInstance', { port: 443 }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-ses/test/integ.receipt.ts b/packages/@aws-cdk/aws-ses/test/integ.receipt.ts index fab80a2dafed2..0d58fe40de0ff 100644 --- a/packages/@aws-cdk/aws-ses/test/integ.receipt.ts +++ b/packages/@aws-cdk/aws-ses/test/integ.receipt.ts @@ -73,4 +73,4 @@ new ses.WhiteListReceiptFilter(stack, 'WhiteList', { ] }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-sns/test/integ.sns-lambda.ts b/packages/@aws-cdk/aws-sns/test/integ.sns-lambda.ts index 315934248e98c..d925481d46ca5 100644 --- a/packages/@aws-cdk/aws-sns/test/integ.sns-lambda.ts +++ b/packages/@aws-cdk/aws-sns/test/integ.sns-lambda.ts @@ -22,7 +22,7 @@ const app = new cdk.App(); new SnsToSqs(app, 'aws-cdk-sns-lambda'); -app.run(); +app.synth(); function handler(event: any, _context: any, callback: any) { // tslint:disable:no-console diff --git a/packages/@aws-cdk/aws-sns/test/integ.sns-sqs.lit.ts b/packages/@aws-cdk/aws-sns/test/integ.sns-sqs.lit.ts index 451c05da349a5..3bda2fd1eefe7 100644 --- a/packages/@aws-cdk/aws-sns/test/integ.sns-sqs.lit.ts +++ b/packages/@aws-cdk/aws-sns/test/integ.sns-sqs.lit.ts @@ -19,4 +19,4 @@ const app = new cdk.App(); new SnsToSqs(app, 'aws-cdk-sns-sqs'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-sns/test/integ.sns.ts b/packages/@aws-cdk/aws-sns/test/integ.sns.ts index e8d5e2e054289..d6aaa9939ce4d 100644 --- a/packages/@aws-cdk/aws-sns/test/integ.sns.ts +++ b/packages/@aws-cdk/aws-sns/test/integ.sns.ts @@ -16,4 +16,4 @@ const app = new App(); new SNSInteg(app, 'SNSInteg'); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-sqs/test/integ.sqs.ts b/packages/@aws-cdk/aws-sqs/test/integ.sqs.ts index 831549b272e71..354d8acf922cb 100644 --- a/packages/@aws-cdk/aws-sqs/test/integ.sqs.ts +++ b/packages/@aws-cdk/aws-sqs/test/integ.sqs.ts @@ -16,4 +16,4 @@ new Queue(stack, 'FifoQueue', { new CfnOutput(stack, 'QueueUrl', { value: queue.queueUrl }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-ssm/test/integ.parameter-store-string.lit.ts b/packages/@aws-cdk/aws-ssm/test/integ.parameter-store-string.lit.ts index a00e6575511b0..c5e22f975e0a3 100644 --- a/packages/@aws-cdk/aws-ssm/test/integ.parameter-store-string.lit.ts +++ b/packages/@aws-cdk/aws-ssm/test/integ.parameter-store-string.lit.ts @@ -45,4 +45,4 @@ const creating = new CreatingStack(app, 'sspms-creating'); const using = new UsingStack(app, 'sspms-using'); using.addDependency(creating); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-ssm/test/integ.parameter.lit.ts b/packages/@aws-cdk/aws-ssm/test/integ.parameter.lit.ts index ec3a0a81cf2bf..1e8c1a8ae3a6b 100644 --- a/packages/@aws-cdk/aws-ssm/test/integ.parameter.lit.ts +++ b/packages/@aws-cdk/aws-ssm/test/integ.parameter.lit.ts @@ -34,4 +34,4 @@ new cdk.CfnOutput(stack, 'StringListOutput', { value: cdk.Fn.join('+', listParameter.stringListValue), }); -app.run(); +app.synth(); diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/json-path.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/json-path.ts index 9b80f9e37a9d5..8c61ea44a313b 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/json-path.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/json-path.ts @@ -36,11 +36,11 @@ export class JsonPath { } } -const JSON_PATH_TOKEN_SYMBOL = Symbol.for('JsonPathToken'); +const JSON_PATH_TOKEN_SYMBOL = Symbol.for('@aws-cdk/aws-step-functions-tasks.JsonPathToken'); class JsonPathToken extends Token { - public static isJsonPathToken(x: object): x is JsonPathToken { - return (x as any)[JSON_PATH_TOKEN_SYMBOL] === true; + public static isJsonPathToken(x: any): x is JsonPathToken { + return JSON_PATH_TOKEN_SYMBOL in x; } constructor(public readonly path: string) { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.ec2-task.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.ec2-task.ts index 49d1a0d4dee9c..455b2f3687469 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.ec2-task.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.ec2-task.ts @@ -48,4 +48,4 @@ new sfn.StateMachine(stack, 'StateMachine', { definition, }); -app.run(); \ No newline at end of file +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.fargate-task.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.fargate-task.ts index 320c278437ab6..b22c71a20f1ee 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.fargate-task.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.fargate-task.ts @@ -48,4 +48,4 @@ new sfn.StateMachine(stack, 'StateMachine', { definition, }); -app.run(); \ No newline at end of file +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.job-poller.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.job-poller.ts index db6aa70f55440..5fae9e8d1819b 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.job-poller.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/integ.job-poller.ts @@ -47,4 +47,4 @@ class JobPollerStack extends cdk.Stack { const app = new cdk.App(); new JobPollerStack(app, 'aws-stepfunctions-integ'); -app.run(); \ No newline at end of file +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/cdk/lib/app.ts b/packages/@aws-cdk/cdk/lib/app.ts index 42a001d585ce1..ac15bb170ccda 100644 --- a/packages/@aws-cdk/cdk/lib/app.ts +++ b/packages/@aws-cdk/cdk/lib/app.ts @@ -1,8 +1,7 @@ import cxapi = require('@aws-cdk/cx-api'); import { CloudAssembly } from '@aws-cdk/cx-api'; -import { Construct } from './construct'; +import { Construct, ConstructNode } from './construct'; import { collectRuntimeInformation } from './runtime-info'; -import { Synthesizer } from './synthesis'; const APP_SYMBOL = Symbol.for('@aws-cdk/cdk.App'); @@ -13,7 +12,7 @@ export interface AppProps { /** * Automatically call run before the application exits * - * If you set this, you don't have to call `run()` anymore. + * If you set this, you don't have to call `synth()` anymore. * * @default true if running via CDK toolkit (`CDK_OUTDIR` is set), false otherwise */ @@ -104,9 +103,9 @@ export class App extends Construct { const autoRun = props.autoRun !== undefined ? props.autoRun : cxapi.OUTDIR_ENV in process.env; if (autoRun) { - // run() guarantuees it will only execute once, so a default of 'true' + // synth() guarantuees it will only execute once, so a default of 'true' // doesn't bite manual calling of the function. - process.once('beforeExit', () => this.run()); + process.once('beforeExit', () => this.synth()); } } @@ -117,15 +116,13 @@ export class App extends Construct { * @returns a `CloudAssembly` which can be used to inspect synthesized * artifacts such as CloudFormation templates and assets. */ - public run(): CloudAssembly { - // this app has already been executed, no-op for you + public synth(): CloudAssembly { + // we already have a cloud assembly, no-op for you if (this._assembly) { return this._assembly; } - const synth = new Synthesizer(); - - const assembly = synth.synthesize(this, { + const assembly = ConstructNode.synth(this.node, { outdir: this.outdir, runtimeInfo: this.runtimeInfo ? collectRuntimeInformation() : undefined }); diff --git a/packages/@aws-cdk/cdk/lib/cfn-element.ts b/packages/@aws-cdk/cdk/lib/cfn-element.ts index 468a78441a55c..2bc8e35c85289 100644 --- a/packages/@aws-cdk/cdk/lib/cfn-element.ts +++ b/packages/@aws-cdk/cdk/lib/cfn-element.ts @@ -1,7 +1,9 @@ import cxapi = require('@aws-cdk/cx-api'); -import { Construct, IConstruct, PATH_SEP } from "./construct"; +import { Construct, ConstructNode } from "./construct"; import { Token } from './token'; +const CFN_ELEMENT_SYMBOL = Symbol.for('@aws-cdk/cdk.CfnElement'); + /** * An element of a CloudFormation stack. */ @@ -15,8 +17,8 @@ export abstract class CfnElement extends Construct { * * @returns The construct as a stack element or undefined if it is not a stack element. */ - public static isCfnElement(construct: IConstruct): construct is CfnElement { - return ('logicalId' in construct && '_toCloudFormation' in construct); + public static isCfnElement(x: any): x is CfnElement { + return CFN_ELEMENT_SYMBOL in x; } /** @@ -42,6 +44,8 @@ export abstract class CfnElement extends Construct { constructor(scope: Construct, id: string) { super(scope, id); + Object.defineProperty(this, CFN_ELEMENT_SYMBOL, { value: true }); + this.node.addMetadata(cxapi.LOGICAL_ID_METADATA_KEY, new (require("./token").Token)(() => this.logicalId), this.constructor); this._logicalId = this.node.stack.logicalIds.getLogicalId(this); @@ -87,7 +91,7 @@ export abstract class CfnElement extends Construct { * Return the path with respect to the stack */ public get stackPath(): string { - return this.node.ancestors(this.node.stack).map(c => c.node.id).join(PATH_SEP); + return this.node.ancestors(this.node.stack).map(c => c.node.id).join(ConstructNode.PATH_SEP); } /** diff --git a/packages/@aws-cdk/cdk/lib/cfn-reference.ts b/packages/@aws-cdk/cdk/lib/cfn-reference.ts index 1c357a1084a8e..9b155bd659a17 100644 --- a/packages/@aws-cdk/cdk/lib/cfn-reference.ts +++ b/packages/@aws-cdk/cdk/lib/cfn-reference.ts @@ -21,7 +21,7 @@ export class CfnReference extends Reference { * Check whether this is actually a Reference */ public static isCfnReference(x: Token): x is CfnReference { - return (x as any)[CFN_REFERENCE_SYMBOL] === true; + return CFN_REFERENCE_SYMBOL in x; } /** diff --git a/packages/@aws-cdk/cdk/lib/construct.ts b/packages/@aws-cdk/cdk/lib/construct.ts index 24735d55f7e98..91f5ef6127ab3 100644 --- a/packages/@aws-cdk/cdk/lib/construct.ts +++ b/packages/@aws-cdk/cdk/lib/construct.ts @@ -7,7 +7,7 @@ import { createStackTrace } from './stack-trace'; import { Token } from './token'; import { makeUniqueId } from './uniqueid'; -export const PATH_SEP = '/'; +const CONSTRUCT_SYMBOL = Symbol.for('@aws-cdk/cdk.Construct'); /** * Represents a construct. @@ -19,10 +19,71 @@ export interface IConstruct extends IDependable { readonly node: ConstructNode; } +export interface ISynthesisSession { + /** + * The cloud assembly being synthesized. + */ + assembly: cxapi.CloudAssemblyBuilder; +} + +/** + * Options for synthesis. + */ +export interface SynthesisOptions extends cxapi.AssemblyBuildOptions { + /** + * The output directory into which to synthesize the cloud assembly. + * @default - creates a temporary directory + */ + readonly outdir?: string; + + /** + * Whether synthesis should skip the validation phase. + * @default false + */ + readonly skipValidation?: boolean; +} + /** * Represents the construct node in the scope tree. */ export class ConstructNode { + /** + * Separator used to delimit construct path components. + */ + public static readonly PATH_SEP = '/'; + + /** + * Synthesizes a CloudAssembly from a construct tree. + * @param root The root of the construct tree. + * @param options Synthesis options. + */ + public static synth(root: ConstructNode, options: SynthesisOptions = { }): cxapi.CloudAssembly { + const builder = new cxapi.CloudAssemblyBuilder(options.outdir); + + // the three holy phases of synthesis: prepare, validate and synthesize + + // prepare + root.prepareTree(); + + // validate + const validate = options.skipValidation === undefined ? true : !options.skipValidation; + if (validate) { + const errors = root.validateTree(); + if (errors.length > 0) { + const errorList = errors.map(e => `[${e.source.node.path}] ${e.message}`).join('\n '); + throw new Error(`Validation failed with the following errors:\n ${errorList}`); + } + } + + // synthesize (leaves first) + for (const construct of root.findAll(ConstructOrder.PostOrder)) { + (construct as any).synthesize({ assembly: builder }); // "as any" is needed because we want to keep "synthesize" protected + } + + // write session manifest and lock store + return builder.build(options); + } + /** * Returns the scope in which this construct is defined. */ @@ -38,12 +99,12 @@ export class ConstructNode { /** * An array of aspects applied to this node */ - public readonly aspects: IAspect[] = []; + private readonly aspects: IAspect[] = []; /** * List of children and their names */ - private readonly _children: { [name: string]: IConstruct } = { }; + private readonly _children: { [name: string]: Construct } = { }; private readonly context: { [key: string]: any } = { }; private readonly _metadata = new Array(); private readonly references = new Set(); @@ -114,7 +175,7 @@ export class ConstructNode { */ public get path(): string { const components = this.ancestors().slice(1).map(c => c.node.id); - return components.join(PATH_SEP); + return components.join(ConstructNode.PATH_SEP); } /** @@ -151,13 +212,13 @@ export class ConstructNode { * @param path Relative path of a direct or indirect child * @returns a child by path or undefined if not found. */ - public tryFindChild(path: string): IConstruct | undefined { - if (path.startsWith(PATH_SEP)) { + public tryFindChild(path: string): Construct | undefined { + if (path.startsWith(ConstructNode.PATH_SEP)) { throw new Error('Path must be relative'); } - const parts = path.split(PATH_SEP); + const parts = path.split(ConstructNode.PATH_SEP); - let curr: IConstruct|undefined = this.host; + let curr: Construct|undefined = this.host; while (curr != null && parts.length > 0) { curr = curr.node._children[parts.shift()!]; } @@ -175,7 +236,7 @@ export class ConstructNode { * @param path Relative path of a direct or indirect child * @returns Child with the given path. */ - public findChild(path: string): IConstruct { + public findChild(path: string): Construct { const ret = this.tryFindChild(path); if (!ret) { throw new Error(`No child with path: '${path}'`); @@ -208,12 +269,12 @@ export class ConstructNode { /** * Return this construct and all of its children in the given order */ - public findAll(order: ConstructOrder = ConstructOrder.PreOrder): IConstruct[] { - const ret = new Array(); + public findAll(order: ConstructOrder = ConstructOrder.PreOrder): Construct[] { + const ret = new Array(); visit(this.host); return ret; - function visit(node: IConstruct) { + function visit(node: Construct) { if (order === ConstructOrder.PreOrder) { ret.push(node); } @@ -339,8 +400,8 @@ export class ConstructNode { errors = errors.concat(child.node.validateTree()); } - const localErrors: string[] = (this.host as any).validate(); - return errors.concat(localErrors.map(msg => new ValidationError(this.host, msg))); + const localErrors: string[] = (this.host as any).validate(); // "as any" is needed because we want to keep "validate" protected + return errors.concat(localErrors.map(msg => ({ source: this.host, message: msg }))); } /** @@ -355,7 +416,7 @@ export class ConstructNode { // Use .reverse() to achieve post-order traversal for (const construct of constructs.reverse()) { if (Construct.isConstruct(construct)) { - (construct as any).prepare(); + (construct as any).prepare(); // "as any" is needed because we want to keep "prepare" protected } } } @@ -431,7 +492,7 @@ export class ConstructNode { * @param childName The type name of the child construct. * @returns The resolved path part name of the child */ - public addChild(child: IConstruct, childName: string) { + public addChild(child: Construct, childName: string) { if (this.locked) { // special error if root is locked @@ -586,7 +647,7 @@ export class ConstructNode { */ private _escapePathSeparator(id: string) { if (!id) { return id; } - return id.split(PATH_SEP).join('--'); + return id.split(ConstructNode.PATH_SEP).join('--'); } } @@ -600,12 +661,12 @@ export class Construct implements IConstruct { /** * Return whether the given object is a Construct */ - public static isConstruct(x: IConstruct): x is Construct { - return (x as any).prepare !== undefined && (x as any).validate !== undefined; + public static isConstruct(x: any): x is Construct { + return CONSTRUCT_SYMBOL in x; } /** - * Construct node. + * Construct tree node which offers APIs for interacting with the construct tree. */ public readonly node: ConstructNode; @@ -618,12 +679,13 @@ export class Construct implements IConstruct { * dash `--`. */ constructor(scope: Construct, id: string) { + Object.defineProperty(this, CONSTRUCT_SYMBOL, { value: true }); + this.node = new ConstructNode(this, scope, id); - // Implement IDependable privately - const self = this; + // implement IDependable privately DependableTrait.implement(this, { - get dependencyRoots() { return [self]; }, + dependencyRoots: [ this ] }); } @@ -660,12 +722,33 @@ export class Construct implements IConstruct { protected prepare(): void { return; } + + /** + * Allows this construct to emit artifacts into the cloud assembly during synthesis. + * + * This method is usually implemented by framework-level constructs such as `Stack` and `Asset` + * as they participate in synthesizing the cloud assembly. + * + * @param session The synthesis session. + */ + protected synthesize(session: ISynthesisSession): void { + ignore(session); + } } -export class ValidationError { - constructor(public readonly source: IConstruct, public readonly message: string) { +/** + * An error returned during the validation phase. + */ +export interface ValidationError { + /** + * The construct which emitted the error. + */ + readonly source: Construct; - } + /** + * The error message. + */ + readonly message: string; } /** @@ -718,6 +801,10 @@ export interface OutgoingReference { readonly reference: Reference; } +function ignore(_x: any) { + return; +} + // Import this _after_ everything else to help node work the classes out in the correct order... -import { Reference } from './reference'; \ No newline at end of file +import { Reference } from './reference'; diff --git a/packages/@aws-cdk/cdk/lib/context.ts b/packages/@aws-cdk/cdk/lib/context.ts index 7d3debbc9375f..d95f5d3843c2c 100644 --- a/packages/@aws-cdk/cdk/lib/context.ts +++ b/packages/@aws-cdk/cdk/lib/context.ts @@ -47,10 +47,12 @@ export class ContextProvider { return value; } - this.context.node.stack.reportMissingContext(this.key, { + this.context.node.stack.reportMissingContext({ + key: this.key, provider: this.provider, props: this.props, }); + return defaultValue; } /** @@ -74,10 +76,12 @@ export class ContextProvider { return value; } - this.context.node.stack.reportMissingContext(this.key, { + this.context.node.stack.reportMissingContext({ + key: this.key, provider: this.provider, props: this.props, }); + return defaultValue; } @@ -104,7 +108,8 @@ export class ContextProvider { return value; } - this.context.node.stack.reportMissingContext(this.key, { + this.context.node.stack.reportMissingContext({ + key: this.key, provider: this.provider, props: this.props, }); diff --git a/packages/@aws-cdk/cdk/lib/index.ts b/packages/@aws-cdk/cdk/lib/index.ts index c1e5c78c75346..05027847f76d1 100644 --- a/packages/@aws-cdk/cdk/lib/index.ts +++ b/packages/@aws-cdk/cdk/lib/index.ts @@ -36,6 +36,5 @@ export * from './environment'; export * from './runtime'; export * from './secret-value'; -export * from './synthesis'; export * from './resource'; diff --git a/packages/@aws-cdk/cdk/lib/reference.ts b/packages/@aws-cdk/cdk/lib/reference.ts index 791f67c7945e4..49de124557f61 100644 --- a/packages/@aws-cdk/cdk/lib/reference.ts +++ b/packages/@aws-cdk/cdk/lib/reference.ts @@ -11,8 +11,8 @@ export class Reference extends Token { /** * Check whether this is actually a Reference */ - public static isReference(x: Token): x is Reference { - return (x as any)[REFERENCE_SYMBOL] === true; + public static isReference(x: any): x is Reference { + return REFERENCE_SYMBOL in x; } public readonly target: Construct; diff --git a/packages/@aws-cdk/cdk/lib/stack.ts b/packages/@aws-cdk/cdk/lib/stack.ts index 07bbb61e009db..bef0750154ee5 100644 --- a/packages/@aws-cdk/cdk/lib/stack.ts +++ b/packages/@aws-cdk/cdk/lib/stack.ts @@ -3,10 +3,9 @@ import fs = require('fs'); import path = require('path'); import { App } from './app'; import { CfnParameter } from './cfn-parameter'; -import { Construct, IConstruct, PATH_SEP } from './construct'; +import { Construct, ConstructNode, IConstruct, ISynthesisSession } from './construct'; import { Environment } from './environment'; import { HashedAddressingScheme, IAddressingScheme, LogicalIDs } from './logical-id'; -import { ISynthesisSession } from './synthesis'; import { makeUniqueId } from './uniqueid'; export interface StackProps { @@ -33,16 +32,16 @@ export interface StackProps { readonly namingScheme?: IAddressingScheme; /** - * Indicates if this stack is hidden, which means that it won't be - * automatically deployed when running `cdk deploy` without arguments. + * Indicates if this stack is an entrypoint of your app, which means that it + * will be automatically deployed when running `cdk deploy` without arguments. * - * Setting this to `true` is useful when you have a stack in your CDK app + * Setting this to `false` is useful when you have a stack in your CDK app * which you don't want to deploy using the CDK toolkit. For example, because * you're planning on deploying it through a deployment pipeline. * - * @default false + * @default true */ - readonly hidden?: boolean; + readonly entrypoint?: boolean; /** * Stack tags that will be applied to all the taggable resources and the stack itself. @@ -58,27 +57,13 @@ const STACK_SYMBOL = Symbol.for('@aws-cdk/cdk.Stack'); * A root construct which represents a single CloudFormation stack. */ export class Stack extends Construct implements ITaggable { - - /** - * Adds a metadata annotation "aws:cdk:physical-name" to the construct if physicalName - * is non-null. This can be used later by tools and aspects to determine if resources - * have been created with physical names. - */ - public static annotatePhysicalName(construct: Construct, physicalName?: string) { - if (physicalName == null) { - return; - } - - construct.node.addMetadata('aws:cdk:physical-name', physicalName); - } - /** * Return whether the given object is a Stack. * * We do attribute detection since we can't reliably use 'instanceof'. */ - public static isStack(obj: any): obj is Stack { - return obj[STACK_SYMBOL] === true; + public static isStack(x: any): x is Stack { + return STACK_SYMBOL in x; } private static readonly VALID_STACK_NAME_REGEX = /^[A-Za-z][A-Za-z0-9-]*$/; @@ -88,13 +73,6 @@ export class Stack extends Construct implements ITaggable { */ public readonly tags: TagManager; - /** - * Lists all missing contextual information. - * This is returned when the stack is synthesized under the 'missing' attribute - * and allows tooling to obtain the context and re-synthesize. - */ - public readonly missingContext: { [key: string]: cxapi.MissingContext } = { }; - /** * The environment in which this stack is deployed. */ @@ -119,16 +97,10 @@ export class Stack extends Construct implements ITaggable { public readonly name: string; /** - * Indicates if this stack is hidden, which means that it won't be + * Indicates if this stack is an entrypoint, which means that it won't be * automatically deployed when running `cdk deploy` without arguments. - * - * Setting this to `true` is useful when you have a stack in your CDK app - * which you don't want to deploy using the CDK toolkit. For example, because - * you're planning on deploying it through a deployment pipeline. - * - * By default, all stacks are visible (this will be false). */ - public readonly hidden: boolean; + public readonly entrypoint: boolean; /** * Other stacks this stack depends on @@ -147,6 +119,13 @@ export class Stack extends Construct implements ITaggable { */ private readonly configuredEnv: Environment; + /** + * Lists all missing contextual information. + * This is returned when the stack is synthesized under the 'missing' attribute + * and allows tooling to obtain the context and re-synthesize. + */ + private readonly missingContext = new Array(); + /** * Creates a new stack. * @@ -165,8 +144,8 @@ export class Stack extends Construct implements ITaggable { this.logicalIds = new LogicalIDs(props.namingScheme ? props.namingScheme : new HashedAddressingScheme()); this.name = props.stackName !== undefined ? props.stackName : this.calculateStackName(); - this.hidden = props.hidden === undefined ? false : true; - this.tags = new TagManager(TagType.KeyValue, "aws:cdk:stack", props.tags); + this.entrypoint = props.entrypoint === undefined ? true : false; + this.tags = new TagManager(TagType.KeyValue, 'aws:cdk:stack', props.tags); if (!Stack.VALID_STACK_NAME_REGEX.test(this.name)) { throw new Error(`Stack name must match the regular expression: ${Stack.VALID_STACK_NAME_REGEX.toString()}, got '${name}'`); @@ -276,12 +255,13 @@ export class Stack extends Construct implements ITaggable { /** * Indicate that a context key was expected * - * Contains instructions on how the key should be supplied. - * @param key Key that uniquely identifies this missing context. - * @param details The set of parameters needed to obtain the context (specific to context provider). + * Contains instructions which will be emitted into the cloud assembly on how + * the key should be supplied. + * + * @param report The set of parameters needed to obtain the context */ - public reportMissingContext(key: string, details: cxapi.MissingContext) { - this.missingContext[key] = details; + public reportMissingContext(report: cxapi.MissingContext) { + this.missingContext.push(report); } /** @@ -534,11 +514,17 @@ export class Stack extends Construct implements ITaggable { type: cxapi.ArtifactType.AwsCloudFormationStack, environment: this.environment, properties, - hidden: this.hidden ? true : undefined, // omit if stack is visible dependencies: deps.length > 0 ? deps : undefined, metadata: Object.keys(meta).length > 0 ? meta : undefined, - missing: this.missingContext && Object.keys(this.missingContext).length > 0 ? this.missingContext : undefined }); + + for (const ctx of this.missingContext) { + builder.addMissing(ctx); + } + + if (this.entrypoint) { + builder.addEntrypoint(this.name); + } } /** @@ -576,7 +562,7 @@ export class Stack extends Construct implements ITaggable { const app = this.parentApp(); if (app && app.node.metadata.length > 0) { - output[PATH_SEP] = app.node.metadata; + output[ConstructNode.PATH_SEP] = app.node.metadata; } return output; @@ -585,7 +571,7 @@ export class Stack extends Construct implements ITaggable { if (node.node.metadata.length > 0) { // Make the path absolute - output[PATH_SEP + node.node.path] = node.node.metadata.map(md => node.node.resolve(md) as cxapi.MetadataEntry); + output[ConstructNode.PATH_SEP + node.node.path] = node.node.metadata.map(md => node.node.resolve(md) as cxapi.MetadataEntry); } for (const child of node.node.children) { diff --git a/packages/@aws-cdk/cdk/lib/synthesis.ts b/packages/@aws-cdk/cdk/lib/synthesis.ts deleted file mode 100644 index baa25cc6913aa..0000000000000 --- a/packages/@aws-cdk/cdk/lib/synthesis.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { BuildOptions, CloudAssembly, CloudAssemblyBuilder } from '@aws-cdk/cx-api'; -import { ConstructOrder, IConstruct } from './construct'; - -export interface ISynthesisSession { - /** - * The cloud assembly being synthesized. - */ - assembly: CloudAssemblyBuilder; -} - -export interface ISynthesizable { - synthesize(session: ISynthesisSession): void; -} - -export interface SynthesisOptions extends BuildOptions { - /** - * The file store used for this session. - * @default - creates a temporary directory - */ - readonly outdir?: string; - - /** - * Whether synthesis should skip the validation phase. - * @default false - */ - readonly skipValidation?: boolean; -} - -export class Synthesizer { - public synthesize(root: IConstruct, options: SynthesisOptions = { }): CloudAssembly { - const builder = new CloudAssemblyBuilder(options.outdir); - - // the three holy phases of synthesis: prepare, validate and synthesize - - // prepare - root.node.prepareTree(); - - // validate - const validate = options.skipValidation === undefined ? true : !options.skipValidation; - if (validate) { - const errors = root.node.validateTree(); - if (errors.length > 0) { - const errorList = errors.map(e => `[${e.source.node.path}] ${e.message}`).join('\n '); - throw new Error(`Validation failed with the following errors:\n ${errorList}`); - } - } - - // synthesize (leaves first) - for (const c of root.node.findAll(ConstructOrder.PostOrder)) { - if (isSynthesizable(c)) { - c.synthesize({ assembly: builder }); - } - } - - // write session manifest and lock store - return builder.build(options); - } -} - -/** - * @returns true if `obj` implements `ISynthesizable`. - */ -function isSynthesizable(obj: any): obj is ISynthesizable { - return 'synthesize' in obj; -} diff --git a/packages/@aws-cdk/cdk/test/test.app.ts b/packages/@aws-cdk/cdk/test/test.app.ts index 8845eb9348031..3dfa7fcbb53b3 100644 --- a/packages/@aws-cdk/cdk/test/test.app.ts +++ b/packages/@aws-cdk/cdk/test/test.app.ts @@ -12,7 +12,7 @@ function withApp(props: AppProps, block: (app: App) => void): cxapi.CloudAssembl block(app); - return app.run(); + return app.synth(); } function synth(context?: { [key: string]: any }): cxapi.CloudAssembly { @@ -140,7 +140,7 @@ export = { test.done(); }, -'app.run() performs validation first and if there are errors, it returns the errors'(test: Test) { +'app.synth() performs validation first and if there are errors, it returns the errors'(test: Test) { class Child extends Construct { protected validate() { @@ -158,7 +158,7 @@ export = { new Child(parent, 'C1'); new Child(parent, 'C2'); - test.throws(() => app.run(), /Validation failed with the following errors/); + test.throws(() => app.synth(), /Validation failed with the following errors/); test.done(); }, @@ -168,7 +168,8 @@ export = { constructor(scope: App, id: string, props?: StackProps) { super(scope, id, props); - this.reportMissingContext('missing-context-key', { + this.reportMissingContext({ + key: 'missing-context-key', provider: 'fake', props: { account: '12345689012', @@ -177,7 +178,8 @@ export = { }, ); - this.reportMissingContext('missing-context-key-2', { + this.reportMissingContext({ + key: 'missing-context-key-2', provider: 'fake2', props: { foo: 'bar', @@ -189,27 +191,29 @@ export = { } } - const response = withApp({}, app => { + const assembly = withApp({}, app => { new MyStack(app, 'MyStack'); }); - test.deepEqual(response.missing, { - "missing-context-key": { + test.deepEqual(assembly.manifest.missing, [ + { + key: "missing-context-key", provider: 'fake', props: { account: '12345689012', region: 'ab-north-1', }, }, - "missing-context-key-2": { + { + key: "missing-context-key-2", provider: 'fake2', props: { account: '12345689012', region: 'ab-south-1', foo: 'bar', }, - }, - }); + } + ]); test.done(); }, @@ -218,12 +222,12 @@ export = { const context: any = {}; context[cxapi.DISABLE_VERSION_REPORTING] = true; - const response = withApp(context, app => { + const assembly = withApp(context, app => { const stack = new Stack(app, 'stack1'); new CfnResource(stack, 'MyResource', { type: 'Resource::Type' }); }); - test.deepEqual(response.runtime, { libraries: {} }); + test.deepEqual(assembly.runtime, { libraries: {} }); test.done(); }, diff --git a/packages/@aws-cdk/cdk/test/test.context.ts b/packages/@aws-cdk/cdk/test/test.context.ts index b11dd432f0b7f..9cb168dfd6099 100644 --- a/packages/@aws-cdk/cdk/test/test.context.ts +++ b/packages/@aws-cdk/cdk/test/test.context.ts @@ -1,6 +1,6 @@ import cxapi = require('@aws-cdk/cx-api'); import { Test } from 'nodeunit'; -import { App, AvailabilityZoneProvider, Construct, ContextProvider, SSMParameterProvider, Stack } from '../lib'; +import { App, AvailabilityZoneProvider, Construct, ConstructNode, ContextProvider, SSMParameterProvider, Stack } from '../lib'; export = { 'AvailabilityZoneProvider returns a list with dummy values if the context is not available'(test: Test) { @@ -100,7 +100,7 @@ export = { test.deepEqual(new AvailabilityZoneProvider(stack).availabilityZones, [ 'dummy1a', 'dummy1b', 'dummy1c' ]); test.deepEqual(new SSMParameterProvider(child, {parameterName: 'foo'}).parameterValue(), 'dummy'); - const assembly = app.run(); + const assembly = app.synth(); const output = assembly.getStack('test-stack'); const metadata = output.manifest.metadata || {}; const azError: cxapi.MetadataEntry | undefined = metadata['/test-stack'].find(x => x.type === cxapi.ERROR_METADATA_KEY); @@ -113,13 +113,13 @@ export = { }, }; -function firstKey(obj: any): string { - return Object.keys(obj)[0]; -} - /** * Get the expected context key from a stack with missing parameters */ function expectedContextKey(stack: Stack): string { - return firstKey(stack.missingContext); + const missing = ConstructNode.synth(stack.node).manifest.missing; + if (!missing || missing.length !== 1) { + throw new Error(`Expecting assembly to include a single missing context report`); + } + return missing[0].key; } diff --git a/packages/@aws-cdk/cdk/test/test.stack.ts b/packages/@aws-cdk/cdk/test/test.stack.ts index 0451745f5c7ba..aca60622c1544 100644 --- a/packages/@aws-cdk/cdk/test/test.stack.ts +++ b/packages/@aws-cdk/cdk/test/test.stack.ts @@ -164,7 +164,7 @@ export = { // THEN // Need to do this manually now, since we're in testing mode. In a normal CDK app, - // this happens as part of app.run(). + // this happens as part of app.synth(). app.node.prepareTree(); test.deepEqual(stack1._toCloudFormation(), { @@ -202,7 +202,7 @@ export = { // THEN // Need to do this manually now, since we're in testing mode. In a normal CDK app, - // this happens as part of app.run(). + // this happens as part of app.synth(). app.node.prepareTree(); test.deepEqual(stack2._toCloudFormation(), { @@ -263,7 +263,7 @@ export = { // THEN // Need to do this manually now, since we're in testing mode. In a normal CDK app, - // this happens as part of app.run(). + // this happens as part of app.synth(). app.node.prepareTree(); test.deepEqual(stack2._toCloudFormation(), { @@ -437,7 +437,7 @@ export = { }); // THEN - const session = app.run(); + const session = app.synth(); test.deepEqual(stack.name, 'valid-stack-name'); test.ok(session.tryGetArtifact('valid-stack-name')); test.done(); diff --git a/packages/@aws-cdk/cdk/test/test.synthesis.ts b/packages/@aws-cdk/cdk/test/test.synthesis.ts index 00716cb1a2e65..7cf6b7b20ae80 100644 --- a/packages/@aws-cdk/cdk/test/test.synthesis.ts +++ b/packages/@aws-cdk/cdk/test/test.synthesis.ts @@ -1,11 +1,10 @@ import cxapi = require('@aws-cdk/cx-api'); -import { CloudAssemblyBuilder } from '@aws-cdk/cx-api'; import fs = require('fs'); import { Test } from 'nodeunit'; import os = require('os'); import path = require('path'); import cdk = require('../lib'); -import { Construct, ISynthesisSession, Synthesizer } from '../lib'; +import { Construct, ConstructNode, ISynthesisSession } from '../lib'; function createModernApp() { return new cdk.App({ @@ -21,10 +20,10 @@ export = { const app = createModernApp(); // WHEN - const session = app.run(); + const session = app.synth(); // THEN - test.same(app.run(), session); // same session if we run() again + test.same(app.synth(), session); // same session if we synth() again test.deepEqual(list(session.directory), [ 'cdk.out', 'manifest.json' ]); test.deepEqual(readJson(session.directory, 'manifest.json').artifacts, {}); test.done(); @@ -36,7 +35,7 @@ export = { new cdk.Stack(app, 'one-stack'); // WHEN - const session = app.run(); + const session = app.synth(); // THEN test.deepEqual(list(session.directory), [ @@ -52,8 +51,8 @@ export = { const app = createModernApp(); const stack = new cdk.Stack(app, 'one-stack'); - class MyConstruct extends cdk.Construct implements cdk.ISynthesizable { - public synthesize(s: ISynthesisSession) { + class MyConstruct extends cdk.Construct { + protected synthesize(s: ISynthesisSession) { writeJson(s.assembly.outdir, 'foo.json', { bar: 123 }); s.assembly.addArtifact('my-random-construct', { type: cxapi.ArtifactType.AwsCloudFormationStack, @@ -68,7 +67,7 @@ export = { new MyConstruct(stack, 'MyConstruct'); // WHEN - const session = app.run(); + const session = app.synth(); // THEN test.deepEqual(list(session.directory), [ @@ -79,7 +78,8 @@ export = { ]); test.deepEqual(readJson(session.directory, 'foo.json'), { bar: 123 }); test.deepEqual(session.manifest, { - version: '0.33.0', + version: '0.34.0', + entrypoints: [ 'one-stack' ], artifacts: { 'my-random-construct': { type: 'aws:cloudformation:stack', @@ -104,19 +104,10 @@ export = { super(undefined as any, 'id'); } - protected validate(): string[] { - calls.push('validate'); - return []; - } - - protected prepare(): void { - calls.push('prepare'); - } - - protected synthesize(session: CloudAssemblyBuilder) { + protected synthesize(session: ISynthesisSession) { calls.push('synthesize'); - session.addArtifact('art', { + session.assembly.addArtifact('art', { type: cxapi.ArtifactType.AwsCloudFormationStack, properties: { templateFile: 'hey.json', @@ -128,14 +119,21 @@ export = { environment: 'aws://unknown-account/us-east-1' }); - writeJson(session.outdir, 'hey.json', { hello: 123 }); + writeJson(session.assembly.outdir, 'hey.json', { hello: 123 }); + } + + protected validate(): string[] { + calls.push('validate'); + return []; + } + + protected prepare(): void { + calls.push('prepare'); } } const root = new SynthesizeMe(); - - const synth = new Synthesizer(); - const assembly = synth.synthesize(root, { outdir: fs.mkdtempSync(path.join(os.tmpdir(), 'outdir')) }); + const assembly = ConstructNode.synth(root.node, { outdir: fs.mkdtempSync(path.join(os.tmpdir(), 'outdir')) }); test.deepEqual(calls, [ 'prepare', 'validate', 'synthesize' ]); const stack = assembly.getStack('art'); @@ -156,7 +154,7 @@ export = { stack.setParameterValue(param, 'Foo'); // THEN - const session = app.run(); + const session = app.synth(); const artifact = session.getStack('my-stack'); test.deepEqual(artifact.parameters, { MyParam: 'Foo' diff --git a/packages/@aws-cdk/cdk/test/test.tag-aspect.ts b/packages/@aws-cdk/cdk/test/test.tag-aspect.ts index ce660803bd00a..3bc2ec87bd40a 100644 --- a/packages/@aws-cdk/cdk/test/test.tag-aspect.ts +++ b/packages/@aws-cdk/cdk/test/test.tag-aspect.ts @@ -54,7 +54,6 @@ export = { type: 'AWS::Fake::Thing', }); res.node.apply(new Tag('foo', 'bar')); - test.deepEqual(res.node.aspects.length, 1); root.node.prepareTree(); test.deepEqual(res.tags.renderTags(), [{key: 'foo', value: 'bar'}]); test.deepEqual(res2.tags.renderTags(), [{key: 'foo', value: 'bar'}]); diff --git a/packages/@aws-cdk/cx-api/lib/cloud-artifact.ts b/packages/@aws-cdk/cx-api/lib/cloud-artifact.ts index 21a1652bfe79a..7e1a01b75b443 100644 --- a/packages/@aws-cdk/cx-api/lib/cloud-artifact.ts +++ b/packages/@aws-cdk/cx-api/lib/cloud-artifact.ts @@ -1,4 +1,4 @@ -import { CloudAssembly, MissingContext } from './cloud-assembly'; +import { CloudAssembly } from './cloud-assembly'; import { Environment, EnvironmentUtils } from './environment'; import { ERROR_METADATA_KEY, @@ -45,20 +45,10 @@ export interface ArtifactManifest { */ readonly dependencies?: string[]; - /** - * Any missing context information. - */ - readonly missing?: { [key: string]: MissingContext }; - /** * The set of properties for this artifact (depends on type) */ readonly properties?: { [name: string]: any }; - - /** - * True if this artifact should be be explicitly deployed or is it a "hidden" artifact. - */ - readonly hidden?: boolean; } /** @@ -111,6 +101,11 @@ export class CloudArtifact { */ public readonly environment: Environment; + /** + * Indicates if this artifact is an entrypoint of the assembly. + */ + public readonly entrypoint: boolean; + /** * IDs of all dependencies. Used when topologically sorting the artifacts within the cloud assembly. * @internal @@ -127,6 +122,7 @@ export class CloudArtifact { this.environment = EnvironmentUtils.parse(manifest.environment); this.messages = this.renderMessages(); this._dependencyIDs = manifest.dependencies || []; + this.entrypoint = (assembly.manifest.entrypoints || []).includes(id); } /** diff --git a/packages/@aws-cdk/cx-api/lib/cloud-assembly.ts b/packages/@aws-cdk/cx-api/lib/cloud-assembly.ts index 8aa3416a6731c..2ab7e7184110a 100644 --- a/packages/@aws-cdk/cx-api/lib/cloud-assembly.ts +++ b/packages/@aws-cdk/cx-api/lib/cloud-assembly.ts @@ -20,6 +20,18 @@ export interface AssemblyManifest { */ readonly artifacts?: { [id: string]: ArtifactManifest }; + /** + * A list of artifact IDs that are entrypoints of this app. Entrypoints will + * automatically be deployed when running "cdk deploy". + */ + readonly entrypoints?: string[]; + + /** + * Missing context information. If this field has values, it means that the + * cloud assembly is not complete and should not be deployed. + */ + readonly missing?: MissingContext[]; + /** * Runtime information. */ @@ -50,11 +62,6 @@ export class CloudAssembly { */ public readonly artifacts: CloudArtifact[]; - /** - * The set of missing context information (or `undefined` if there is no missing context). - */ - public readonly missing?: { [key: string]: MissingContext }; - /** * Runtime information such as module versions used to synthesize this assembly. */ @@ -77,7 +84,6 @@ export class CloudAssembly { verifyManifestVersion(this.version); this.artifacts = this.renderArtifacts(); - this.missing = this.renderMissing(); this.runtime = this.manifest.runtime || { libraries: { } }; // force validation of deps by accessing 'depends' on all artifacts @@ -139,17 +145,6 @@ export class CloudAssembly { return topologicalSort(result, x => x.id, x => x._dependencyIDs); } - - private renderMissing() { - const missing: { [key: string]: MissingContext } = { }; - for (const artifact of Object.values(this.manifest.artifacts || {})) { - for (const [ key, m ] of Object.entries(artifact.missing || {})) { - missing[key] = m; - } - } - - return Object.keys(missing).length > 0 ? missing : undefined; - } } /** @@ -162,6 +157,8 @@ export class CloudAssemblyBuilder { public readonly outdir: string; private readonly artifacts: { [id: string]: ArtifactManifest } = { }; + private readonly entrypoints = new Array(); + private readonly missing = new Array(); /** * Initializes a cloud assembly builder. @@ -193,11 +190,36 @@ export class CloudAssemblyBuilder { this.artifacts[id] = filterUndefined(manifest); } - public build(options: BuildOptions = { }): CloudAssembly { + /** + * Marks an artifact as an entrypoint, which means that it will be automatically + * deployed with "cdk deploy". + * + * @param id The ID of the artifact. + */ + public addEntrypoint(id: string) { + this.entrypoints.push(id); + } + + /** + * Reports that some context is missing in order for this cloud assembly to be fully synthesized. + * @param missing Missing context information. + */ + public addMissing(missing: MissingContext) { + this.missing.push(missing); + } + + /** + * Finalizes the cloud assembly into the output directory returns a + * `CloudAssembly` object that can be used to inspect the assembly. + * @param options + */ + public build(options: AssemblyBuildOptions = { }): CloudAssembly { const manifest: AssemblyManifest = filterUndefined({ version: CLOUD_ASSEMBLY_VERSION, artifacts: this.artifacts, - runtime: options.runtimeInfo + entrypoints: this.entrypoints.length > 0 ? this.entrypoints : undefined, + runtime: options.runtimeInfo, + missing: this.missing.length > 0 ? this.missing : undefined }); const manifestFilePath = path.join(this.outdir, MANIFEST_FILE); @@ -205,14 +227,14 @@ export class CloudAssemblyBuilder { // "backwards compatibility": in order for the old CLI to tell the user they // need a new version, we'll emit the legacy manifest with only "version". - // this will result in an error "CDK Toolkit >= 0.33.0 is required in order to interact with this program." + // this will result in an error "CDK Toolkit >= 0.34.0 is required in order to interact with this program." fs.writeFileSync(path.join(this.outdir, 'cdk.out'), JSON.stringify({ version: CLOUD_ASSEMBLY_VERSION })); return new CloudAssembly(this.outdir); } } -export interface BuildOptions { +export interface AssemblyBuildOptions { /** * Include runtime information (module versions) in manifest. * @default true @@ -234,7 +256,19 @@ export interface RuntimeInfo { * Represents a missing piece of context. */ export interface MissingContext { + /** + * The missing context key. + */ + readonly key: string; + + /** + * The provider from which we expect this context key to be obtained. + */ readonly provider: string; + + /** + * A set of provider-specific options. + */ readonly props: { account?: string; region?: string; diff --git a/packages/@aws-cdk/cx-api/lib/versioning.ts b/packages/@aws-cdk/cx-api/lib/versioning.ts index 281e7242f6b66..f5d2be483dc91 100644 --- a/packages/@aws-cdk/cx-api/lib/versioning.ts +++ b/packages/@aws-cdk/cx-api/lib/versioning.ts @@ -16,7 +16,7 @@ import semver = require('semver'); * updated (as the current verison in package.json has already been released!) * - The request does not have versioning yet, only the response. */ -export const CLOUD_ASSEMBLY_VERSION = '0.33.0'; +export const CLOUD_ASSEMBLY_VERSION = '0.34.0'; /** * Look at the type of response we get and upgrade it to the latest expected version diff --git a/packages/@aws-cdk/cx-api/test/__snapshots__/cloud-assembly.test.js.snap b/packages/@aws-cdk/cx-api/test/__snapshots__/cloud-assembly.test.js.snap index 8bf4506feca6e..76fbb4eeb9785 100644 --- a/packages/@aws-cdk/cx-api/test/__snapshots__/cloud-assembly.test.js.snap +++ b/packages/@aws-cdk/cx-api/test/__snapshots__/cloud-assembly.test.js.snap @@ -1,13 +1,22 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`assembly a single cloudformation stack 1`] = ` +Object { + "environment": "aws://37736633/us-region-1", + "properties": Object { + "templateFile": "template.json", + }, + "type": "aws:cloudformation:stack", +} +`; + exports[`assembly with missing context 1`] = ` Object { - "missing:context:key": Object { + "key": "missing:context:key", + "props": Object { "foo": 123, }, - "missing:context:key2": Object { - "foo": 6688, - }, + "provider": "context-provider", } `; @@ -28,6 +37,12 @@ Array [ ] `; +exports[`empty assembly 1`] = ` +Object { + "version": "0.34.0", +} +`; + exports[`messages 1`] = ` Array [ Object { diff --git a/packages/@aws-cdk/cx-api/test/cloud-assembly-builder.test.ts b/packages/@aws-cdk/cx-api/test/cloud-assembly-builder.test.ts index 90d67873cd137..79380b99e64bb 100644 --- a/packages/@aws-cdk/cx-api/test/cloud-assembly-builder.test.ts +++ b/packages/@aws-cdk/cx-api/test/cloud-assembly-builder.test.ts @@ -25,14 +25,14 @@ test('cloud assembly builder', () => { prop2: '555' } }, - missing: { - foo: { - provider: 'context-provider', - props: { - a: 'A', - b: 2 - } - } + }); + + session.addMissing({ + key: 'foo', + provider: 'context-provider', + props: { + a: 'A', + b: 2 } }); @@ -53,13 +53,15 @@ test('cloud assembly builder', () => { })); const assembly = session.build(); - const manifest = assembly.manifest; // THEN // verify the manifest looks right expect(manifest).toStrictEqual({ version: CLOUD_ASSEMBLY_VERSION, + missing: [ + { key: 'foo', provider: 'context-provider', props: { a: 'A', b: 2 } } + ], artifacts: { 'my-first-artifact': { type: 'aws:cloudformation:stack', @@ -73,9 +75,6 @@ test('cloud assembly builder', () => { prop2: '555' }, }, - missing: { - foo: { provider: 'context-provider', props: { a: 'A', b: 2 } } - } }, 'minimal-artifact': { type: 'aws:cloudformation:stack', diff --git a/packages/@aws-cdk/cx-api/test/cloud-assembly.test.ts b/packages/@aws-cdk/cx-api/test/cloud-assembly.test.ts index 4736659cdede2..3f66e6c38f215 100644 --- a/packages/@aws-cdk/cx-api/test/cloud-assembly.test.ts +++ b/packages/@aws-cdk/cx-api/test/cloud-assembly.test.ts @@ -7,37 +7,36 @@ const FIXTURES = path.join(__dirname, 'fixtures'); test('empty assembly', () => { const assembly = new CloudAssembly(path.join(FIXTURES, 'empty')); expect(assembly.artifacts).toEqual([]); - expect(assembly.missing).toBeUndefined(); expect(assembly.runtime).toEqual({ libraries: { } }); expect(assembly.stacks).toEqual([]); expect(assembly.version).toEqual(CLOUD_ASSEMBLY_VERSION); + expect(assembly.manifest).toMatchSnapshot(); }); test('assembly a single cloudformation stack', () => { const assembly = new CloudAssembly(path.join(FIXTURES, 'single-stack')); expect(assembly.artifacts).toHaveLength(1); expect(assembly.stacks).toHaveLength(1); - expect(assembly.missing).toBeUndefined(); + expect(assembly.manifest.missing).toBeUndefined(); expect(assembly.runtime).toEqual({ libraries: { } }); expect(assembly.version).toEqual(CLOUD_ASSEMBLY_VERSION); expect(assembly.artifacts[0]).toEqual(assembly.stacks[0]); const stack = assembly.stacks[0]; + expect(stack.manifest).toMatchSnapshot(); expect(stack.assets).toHaveLength(0); - expect(stack.manifest.hidden).toBeFalsy(); expect(stack.dependencies).toEqual([]); expect(stack.environment).toEqual({ account: '37736633', region: 'us-region-1', name: 'aws://37736633/us-region-1' }); expect(stack.template).toEqual({ Resources: { MyBucket: { Type: "AWS::S3::Bucket" } } }); expect(stack.messages).toEqual([]); expect(stack.manifest.metadata).toEqual(undefined); - expect(stack.manifest.missing).toEqual(undefined); expect(stack.originalName).toEqual('MyStackName'); expect(stack.name).toEqual('MyStackName'); }); test('assembly with missing context', () => { const assembly = new CloudAssembly(path.join(FIXTURES, 'missing-context')); - expect(assembly.missing).toMatchSnapshot(); + expect(assembly.manifest.missing).toMatchSnapshot(); }); test('assembly with multiple stacks', () => { @@ -88,7 +87,7 @@ test('fails for invalid dependencies', () => { }); test('verifyManifestVersion', () => { - verifyManifestVersion('0.33.0'); - expect(() => verifyManifestVersion('0.31.0')).toThrow('CDK CLI can only be used with apps created by CDK >= 0.33.0'); - expect(() => verifyManifestVersion('0.34.0')).toThrow('CDK CLI >= 0.34.0 is required to interact with this app'); + verifyManifestVersion('0.34.0'); + expect(() => verifyManifestVersion('0.31.0')).toThrow('CDK CLI can only be used with apps created by CDK >= 0.34.0'); + expect(() => verifyManifestVersion('0.35.0')).toThrow('CDK CLI >= 0.35.0 is required to interact with this app'); }); \ No newline at end of file diff --git a/packages/@aws-cdk/cx-api/test/fixtures/assets/manifest.json b/packages/@aws-cdk/cx-api/test/fixtures/assets/manifest.json index 93c9745639042..7a82e769c79e4 100644 --- a/packages/@aws-cdk/cx-api/test/fixtures/assets/manifest.json +++ b/packages/@aws-cdk/cx-api/test/fixtures/assets/manifest.json @@ -1,5 +1,5 @@ { - "version": "0.33.0", + "version": "0.34.0", "artifacts": { "MyStackName": { "type": "aws:cloudformation:stack", diff --git a/packages/@aws-cdk/cx-api/test/fixtures/depends/manifest.json b/packages/@aws-cdk/cx-api/test/fixtures/depends/manifest.json index f0a43dc6cf926..a611f4b5b62b3 100644 --- a/packages/@aws-cdk/cx-api/test/fixtures/depends/manifest.json +++ b/packages/@aws-cdk/cx-api/test/fixtures/depends/manifest.json @@ -1,5 +1,5 @@ { - "version": "0.33.0", + "version": "0.34.0", "artifacts": { "StackA": { "type": "aws:cloudformation:stack", diff --git a/packages/@aws-cdk/cx-api/test/fixtures/empty/manifest.json b/packages/@aws-cdk/cx-api/test/fixtures/empty/manifest.json index 1a1c7486458ef..11b30463aa234 100644 --- a/packages/@aws-cdk/cx-api/test/fixtures/empty/manifest.json +++ b/packages/@aws-cdk/cx-api/test/fixtures/empty/manifest.json @@ -1,3 +1,3 @@ { - "version": "0.33.0" + "version": "0.34.0" } \ No newline at end of file diff --git a/packages/@aws-cdk/cx-api/test/fixtures/invalid-artifact-type/manifest.json b/packages/@aws-cdk/cx-api/test/fixtures/invalid-artifact-type/manifest.json index f3e4eff9bcfb8..0c92139477a1d 100644 --- a/packages/@aws-cdk/cx-api/test/fixtures/invalid-artifact-type/manifest.json +++ b/packages/@aws-cdk/cx-api/test/fixtures/invalid-artifact-type/manifest.json @@ -1,5 +1,5 @@ { - "version": "0.33.0", + "version": "0.34.0", "artifacts": { "MyArt": { "type": "who:am:i", diff --git a/packages/@aws-cdk/cx-api/test/fixtures/invalid-depends/manifest.json b/packages/@aws-cdk/cx-api/test/fixtures/invalid-depends/manifest.json index 27f637ba0aabe..2f15a7b00a313 100644 --- a/packages/@aws-cdk/cx-api/test/fixtures/invalid-depends/manifest.json +++ b/packages/@aws-cdk/cx-api/test/fixtures/invalid-depends/manifest.json @@ -1,5 +1,5 @@ { - "version": "0.33.0", + "version": "0.34.0", "artifacts": { "StackA": { "type": "aws:cloudformation:stack", diff --git a/packages/@aws-cdk/cx-api/test/fixtures/invalid-env-format/manifest.json b/packages/@aws-cdk/cx-api/test/fixtures/invalid-env-format/manifest.json index 4533438b41f14..db458ca00d7b5 100644 --- a/packages/@aws-cdk/cx-api/test/fixtures/invalid-env-format/manifest.json +++ b/packages/@aws-cdk/cx-api/test/fixtures/invalid-env-format/manifest.json @@ -1,5 +1,5 @@ { - "version": "0.33.0", + "version": "0.34.0", "artifacts": { "MyStackName": { "type": "aws:cloudformation:stack", diff --git a/packages/@aws-cdk/cx-api/test/fixtures/logical-id-map/manifest.json b/packages/@aws-cdk/cx-api/test/fixtures/logical-id-map/manifest.json index e77bd29eda177..063f712757085 100644 --- a/packages/@aws-cdk/cx-api/test/fixtures/logical-id-map/manifest.json +++ b/packages/@aws-cdk/cx-api/test/fixtures/logical-id-map/manifest.json @@ -1,5 +1,5 @@ { - "version": "0.33.0", + "version": "0.34.0", "artifacts": { "MyStackName": { "type": "aws:cloudformation:stack", diff --git a/packages/@aws-cdk/cx-api/test/fixtures/messages/manifest.json b/packages/@aws-cdk/cx-api/test/fixtures/messages/manifest.json index aedd6d1b48bf4..d90c854d19241 100644 --- a/packages/@aws-cdk/cx-api/test/fixtures/messages/manifest.json +++ b/packages/@aws-cdk/cx-api/test/fixtures/messages/manifest.json @@ -1,5 +1,5 @@ { - "version": "0.33.0", + "version": "0.34.0", "artifacts": { "MyStackName": { "type": "aws:cloudformation:stack", diff --git a/packages/@aws-cdk/cx-api/test/fixtures/missing-context/manifest.json b/packages/@aws-cdk/cx-api/test/fixtures/missing-context/manifest.json index 4a5185aad4056..033e0298244b1 100644 --- a/packages/@aws-cdk/cx-api/test/fixtures/missing-context/manifest.json +++ b/packages/@aws-cdk/cx-api/test/fixtures/missing-context/manifest.json @@ -1,12 +1,14 @@ { - "version": "0.33.0", + "version": "0.34.0", + "missing": { + "key": "missing:context:key", + "provider": "context-provider", + "props": { "foo": 123 } + }, "artifacts": { "MyStackName": { "type": "aws:cloudformation:stack", "environment": "aws://37736633/us-region-1", - "missing": { - "missing:context:key": { "foo": 123 } - }, "properties": { "templateFile": "template.json" } diff --git a/packages/@aws-cdk/cx-api/test/fixtures/multiple-stacks/manifest.json b/packages/@aws-cdk/cx-api/test/fixtures/multiple-stacks/manifest.json index 62458941a6728..419fb9720861e 100644 --- a/packages/@aws-cdk/cx-api/test/fixtures/multiple-stacks/manifest.json +++ b/packages/@aws-cdk/cx-api/test/fixtures/multiple-stacks/manifest.json @@ -1,5 +1,5 @@ { - "version": "0.33.0", + "version": "0.34.0", "artifacts": { "MyStackName": { "type": "aws:cloudformation:stack", diff --git a/packages/@aws-cdk/cx-api/test/fixtures/single-stack/manifest.json b/packages/@aws-cdk/cx-api/test/fixtures/single-stack/manifest.json index 09d0cae2be4e1..52431c4ec78f0 100644 --- a/packages/@aws-cdk/cx-api/test/fixtures/single-stack/manifest.json +++ b/packages/@aws-cdk/cx-api/test/fixtures/single-stack/manifest.json @@ -1,5 +1,5 @@ { - "version": "0.33.0", + "version": "0.34.0", "artifacts": { "MyStackName": { "type": "aws:cloudformation:stack", diff --git a/packages/@aws-cdk/cx-api/test/fixtures/stack-without-params/manifest.json b/packages/@aws-cdk/cx-api/test/fixtures/stack-without-params/manifest.json index fd4bbfc3da8fb..1a13623b27127 100644 --- a/packages/@aws-cdk/cx-api/test/fixtures/stack-without-params/manifest.json +++ b/packages/@aws-cdk/cx-api/test/fixtures/stack-without-params/manifest.json @@ -1,5 +1,5 @@ { - "version": "0.33.0", + "version": "0.34.0", "artifacts": { "MyStackName": { "type": "aws:cloudformation:stack", diff --git a/packages/aws-cdk/lib/api/cxapp/stacks.ts b/packages/aws-cdk/lib/api/cxapp/stacks.ts index f1341bcbaadf3..2efe3a97179e1 100644 --- a/packages/aws-cdk/lib/api/cxapp/stacks.ts +++ b/packages/aws-cdk/lib/api/cxapp/stacks.ts @@ -91,10 +91,10 @@ export class AppStacks { if (selectors.length === 0) { // remove non-auto deployed Stacks - const visibleStacks = stacks.filter(s => !s.manifest.hidden); - debug('Stack name not specified, so defaulting to all available stacks: ' + listStackNames(visibleStacks)); - this.applyRenames(visibleStacks); - return visibleStacks; + const entrypoints = stacks.filter(s => s.entrypoint); + debug('Stack name not specified, so defaulting to all available stacks: ' + listStackNames(entrypoints)); + this.applyRenames(entrypoints); + return entrypoints; } const allStacks = new Map(); @@ -177,10 +177,10 @@ export class AppStacks { while (true) { const assembly = await this.props.synthesizer(this.props.aws, this.props.configuration); - if (assembly.missing) { + if (assembly.manifest.missing) { debug(`Some context information is missing. Fetching...`); - await contextproviders.provideContextValues(assembly.missing, this.props.configuration.context, this.props.aws); + await contextproviders.provideContextValues(assembly.manifest.missing, this.props.configuration.context, this.props.aws); // Cache the new context to disk await this.props.configuration.saveContext(); diff --git a/packages/aws-cdk/lib/context-providers/index.ts b/packages/aws-cdk/lib/context-providers/index.ts index 898874be1778f..f885d588b5929 100644 --- a/packages/aws-cdk/lib/context-providers/index.ts +++ b/packages/aws-cdk/lib/context-providers/index.ts @@ -15,12 +15,11 @@ export type ProviderMap = {[name: string]: ProviderConstructor}; * Iterate over the list of missing context values and invoke the appropriate providers from the map to retrieve them */ export async function provideContextValues( - missingValues: { [key: string]: cxapi.MissingContext }, + missingValues: cxapi.MissingContext[], context: Context, sdk: SDK) { - for (const key of Object.keys(missingValues)) { - const missingContext = missingValues[key]; - + for (const missingContext of missingValues) { + const key = missingContext.key; const constructor = availableContextProviders[missingContext.provider]; if (!constructor) { // tslint:disable-next-line:max-line-length diff --git a/packages/aws-cdk/test/api/test.stacks.ts b/packages/aws-cdk/test/api/test.stacks.ts index 6977a5ddc0ba4..2e82aa7ac1bf6 100644 --- a/packages/aws-cdk/test/api/test.stacks.ts +++ b/packages/aws-cdk/test/api/test.stacks.ts @@ -12,7 +12,7 @@ const FIXED_RESULT = testAssembly({ }, { stackName: 'witherrors', - hidden: false, + entrypoint: true, template: { resource: 'errorresource' }, metadata: { '/resource': [ @@ -86,7 +86,7 @@ export = { { stackName: 'NotAutoDeployedStack', template: { resource: 'Resource' }, - hidden: true, + entrypoint: false, }, ]); @@ -105,7 +105,7 @@ export = { { stackName: 'NotAutoDeployedStack', template: { resource: 'Resource' }, - hidden: true, + entrypoint: false, }, ]); @@ -124,11 +124,10 @@ export = { { stackName: 'NotAutoDeployedStack', template: { resource: 'Resource' }, - hidden: true, + entrypoint: false, }, { stackName: 'AutoDeployedStack', - hidden: false, depends: [ 'NotAutoDeployedStack' ], template: { resource: 'Resource' }, }, diff --git a/packages/aws-cdk/test/util.ts b/packages/aws-cdk/test/util.ts index 60238ee581c64..72ac396210b5a 100644 --- a/packages/aws-cdk/test/util.ts +++ b/packages/aws-cdk/test/util.ts @@ -5,7 +5,7 @@ import path = require('path'); export interface TestStackArtifact { stackName: string; template: any; - hidden?: boolean; + entrypoint?: boolean; depends?: string[]; metadata?: cxapi.StackMetadata; assets?: cxapi.AssetMetadataEntry[]; @@ -29,13 +29,18 @@ export function testAssembly(...stacks: TestStackArtifact[]): cxapi.CloudAssembl builder.addArtifact(stack.stackName, { type: cxapi.ArtifactType.AwsCloudFormationStack, environment: 'aws://12345/here', - hidden: stack.hidden, + dependencies: stack.depends, metadata, properties: { templateFile } }); + + const entrypoint = stack.entrypoint === undefined ? true : stack.entrypoint; + if (entrypoint) { + builder.addEntrypoint(stack.stackName); + } } return builder.build(); From 7565b7e815705e9bbf3e7876d95c914e8a756c84 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 4 Jun 2019 14:27:11 +0300 Subject: [PATCH 03/17] CR fixes --- packages/@aws-cdk/assets/lib/staging.ts | 3 +- packages/@aws-cdk/assets/test/test.asset.ts | 6 ++- .../@aws-cdk/aws-ec2/lib/security-group.ts | 2 +- packages/@aws-cdk/cdk/lib/construct.ts | 53 ++++++++++--------- packages/@aws-cdk/cdk/lib/stack.ts | 2 +- 5 files changed, 35 insertions(+), 31 deletions(-) diff --git a/packages/@aws-cdk/assets/lib/staging.ts b/packages/@aws-cdk/assets/lib/staging.ts index a851bc02f0026..92a07874b579d 100644 --- a/packages/@aws-cdk/assets/lib/staging.ts +++ b/packages/@aws-cdk/assets/lib/staging.ts @@ -67,12 +67,11 @@ export class Staging extends Construct { } public synthesize(session: ISynthesisSession) { - const assembly = session.assembly; if (!this.relativePath) { return; } - const targetPath = path.join(assembly.outdir, this.relativePath); + const targetPath = path.join(session.assembly.outdir, this.relativePath); // asset already staged if (fs.existsSync(targetPath)) { diff --git a/packages/@aws-cdk/assets/test/test.asset.ts b/packages/@aws-cdk/assets/test/test.asset.ts index 72100dc0bbad8..2712e7e4b4421 100644 --- a/packages/@aws-cdk/assets/test/test.asset.ts +++ b/packages/@aws-cdk/assets/test/test.asset.ts @@ -59,6 +59,8 @@ export = { const synth = app.synth().getStack(stack.name); const meta = synth.manifest.metadata || {}; + test.ok(meta['/my-stack/MyAsset']); + test.ok(meta['/my-stack/MyAsset'][0]); test.deepEqual(meta['/my-stack/MyAsset'][0].data, { path: 'asset.6b84b87243a4a01c592d78e1fd3855c4bfef39328cd0a450cc97e81717fea2a2', id: "mystackMyAssetD6B1B593", @@ -343,8 +345,8 @@ export = { // WHEN const session = app.synth(); const artifact = session.getStack(stack.name); - - const md = Object.values(artifact.manifest.metadata || {})[0][0].data; + const metadata = artifact.manifest.metadata || {}; + const md = Object.values(metadata)[0]![0]!.data; test.deepEqual(md.path, 'asset.6b84b87243a4a01c592d78e1fd3855c4bfef39328cd0a450cc97e81717fea2a2'); test.done(); } diff --git a/packages/@aws-cdk/aws-ec2/lib/security-group.ts b/packages/@aws-cdk/aws-ec2/lib/security-group.ts index 4ff6120715b49..d9023fb37b889 100644 --- a/packages/@aws-cdk/aws-ec2/lib/security-group.ts +++ b/packages/@aws-cdk/aws-ec2/lib/security-group.ts @@ -4,7 +4,7 @@ import { CfnSecurityGroup, CfnSecurityGroupEgress, CfnSecurityGroupIngress } fro import { IPortRange, ISecurityGroupRule } from './security-group-rule'; import { IVpc } from './vpc'; -const SECURITY_GROUP_SYMBOL = Symbol.for('aws-cdk:isSecurityGroup'); +const SECURITY_GROUP_SYMBOL = Symbol.for('@aws-cdk/iam.SecurityGroup'); export interface ISecurityGroup extends IResource, ISecurityGroupRule, IConnectable { /** diff --git a/packages/@aws-cdk/cdk/lib/construct.ts b/packages/@aws-cdk/cdk/lib/construct.ts index 91f5ef6127ab3..e2c7f9afb8704 100644 --- a/packages/@aws-cdk/cdk/lib/construct.ts +++ b/packages/@aws-cdk/cdk/lib/construct.ts @@ -19,30 +19,6 @@ export interface IConstruct extends IDependable { readonly node: ConstructNode; } -export interface ISynthesisSession { - /** - * The cloud assembly being synthesized. - */ - assembly: cxapi.CloudAssemblyBuilder; -} - -/** - * Options for synthesis. - */ -export interface SynthesisOptions extends cxapi.AssemblyBuildOptions { - /** - * The output directory into which to synthesize the cloud assembly. - * @default - creates a temporary directory - */ - readonly outdir?: string; - - /** - * Whether synthesis should skip the validation phase. - * @default false - */ - readonly skipValidation?: boolean; -} - /** * Represents the construct node in the scope tree. */ @@ -218,7 +194,7 @@ export class ConstructNode { } const parts = path.split(ConstructNode.PATH_SEP); - let curr: Construct|undefined = this.host; + let curr: Construct | undefined = this.host; while (curr != null && parts.length > 0) { curr = curr.node._children[parts.shift()!]; } @@ -801,6 +777,33 @@ export interface OutgoingReference { readonly reference: Reference; } +/** + * Represents a single session of synthesis. Passed into `Construct.synthesize()` methods. + */ +export interface ISynthesisSession { + /** + * The cloud assembly being synthesized. + */ + assembly: cxapi.CloudAssemblyBuilder; +} + +/** + * Options for synthesis. + */ +export interface SynthesisOptions extends cxapi.AssemblyBuildOptions { + /** + * The output directory into which to synthesize the cloud assembly. + * @default - creates a temporary directory + */ + readonly outdir?: string; + + /** + * Whether synthesis should skip the validation phase. + * @default false + */ + readonly skipValidation?: boolean; +} + function ignore(_x: any) { return; } diff --git a/packages/@aws-cdk/cdk/lib/stack.ts b/packages/@aws-cdk/cdk/lib/stack.ts index bef0750154ee5..9a976b472b9e7 100644 --- a/packages/@aws-cdk/cdk/lib/stack.ts +++ b/packages/@aws-cdk/cdk/lib/stack.ts @@ -100,7 +100,7 @@ export class Stack extends Construct implements ITaggable { * Indicates if this stack is an entrypoint, which means that it won't be * automatically deployed when running `cdk deploy` without arguments. */ - public readonly entrypoint: boolean; + private readonly entrypoint: boolean; /** * Other stacks this stack depends on From d9cb6f399bd4d9778a19a22e540961749625b3f3 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 4 Jun 2019 15:08:42 +0300 Subject: [PATCH 04/17] additional fixes --- packages/@aws-cdk/aws-lambda/test/test.code.ts | 7 +++++-- .../aws-route53/test/test.hosted-zone-provider.ts | 7 +++++-- packages/@aws-cdk/cdk/lib/construct.ts | 14 +++++++------- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/packages/@aws-cdk/aws-lambda/test/test.code.ts b/packages/@aws-cdk/aws-lambda/test/test.code.ts index 824ca6dc3c2a0..29b21b0a66cf6 100644 --- a/packages/@aws-cdk/aws-lambda/test/test.code.ts +++ b/packages/@aws-cdk/aws-lambda/test/test.code.ts @@ -67,8 +67,11 @@ export = { const synthesized = assembly.stacks[0]; // Func1 has an asset, Func2 does not - test.deepEqual(synthesized.metadata['/MyStack/Func1/Code'][0].type, 'aws:cdk:asset'); - test.deepEqual(synthesized.metadata['/MyStack/Func2/Code'], undefined); + const metadata = synthesized.manifest.metadata || {}; + test.ok(metadata['/MyStack/Func1/Code']); + test.deepEqual(metadata['/MyStack/Func1/Code'].length, 1); + test.deepEqual(metadata['/MyStack/Func1/Code'][0].type, 'aws:cdk:asset'); + test.deepEqual(metadata['/MyStack/Func2/Code'], undefined); test.done(); }, diff --git a/packages/@aws-cdk/aws-route53/test/test.hosted-zone-provider.ts b/packages/@aws-cdk/aws-route53/test/test.hosted-zone-provider.ts index 2a2e8e8bc5348..31c0eeb8f6185 100644 --- a/packages/@aws-cdk/aws-route53/test/test.hosted-zone-provider.ts +++ b/packages/@aws-cdk/aws-route53/test/test.hosted-zone-provider.ts @@ -1,3 +1,4 @@ +import { SynthUtils } from '@aws-cdk/assert'; import cdk = require('@aws-cdk/cdk'); import { Test } from 'nodeunit'; import { HostedZone, HostedZoneAttributes, HostedZoneProvider } from '../lib'; @@ -9,7 +10,9 @@ export = { const stack = new cdk.Stack(undefined, 'TestStack', { env: { account: '12345', region: 'us-east-1' } }); const filter = {domainName: 'test.com'}; new HostedZoneProvider(stack, filter).findHostedZone(); - const key = Object.keys(stack.missingContext)[0]; + + const missing = SynthUtils.synthesize(stack).assembly.manifest.missing!; + test.ok(missing && missing.length === 1); const fakeZone = { Id: "/hostedzone/11111111111111", @@ -22,7 +25,7 @@ export = { ResourceRecordSetCount: 3 }; - stack.node.setContext(key, fakeZone); + stack.node.setContext(missing[0].key, fakeZone); const cdkZoneProps: HostedZoneAttributes = { hostedZoneId: fakeZone.Id, diff --git a/packages/@aws-cdk/cdk/lib/construct.ts b/packages/@aws-cdk/cdk/lib/construct.ts index e2c7f9afb8704..412c67c986cb9 100644 --- a/packages/@aws-cdk/cdk/lib/construct.ts +++ b/packages/@aws-cdk/cdk/lib/construct.ts @@ -80,7 +80,7 @@ export class ConstructNode { /** * List of children and their names */ - private readonly _children: { [name: string]: Construct } = { }; + private readonly _children: { [name: string]: IConstruct } = { }; private readonly context: { [key: string]: any } = { }; private readonly _metadata = new Array(); private readonly references = new Set(); @@ -188,13 +188,13 @@ export class ConstructNode { * @param path Relative path of a direct or indirect child * @returns a child by path or undefined if not found. */ - public tryFindChild(path: string): Construct | undefined { + public tryFindChild(path: string): IConstruct | undefined { if (path.startsWith(ConstructNode.PATH_SEP)) { throw new Error('Path must be relative'); } const parts = path.split(ConstructNode.PATH_SEP); - let curr: Construct | undefined = this.host; + let curr: IConstruct | undefined = this.host; while (curr != null && parts.length > 0) { curr = curr.node._children[parts.shift()!]; } @@ -212,7 +212,7 @@ export class ConstructNode { * @param path Relative path of a direct or indirect child * @returns Child with the given path. */ - public findChild(path: string): Construct { + public findChild(path: string): IConstruct { const ret = this.tryFindChild(path); if (!ret) { throw new Error(`No child with path: '${path}'`); @@ -245,12 +245,12 @@ export class ConstructNode { /** * Return this construct and all of its children in the given order */ - public findAll(order: ConstructOrder = ConstructOrder.PreOrder): Construct[] { - const ret = new Array(); + public findAll(order: ConstructOrder = ConstructOrder.PreOrder): IConstruct[] { + const ret = new Array(); visit(this.host); return ret; - function visit(node: Construct) { + function visit(node: IConstruct) { if (order === ConstructOrder.PreOrder) { ret.push(node); } From 96be493e57054b8e5a5c548528fc20f8dfda70a9 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Tue, 4 Jun 2019 15:49:02 +0300 Subject: [PATCH 05/17] more fixes --- .../test/integ.lambda-deployed-through-codepipeline.lit.ts | 2 +- packages/decdk/bin/decdk.ts | 2 +- packages/decdk/package.json | 2 +- packages/decdk/test/synth.test.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts index 2ba724c3fd045..b3ed5a1b5d4b8 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts @@ -11,7 +11,7 @@ const app = new cdk.App(); const lambdaStack = new cdk.Stack(app, 'LambdaStack', { // remove the Stack from `cdk synth` and `cdk deploy` // unless you explicitly filter for it - autoDeploy: false, + entrypoint: false, }); const lambdaCode = lambda.Code.cfnParameters(); new lambda.Function(lambdaStack, 'Lambda', { diff --git a/packages/decdk/bin/decdk.ts b/packages/decdk/bin/decdk.ts index 20c0b036c2069..3fc504beceb10 100644 --- a/packages/decdk/bin/decdk.ts +++ b/packages/decdk/bin/decdk.ts @@ -16,7 +16,7 @@ async function main() { const app = new cdk.App(); new DeclarativeStack(app, stackName, { template, typeSystem }); - app.run(); + app.synth(); } main().catch(e => { diff --git a/packages/decdk/package.json b/packages/decdk/package.json index ab67e091af73d..1f4f8f272e707 100644 --- a/packages/decdk/package.json +++ b/packages/decdk/package.json @@ -154,4 +154,4 @@ "engines": { "node": ">= 8.10.0" } -} +} \ No newline at end of file diff --git a/packages/decdk/test/synth.test.ts b/packages/decdk/test/synth.test.ts index 27820793c8ee0..cbbf19713b839 100644 --- a/packages/decdk/test/synth.test.ts +++ b/packages/decdk/test/synth.test.ts @@ -40,7 +40,7 @@ for (const templateFile of fs.readdirSync(dir)) { typeSystem }); - const output = app.run().getStack(stackName); + const output = app.synth().getStack(stackName); expect(output.template).toMatchSnapshot(stackName); }); } From 27959e6486e8ec2257c31adc2fefcd872d86ff77 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 5 Jun 2019 09:50:07 +0300 Subject: [PATCH 06/17] remove "entrypoints" (autoDeploy) --- ...ambda-deployed-through-codepipeline.lit.ts | 6 +---- packages/@aws-cdk/cdk/lib/stack.ts | 27 ++----------------- packages/@aws-cdk/cdk/test/test.synthesis.ts | 1 - .../@aws-cdk/cx-api/lib/cloud-artifact.ts | 6 ----- .../@aws-cdk/cx-api/lib/cloud-assembly.ts | 18 ------------- packages/aws-cdk/lib/api/cxapp/stacks.ts | 7 +++-- packages/aws-cdk/test/api/test.stacks.ts | 4 --- packages/aws-cdk/test/util.ts | 6 ----- 8 files changed, 6 insertions(+), 69 deletions(-) diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts index b3ed5a1b5d4b8..2b5382ae73633 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts @@ -8,11 +8,7 @@ import codepipeline_actions = require('../lib'); const app = new cdk.App(); /// !show -const lambdaStack = new cdk.Stack(app, 'LambdaStack', { - // remove the Stack from `cdk synth` and `cdk deploy` - // unless you explicitly filter for it - entrypoint: false, -}); +const lambdaStack = new cdk.Stack(app, 'LambdaStack'); const lambdaCode = lambda.Code.cfnParameters(); new lambda.Function(lambdaStack, 'Lambda', { code: lambdaCode, diff --git a/packages/@aws-cdk/cdk/lib/stack.ts b/packages/@aws-cdk/cdk/lib/stack.ts index 9a976b472b9e7..bfabcaeac51ee 100644 --- a/packages/@aws-cdk/cdk/lib/stack.ts +++ b/packages/@aws-cdk/cdk/lib/stack.ts @@ -8,6 +8,8 @@ import { Environment } from './environment'; import { HashedAddressingScheme, IAddressingScheme, LogicalIDs } from './logical-id'; import { makeUniqueId } from './uniqueid'; +const STACK_SYMBOL = Symbol.for('@aws-cdk/cdk.Stack'); + export interface StackProps { /** * The AWS environment (account/region) where this stack will be deployed. @@ -31,18 +33,6 @@ export interface StackProps { */ readonly namingScheme?: IAddressingScheme; - /** - * Indicates if this stack is an entrypoint of your app, which means that it - * will be automatically deployed when running `cdk deploy` without arguments. - * - * Setting this to `false` is useful when you have a stack in your CDK app - * which you don't want to deploy using the CDK toolkit. For example, because - * you're planning on deploying it through a deployment pipeline. - * - * @default true - */ - readonly entrypoint?: boolean; - /** * Stack tags that will be applied to all the taggable resources and the stack itself. * @@ -51,8 +41,6 @@ export interface StackProps { readonly tags?: { [key: string]: string }; } -const STACK_SYMBOL = Symbol.for('@aws-cdk/cdk.Stack'); - /** * A root construct which represents a single CloudFormation stack. */ @@ -96,12 +84,6 @@ export class Stack extends Construct implements ITaggable { */ public readonly name: string; - /** - * Indicates if this stack is an entrypoint, which means that it won't be - * automatically deployed when running `cdk deploy` without arguments. - */ - private readonly entrypoint: boolean; - /** * Other stacks this stack depends on */ @@ -144,7 +126,6 @@ export class Stack extends Construct implements ITaggable { this.logicalIds = new LogicalIDs(props.namingScheme ? props.namingScheme : new HashedAddressingScheme()); this.name = props.stackName !== undefined ? props.stackName : this.calculateStackName(); - this.entrypoint = props.entrypoint === undefined ? true : false; this.tags = new TagManager(TagType.KeyValue, 'aws:cdk:stack', props.tags); if (!Stack.VALID_STACK_NAME_REGEX.test(this.name)) { @@ -521,10 +502,6 @@ export class Stack extends Construct implements ITaggable { for (const ctx of this.missingContext) { builder.addMissing(ctx); } - - if (this.entrypoint) { - builder.addEntrypoint(this.name); - } } /** diff --git a/packages/@aws-cdk/cdk/test/test.synthesis.ts b/packages/@aws-cdk/cdk/test/test.synthesis.ts index 7cf6b7b20ae80..bd7aa617d7b4e 100644 --- a/packages/@aws-cdk/cdk/test/test.synthesis.ts +++ b/packages/@aws-cdk/cdk/test/test.synthesis.ts @@ -79,7 +79,6 @@ export = { test.deepEqual(readJson(session.directory, 'foo.json'), { bar: 123 }); test.deepEqual(session.manifest, { version: '0.34.0', - entrypoints: [ 'one-stack' ], artifacts: { 'my-random-construct': { type: 'aws:cloudformation:stack', diff --git a/packages/@aws-cdk/cx-api/lib/cloud-artifact.ts b/packages/@aws-cdk/cx-api/lib/cloud-artifact.ts index 7e1a01b75b443..662152284dd74 100644 --- a/packages/@aws-cdk/cx-api/lib/cloud-artifact.ts +++ b/packages/@aws-cdk/cx-api/lib/cloud-artifact.ts @@ -101,11 +101,6 @@ export class CloudArtifact { */ public readonly environment: Environment; - /** - * Indicates if this artifact is an entrypoint of the assembly. - */ - public readonly entrypoint: boolean; - /** * IDs of all dependencies. Used when topologically sorting the artifacts within the cloud assembly. * @internal @@ -122,7 +117,6 @@ export class CloudArtifact { this.environment = EnvironmentUtils.parse(manifest.environment); this.messages = this.renderMessages(); this._dependencyIDs = manifest.dependencies || []; - this.entrypoint = (assembly.manifest.entrypoints || []).includes(id); } /** diff --git a/packages/@aws-cdk/cx-api/lib/cloud-assembly.ts b/packages/@aws-cdk/cx-api/lib/cloud-assembly.ts index 2ab7e7184110a..912eceabeb013 100644 --- a/packages/@aws-cdk/cx-api/lib/cloud-assembly.ts +++ b/packages/@aws-cdk/cx-api/lib/cloud-assembly.ts @@ -20,12 +20,6 @@ export interface AssemblyManifest { */ readonly artifacts?: { [id: string]: ArtifactManifest }; - /** - * A list of artifact IDs that are entrypoints of this app. Entrypoints will - * automatically be deployed when running "cdk deploy". - */ - readonly entrypoints?: string[]; - /** * Missing context information. If this field has values, it means that the * cloud assembly is not complete and should not be deployed. @@ -157,7 +151,6 @@ export class CloudAssemblyBuilder { public readonly outdir: string; private readonly artifacts: { [id: string]: ArtifactManifest } = { }; - private readonly entrypoints = new Array(); private readonly missing = new Array(); /** @@ -190,16 +183,6 @@ export class CloudAssemblyBuilder { this.artifacts[id] = filterUndefined(manifest); } - /** - * Marks an artifact as an entrypoint, which means that it will be automatically - * deployed with "cdk deploy". - * - * @param id The ID of the artifact. - */ - public addEntrypoint(id: string) { - this.entrypoints.push(id); - } - /** * Reports that some context is missing in order for this cloud assembly to be fully synthesized. * @param missing Missing context information. @@ -217,7 +200,6 @@ export class CloudAssemblyBuilder { const manifest: AssemblyManifest = filterUndefined({ version: CLOUD_ASSEMBLY_VERSION, artifacts: this.artifacts, - entrypoints: this.entrypoints.length > 0 ? this.entrypoints : undefined, runtime: options.runtimeInfo, missing: this.missing.length > 0 ? this.missing : undefined }); diff --git a/packages/aws-cdk/lib/api/cxapp/stacks.ts b/packages/aws-cdk/lib/api/cxapp/stacks.ts index 2efe3a97179e1..ce870249115e1 100644 --- a/packages/aws-cdk/lib/api/cxapp/stacks.ts +++ b/packages/aws-cdk/lib/api/cxapp/stacks.ts @@ -91,10 +91,9 @@ export class AppStacks { if (selectors.length === 0) { // remove non-auto deployed Stacks - const entrypoints = stacks.filter(s => s.entrypoint); - debug('Stack name not specified, so defaulting to all available stacks: ' + listStackNames(entrypoints)); - this.applyRenames(entrypoints); - return entrypoints; + debug('Stack name not specified, so defaulting to all available stacks: ' + listStackNames(stacks)); + this.applyRenames(stacks); + return stacks; } const allStacks = new Map(); diff --git a/packages/aws-cdk/test/api/test.stacks.ts b/packages/aws-cdk/test/api/test.stacks.ts index 2e82aa7ac1bf6..0a40e12e819a8 100644 --- a/packages/aws-cdk/test/api/test.stacks.ts +++ b/packages/aws-cdk/test/api/test.stacks.ts @@ -12,7 +12,6 @@ const FIXED_RESULT = testAssembly({ }, { stackName: 'witherrors', - entrypoint: true, template: { resource: 'errorresource' }, metadata: { '/resource': [ @@ -86,7 +85,6 @@ export = { { stackName: 'NotAutoDeployedStack', template: { resource: 'Resource' }, - entrypoint: false, }, ]); @@ -105,7 +103,6 @@ export = { { stackName: 'NotAutoDeployedStack', template: { resource: 'Resource' }, - entrypoint: false, }, ]); @@ -124,7 +121,6 @@ export = { { stackName: 'NotAutoDeployedStack', template: { resource: 'Resource' }, - entrypoint: false, }, { stackName: 'AutoDeployedStack', diff --git a/packages/aws-cdk/test/util.ts b/packages/aws-cdk/test/util.ts index 72ac396210b5a..ff725a322f990 100644 --- a/packages/aws-cdk/test/util.ts +++ b/packages/aws-cdk/test/util.ts @@ -5,7 +5,6 @@ import path = require('path'); export interface TestStackArtifact { stackName: string; template: any; - entrypoint?: boolean; depends?: string[]; metadata?: cxapi.StackMetadata; assets?: cxapi.AssetMetadataEntry[]; @@ -36,11 +35,6 @@ export function testAssembly(...stacks: TestStackArtifact[]): cxapi.CloudAssembl templateFile } }); - - const entrypoint = stack.entrypoint === undefined ? true : stack.entrypoint; - if (entrypoint) { - builder.addEntrypoint(stack.stackName); - } } return builder.build(); From 7ae9720af2c9ee1bcce732d56e307fc0efe8942c Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 5 Jun 2019 09:59:12 +0300 Subject: [PATCH 07/17] fix tests --- packages/aws-cdk/test/api/test.stacks.ts | 70 +----------------------- 1 file changed, 1 insertion(+), 69 deletions(-) diff --git a/packages/aws-cdk/test/api/test.stacks.ts b/packages/aws-cdk/test/api/test.stacks.ts index 0a40e12e819a8..54ad8355379e1 100644 --- a/packages/aws-cdk/test/api/test.stacks.ts +++ b/packages/aws-cdk/test/api/test.stacks.ts @@ -4,7 +4,7 @@ import { SDK } from '../../lib'; import { AppStacks, ExtendedStackSelection } from '../../lib/api/cxapp/stacks'; import { Renames } from '../../lib/renames'; import { Configuration } from '../../lib/settings'; -import { testAssembly, TestStackArtifact } from '../util'; +import { testAssembly } from '../util'; const FIXED_RESULT = testAssembly({ stackName: 'withouterrors', @@ -78,72 +78,4 @@ export = { test.done(); }, - - async 'does not return non-autoDeployed Stacks when called without any selectors'(test: Test) { - // GIVEN - const stacks = appStacksWith([ - { - stackName: 'NotAutoDeployedStack', - template: { resource: 'Resource' }, - }, - ]); - - // WHEN - const synthed = await stacks.selectStacks([], ExtendedStackSelection.None); - - // THEN - test.equal(synthed.length, 0); - - test.done(); - }, - - async 'does return non-autoDeployed Stacks when called with selectors matching it'(test: Test) { - // GIVEN - const stacks = appStacksWith([ - { - stackName: 'NotAutoDeployedStack', - template: { resource: 'Resource' }, - }, - ]); - - // WHEN - const synthed = await stacks.selectStacks(['NotAutoDeployedStack'], ExtendedStackSelection.None); - - // THEN - test.equal(synthed.length, 1); - - test.done(); - }, - - async "does return an non-autoDeployed Stack when it's a dependency of a selected Stack"(test: Test) { - // GIVEN - const stacks = appStacksWith([ - { - stackName: 'NotAutoDeployedStack', - template: { resource: 'Resource' }, - }, - { - stackName: 'AutoDeployedStack', - depends: [ 'NotAutoDeployedStack' ], - template: { resource: 'Resource' }, - }, - ]); - - // WHEN - const synthed = await stacks.selectStacks(['AutoDeployedStack'], ExtendedStackSelection.Upstream); - - // THEN - test.equal(synthed.length, 2); - - test.done(); - }, }; - -function appStacksWith(stacks: TestStackArtifact[]): AppStacks { - const assembly = testAssembly(...stacks); - return new AppStacks({ - configuration: new Configuration(), - aws: new SDK(), - synthesizer: async () => assembly, - }); -} From 731cf646d57f2de8a7fa58a8b56f88e4b8e2b87e Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 5 Jun 2019 10:51:59 +0300 Subject: [PATCH 08/17] fix integ test --- .../aws-events-targets/test/sqs/integ.sqs-event-rule-target.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-events-targets/test/sqs/integ.sqs-event-rule-target.ts b/packages/@aws-cdk/aws-events-targets/test/sqs/integ.sqs-event-rule-target.ts index f94b83deee11a..c45554ca0c51c 100644 --- a/packages/@aws-cdk/aws-events-targets/test/sqs/integ.sqs-event-rule-target.ts +++ b/packages/@aws-cdk/aws-events-targets/test/sqs/integ.sqs-event-rule-target.ts @@ -19,4 +19,4 @@ const event = new events.Rule(stack, 'MyRule', { const queue = new sqs.Queue(stack, 'MyQueue'); event.addTarget(new targets.SqsQueue(queue)); -app.run(); +app.synth(); From c2cdd309e8cde48aee44cb3106fdc68844affcb4 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 5 Jun 2019 15:05:29 +0300 Subject: [PATCH 09/17] allow integ tests to specify which stack to deploy --- ...ambda-deployed-through-codepipeline.lit.ts | 1 + tools/cdk-integ-tools/bin/cdk-integ-assert.ts | 3 +- tools/cdk-integ-tools/bin/cdk-integ.ts | 7 ++- tools/cdk-integ-tools/lib/integ-helpers.ts | 55 +++++++++++++++++++ 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts index 2b5382ae73633..aeece6fd9797c 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts @@ -1,3 +1,4 @@ +/// !cdk-integ:stack PipelineStack import codebuild = require('@aws-cdk/aws-codebuild'); import codecommit = require('@aws-cdk/aws-codecommit'); import codepipeline = require('@aws-cdk/aws-codepipeline'); diff --git a/tools/cdk-integ-tools/bin/cdk-integ-assert.ts b/tools/cdk-integ-tools/bin/cdk-integ-assert.ts index 993d3f7d6260c..4533de582c87f 100644 --- a/tools/cdk-integ-tools/bin/cdk-integ-assert.ts +++ b/tools/cdk-integ-tools/bin/cdk-integ-assert.ts @@ -16,6 +16,7 @@ async function main() { throw new Error(`No such file: ${test.expectedFileName}. Run 'npm run integ'.`); } + const stackToDeploy = await test.determineTestStack(); const expected = await test.readExpected(); const args = new Array(); @@ -23,7 +24,7 @@ async function main() { args.push('--no-asset-metadata'); args.push('--no-staging'); - const actual = await test.invoke(['--json', ...args, 'synth'], { json: true, context: STATIC_TEST_CONTEXT }); + const actual = await test.invoke(['--json', ...args, 'synth', stackToDeploy], { json: true, context: STATIC_TEST_CONTEXT }); const diff = diffTemplate(expected, actual); diff --git a/tools/cdk-integ-tools/bin/cdk-integ.ts b/tools/cdk-integ-tools/bin/cdk-integ.ts index 8eed72579a672..9885b4b5603b3 100644 --- a/tools/cdk-integ-tools/bin/cdk-integ.ts +++ b/tools/cdk-integ-tools/bin/cdk-integ.ts @@ -23,6 +23,9 @@ async function main() { for (const test of tests) { console.error(`Trying to deploy ${test.name}`); + const stackToDeploy = await test.determineTestStack(); + console.error(`Selected stack: ${stackToDeploy}`); + const args = new Array(); // don't inject cloudformation metadata into template @@ -37,12 +40,12 @@ async function main() { try { // tslint:disable-next-line:max-line-length - await test.invoke([ ...args, 'deploy', '--require-approval', 'never' ], { verbose: argv.verbose }); // Note: no context, so use default user settings! + await test.invoke([ ...args, 'deploy', '--require-approval', 'never', stackToDeploy ], { verbose: argv.verbose }); // Note: no context, so use default user settings! console.error(`Success! Writing out reference synth.`); // If this all worked, write the new expectation file - const actual = await test.invoke([ ...args, '--json', 'synth' ], { + const actual = await test.invoke([ ...args, '--json', 'synth', stackToDeploy ], { json: true, context: STATIC_TEST_CONTEXT, verbose: argv.verbose diff --git a/tools/cdk-integ-tools/lib/integ-helpers.ts b/tools/cdk-integ-tools/lib/integ-helpers.ts index b250790c269a8..a7585d92d1c79 100644 --- a/tools/cdk-integ-tools/lib/integ-helpers.ts +++ b/tools/cdk-integ-tools/lib/integ-helpers.ts @@ -7,6 +7,7 @@ import util = require('util'); const stat = util.promisify(fs.stat); const readdir = util.promisify(fs.readdir); +const CDK_INTEG_STACK_PRAGMA = '/// !cdk-integ:stack'; export class IntegrationTests { constructor(private readonly directory: string) { @@ -14,6 +15,8 @@ export class IntegrationTests { public async fromCliArgs(tests?: string[]): Promise { let allTests = await this.discover(); + const all = allTests.map(x => x.name); + let foundAll = true; if (tests && tests.length > 0) { // Pare down found tests to filter @@ -22,9 +25,15 @@ export class IntegrationTests { const selectedNames = allTests.map(t => t.name); for (const unmatched of tests.filter(t => !selectedNames.includes(t))) { process.stderr.write(`No such integ test: ${unmatched}\n`); + foundAll = false; } } + if (!foundAll) { + process.stderr.write(`Available tests: ${all.join(' ')}\n`); + return []; + } + return allTests; } @@ -62,11 +71,13 @@ export class IntegrationTest { public readonly expectedFileName: string; private readonly expectedFilePath: string; private readonly cdkContextPath: string; + private readonly sourceFilePath: string; constructor(private readonly directory: string, public readonly name: string) { const baseName = this.name.endsWith('.js') ? this.name.substr(0, this.name.length - 3) : this.name; this.expectedFileName = baseName + '.expected.json'; this.expectedFilePath = path.join(this.directory, this.expectedFileName); + this.sourceFilePath = path.join(this.directory, this.name); this.cdkContextPath = path.join(this.directory, 'cdk.context.json'); } @@ -95,6 +106,31 @@ export class IntegrationTest { return fs.existsSync(this.expectedFilePath); } + /** + * Returns the single test stack to use. + * + * If the test has a single stack, it will be chosen. Otherwise a pragma is expected within the + * test file the name of the stack: + * + * @example + * + * /// !cdk-integ:stack + * + */ + public async determineTestStack() { + const pragma = (await this.readStackPragma()); + const availableStacks = (await this.invoke([ 'ls' ])).split('\n'); + const selectedStacks = availableStacks.filter((x: any) => pragma ? x === pragma : x); + if (selectedStacks.length !== 1) { + throw new Error(`"cdk-integ" can only operate on apps with a single stack.\n\n` + + ` If your app has multiple stacks, specify which stack to select by adding this to your test source:\n\n` + + ` ${CDK_INTEG_STACK_PRAGMA} \n\n` + + ` Available stacks: ${availableStacks.join(' ')}\n`); + } + + return selectedStacks[0]; + } + public async readExpected(): Promise { return JSON.parse((await util.promisify(fs.readFile)(this.expectedFilePath, { encoding: 'utf-8' }))); } @@ -112,6 +148,25 @@ export class IntegrationTest { fs.unlinkSync(this.cdkContextPath); } } + + /** + * Reads the test source file and looks for the "!cdk-integ" pragma. If it exists, returns it's + * contents. This allows integ tests to supply custom command line arguments to "cdk deploy" and "cdk synth". + */ + private async readStackPragma(): Promise { + const source = await util.promisify(fs.readFile)(this.sourceFilePath, 'utf-8'); + const pragmaLine = source.split('\n').find(x => x.startsWith(CDK_INTEG_STACK_PRAGMA)); + if (!pragmaLine) { + return undefined; + } + + const args = pragmaLine.substring(CDK_INTEG_STACK_PRAGMA.length).trim().split(' '); + if (args.length !== 1) { + throw new Error(`Syntax of stack pragma in test code: ${CDK_INTEG_STACK_PRAGMA} `); + } + + return args[0]; + } } // Default context we run all integ tests with, so they don't depend on the From 0dc7bef563564bd50637455817aa600cbcc52430 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 5 Jun 2019 15:54:34 +0300 Subject: [PATCH 10/17] fix kms test and be less opinionated --- ...ambda-deployed-through-codepipeline.lit.ts | 2 +- .../aws-kms/test/integ.key-sharing.lit.ts | 1 + tools/cdk-integ-tools/bin/cdk-integ-assert.ts | 2 +- tools/cdk-integ-tools/bin/cdk-integ.ts | 4 +-- tools/cdk-integ-tools/lib/integ-helpers.ts | 34 ++++++++++--------- 5 files changed, 23 insertions(+), 20 deletions(-) diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts index aeece6fd9797c..88b1ba9db4698 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts @@ -1,4 +1,4 @@ -/// !cdk-integ:stack PipelineStack +/// !cdk-integ PipelineStack import codebuild = require('@aws-cdk/aws-codebuild'); import codecommit = require('@aws-cdk/aws-codecommit'); import codepipeline = require('@aws-cdk/aws-codepipeline'); diff --git a/packages/@aws-cdk/aws-kms/test/integ.key-sharing.lit.ts b/packages/@aws-cdk/aws-kms/test/integ.key-sharing.lit.ts index 8889a2902f929..4c2fcbacc9ad7 100644 --- a/packages/@aws-cdk/aws-kms/test/integ.key-sharing.lit.ts +++ b/packages/@aws-cdk/aws-kms/test/integ.key-sharing.lit.ts @@ -1,3 +1,4 @@ +/// !cdk-integ * import cdk = require('@aws-cdk/cdk'); import kms = require('../lib'); diff --git a/tools/cdk-integ-tools/bin/cdk-integ-assert.ts b/tools/cdk-integ-tools/bin/cdk-integ-assert.ts index 4533de582c87f..c6d27bb0dbf39 100644 --- a/tools/cdk-integ-tools/bin/cdk-integ-assert.ts +++ b/tools/cdk-integ-tools/bin/cdk-integ-assert.ts @@ -24,7 +24,7 @@ async function main() { args.push('--no-asset-metadata'); args.push('--no-staging'); - const actual = await test.invoke(['--json', ...args, 'synth', stackToDeploy], { json: true, context: STATIC_TEST_CONTEXT }); + const actual = await test.invoke(['--json', ...args, 'synth', ...stackToDeploy], { json: true, context: STATIC_TEST_CONTEXT }); const diff = diffTemplate(expected, actual); diff --git a/tools/cdk-integ-tools/bin/cdk-integ.ts b/tools/cdk-integ-tools/bin/cdk-integ.ts index 9885b4b5603b3..11d07aa338d80 100644 --- a/tools/cdk-integ-tools/bin/cdk-integ.ts +++ b/tools/cdk-integ-tools/bin/cdk-integ.ts @@ -40,12 +40,12 @@ async function main() { try { // tslint:disable-next-line:max-line-length - await test.invoke([ ...args, 'deploy', '--require-approval', 'never', stackToDeploy ], { verbose: argv.verbose }); // Note: no context, so use default user settings! + await test.invoke([ ...args, 'deploy', '--require-approval', 'never', ...stackToDeploy ], { verbose: argv.verbose }); // Note: no context, so use default user settings! console.error(`Success! Writing out reference synth.`); // If this all worked, write the new expectation file - const actual = await test.invoke([ ...args, '--json', 'synth', stackToDeploy ], { + const actual = await test.invoke([ ...args, '--json', 'synth', ...stackToDeploy ], { json: true, context: STATIC_TEST_CONTEXT, verbose: argv.verbose diff --git a/tools/cdk-integ-tools/lib/integ-helpers.ts b/tools/cdk-integ-tools/lib/integ-helpers.ts index a7585d92d1c79..4a8e3fb05e14f 100644 --- a/tools/cdk-integ-tools/lib/integ-helpers.ts +++ b/tools/cdk-integ-tools/lib/integ-helpers.ts @@ -7,7 +7,7 @@ import util = require('util'); const stat = util.promisify(fs.stat); const readdir = util.promisify(fs.readdir); -const CDK_INTEG_STACK_PRAGMA = '/// !cdk-integ:stack'; +const CDK_INTEG_STACK_PRAGMA = '/// !cdk-integ'; export class IntegrationTests { constructor(private readonly directory: string) { @@ -114,21 +114,24 @@ export class IntegrationTest { * * @example * - * /// !cdk-integ:stack + * /// !cdk-integ * */ - public async determineTestStack() { + public async determineTestStack(): Promise { const pragma = (await this.readStackPragma()); - const availableStacks = (await this.invoke([ 'ls' ])).split('\n'); - const selectedStacks = availableStacks.filter((x: any) => pragma ? x === pragma : x); - if (selectedStacks.length !== 1) { + if (pragma.length > 0) { + return pragma; + } + + const stacks = (await this.invoke([ 'ls' ])).split('\n'); + if (stacks.length !== 1) { throw new Error(`"cdk-integ" can only operate on apps with a single stack.\n\n` + ` If your app has multiple stacks, specify which stack to select by adding this to your test source:\n\n` + - ` ${CDK_INTEG_STACK_PRAGMA} \n\n` + - ` Available stacks: ${availableStacks.join(' ')}\n`); + ` ${CDK_INTEG_STACK_PRAGMA} STACK ...\n\n` + + ` Available stacks: ${stacks.join(' ')} (wildcards are also supported)\n`); } - return selectedStacks[0]; + return stacks; } public async readExpected(): Promise { @@ -153,19 +156,18 @@ export class IntegrationTest { * Reads the test source file and looks for the "!cdk-integ" pragma. If it exists, returns it's * contents. This allows integ tests to supply custom command line arguments to "cdk deploy" and "cdk synth". */ - private async readStackPragma(): Promise { + private async readStackPragma(): Promise { const source = await util.promisify(fs.readFile)(this.sourceFilePath, 'utf-8'); - const pragmaLine = source.split('\n').find(x => x.startsWith(CDK_INTEG_STACK_PRAGMA)); + const pragmaLine = source.split('\n').find(x => x.startsWith(CDK_INTEG_STACK_PRAGMA + ' ')); if (!pragmaLine) { - return undefined; + return []; } const args = pragmaLine.substring(CDK_INTEG_STACK_PRAGMA.length).trim().split(' '); - if (args.length !== 1) { - throw new Error(`Syntax of stack pragma in test code: ${CDK_INTEG_STACK_PRAGMA} `); + if (args.length === 0) { + throw new Error(`Invalid syntax for cdk-integ pragma. Usage: "${CDK_INTEG_STACK_PRAGMA} STACK ..."`); } - - return args[0]; + return args; } } From b758f231e7289e3439ee543eaefad80fecdf6ee1 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 5 Jun 2019 16:21:07 +0300 Subject: [PATCH 11/17] fix another multi-stack test --- .../@aws-cdk/aws-ssm/test/integ.parameter-store-string.lit.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/@aws-cdk/aws-ssm/test/integ.parameter-store-string.lit.ts b/packages/@aws-cdk/aws-ssm/test/integ.parameter-store-string.lit.ts index c5e22f975e0a3..f9e79e408af4e 100644 --- a/packages/@aws-cdk/aws-ssm/test/integ.parameter-store-string.lit.ts +++ b/packages/@aws-cdk/aws-ssm/test/integ.parameter-store-string.lit.ts @@ -1,3 +1,4 @@ +/// !cdk-integ * import cdk = require('@aws-cdk/cdk'); import ssm = require('../lib'); From 530fc3d769c3822f9078629b0fe31d617c033d56 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 5 Jun 2019 16:21:19 +0300 Subject: [PATCH 12/17] add a @deprecated "app.run()" --- packages/@aws-cdk/cdk/lib/app.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/@aws-cdk/cdk/lib/app.ts b/packages/@aws-cdk/cdk/lib/app.ts index ac15bb170ccda..feb26482cffc9 100644 --- a/packages/@aws-cdk/cdk/lib/app.ts +++ b/packages/@aws-cdk/cdk/lib/app.ts @@ -131,6 +131,13 @@ export class App extends Construct { return assembly; } + /** + * @deprecated use `synth()` + */ + public run() { + return this.synth(); + } + private loadContext(defaults: { [key: string]: string } = { }) { // prime with defaults passed through constructor for (const [ k, v ] of Object.entries(defaults)) { From e3a197c42faedf8b4324a216d83496a5b32182ec Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 5 Jun 2019 16:58:51 +0300 Subject: [PATCH 13/17] fix ec2 tests --- packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts | 1 + packages/@aws-cdk/aws-ec2/test/integ.share-vpcs.lit.ts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts b/packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts index 5f6b11de067c7..0bb6d9edd4193 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.import-default-vpc.lit.ts @@ -1,3 +1,4 @@ +/// !cdk-integ * import cdk = require('@aws-cdk/cdk'); import ec2 = require("../lib"); diff --git a/packages/@aws-cdk/aws-ec2/test/integ.share-vpcs.lit.ts b/packages/@aws-cdk/aws-ec2/test/integ.share-vpcs.lit.ts index f8372de4cacaf..af632fd9ffd4a 100644 --- a/packages/@aws-cdk/aws-ec2/test/integ.share-vpcs.lit.ts +++ b/packages/@aws-cdk/aws-ec2/test/integ.share-vpcs.lit.ts @@ -1,3 +1,4 @@ +/// !cdk-integ * import cdk = require('@aws-cdk/cdk'); import ec2 = require("../lib"); @@ -53,4 +54,4 @@ const stack2 = new Stack2(app, 'Stack2', { Array.isArray(stack2); -app.synth(); \ No newline at end of file +app.synth(); From 2461cdd04ccceadb2ee5c3fb6437c18ce712fe0d Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 5 Jun 2019 17:34:26 +0300 Subject: [PATCH 14/17] fix s3 test --- packages/@aws-cdk/aws-s3/test/integ.bucket-sharing.lit.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-s3/test/integ.bucket-sharing.lit.ts b/packages/@aws-cdk/aws-s3/test/integ.bucket-sharing.lit.ts index e85dadbab971c..c68f0039f36c0 100644 --- a/packages/@aws-cdk/aws-s3/test/integ.bucket-sharing.lit.ts +++ b/packages/@aws-cdk/aws-s3/test/integ.bucket-sharing.lit.ts @@ -1,3 +1,4 @@ +/// !cdk-integ * import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); import s3 = require('../lib'); @@ -42,4 +43,4 @@ const producer = new Producer(app, 'ProducerStack'); new Consumer(app, 'ConsumerStack', { userBucket: producer.myBucket }); /// !hide -app.synth(); \ No newline at end of file +app.synth(); From bbce0879039459dbf4b7ca8db0762e9b3648e884 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 5 Jun 2019 18:31:24 +0300 Subject: [PATCH 15/17] fix ddb global test --- .../@aws-cdk/aws-dynamodb-global/test/integ.dynamodb.global.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/@aws-cdk/aws-dynamodb-global/test/integ.dynamodb.global.ts b/packages/@aws-cdk/aws-dynamodb-global/test/integ.dynamodb.global.ts index 7497b17245e78..29dbbd0693823 100644 --- a/packages/@aws-cdk/aws-dynamodb-global/test/integ.dynamodb.global.ts +++ b/packages/@aws-cdk/aws-dynamodb-global/test/integ.dynamodb.global.ts @@ -1,3 +1,4 @@ +/// !cdk-integ * import { AttributeType } from '@aws-cdk/aws-dynamodb'; import { App } from '@aws-cdk/cdk'; import { GlobalTable } from '../lib'; From 0c4696eef1d7ac2a78e6e4bc216e4c62cc81f240 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 6 Jun 2019 00:25:35 +0300 Subject: [PATCH 16/17] inject static test context into "ls" --- tools/cdk-integ-tools/lib/integ-helpers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cdk-integ-tools/lib/integ-helpers.ts b/tools/cdk-integ-tools/lib/integ-helpers.ts index 4a8e3fb05e14f..7eec3a9250519 100644 --- a/tools/cdk-integ-tools/lib/integ-helpers.ts +++ b/tools/cdk-integ-tools/lib/integ-helpers.ts @@ -123,7 +123,7 @@ export class IntegrationTest { return pragma; } - const stacks = (await this.invoke([ 'ls' ])).split('\n'); + const stacks = (await this.invoke([ 'ls' ], { context: STATIC_TEST_CONTEXT })).split('\n'); if (stacks.length !== 1) { throw new Error(`"cdk-integ" can only operate on apps with a single stack.\n\n` + ` If your app has multiple stacks, specify which stack to select by adding this to your test source:\n\n` + From 1e1b192f106ea0af721048d62eb9a947106ba633 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 6 Jun 2019 01:18:17 +0300 Subject: [PATCH 17/17] Change back synthesize from public to protected --- packages/@aws-cdk/assets/lib/staging.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/assets/lib/staging.ts b/packages/@aws-cdk/assets/lib/staging.ts index 92a07874b579d..030ed3f6195a9 100644 --- a/packages/@aws-cdk/assets/lib/staging.ts +++ b/packages/@aws-cdk/assets/lib/staging.ts @@ -66,7 +66,7 @@ export class Staging extends Construct { } } - public synthesize(session: ISynthesisSession) { + protected synthesize(session: ISynthesisSession) { if (!this.relativePath) { return; }