Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(toolkit): by default hide AWS::CDK::Metadata from "cdk diff" #1186

Merged
merged 3 commits into from
Nov 18, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 39 additions & 20 deletions packages/@aws-cdk/cloudformation-diff/lib/diff/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,48 @@ export class TemplateDiff implements ITemplateDiff {
/** The differences in unknown/unexpected parts of the template */
public readonly unknown: DifferenceCollection<any, Difference<any>>;

public readonly count: number;

constructor(args: ITemplateDiff) {
let count = 0;
if (args.awsTemplateFormatVersion !== undefined) {
this.awsTemplateFormatVersion = args.awsTemplateFormatVersion;
count += 1;
}
if (args.description !== undefined) {
this.description = args.description;
count += 1;
}
if (args.transform !== undefined) {
this.transform = args.transform;
count += 1;
}

this.conditions = args.conditions || new DifferenceCollection({});
count += this.conditions.count;

this.mappings = args.mappings || new DifferenceCollection({});
count += this.mappings.count;

this.metadata = args.metadata || new DifferenceCollection({});
count += this.metadata.count;

this.outputs = args.outputs || new DifferenceCollection({});
count += this.outputs.count;

this.parameters = args.parameters || new DifferenceCollection({});
count += this.parameters.count;

this.resources = args.resources || new DifferenceCollection({});
count += this.resources.count;

this.unknown = args.unknown || new DifferenceCollection({});
}

public get count() {
let count = 0;

if (this.awsTemplateFormatVersion !== undefined) {
count += 1;
}
if (this.description !== undefined) {
count += 1;
}
if (this.transform !== undefined) {
count += 1;
}

count += this.conditions.count;
count += this.mappings.count;
count += this.metadata.count;
count += this.outputs.count;
count += this.parameters.count;
count += this.resources.count;
count += this.unknown.count;

this.count = count;
return count;
}

public get isEmpty(): boolean {
Expand Down Expand Up @@ -107,7 +110,7 @@ export class PropertyDifference<ValueType> extends Difference<ValueType> {
}

export class DifferenceCollection<V, T extends Difference<V>> {
constructor(public readonly changes: { [logicalId: string]: T | undefined }) {}
constructor(public changes: { [logicalId: string]: T | undefined }) {}

public get count(): number {
return this.logicalIds.length;
Expand All @@ -117,6 +120,22 @@ export class DifferenceCollection<V, T extends Difference<V>> {
return Object.keys(this.changes);
}

/**
* Removes all changes that do not match the specified filter.
*/
public applyFilter(filter: (diff: T | undefined) => boolean) {
eladb marked this conversation as resolved.
Show resolved Hide resolved
const newChanges: { [logicalId: string]: T | undefined } = { };
for (const id of Object.keys(this.changes)) {
const diff = this.changes[id];

if (filter(diff)) {
newChanges[id] = diff;
}
}

this.changes = newChanges;
}

public forEach(cb: (logicalId: string, change: T) => any): void {
for (const logicalId of this.logicalIds) {
cb(logicalId, this.changes[logicalId]!);
Expand Down
9 changes: 5 additions & 4 deletions packages/aws-cdk/bin/cdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ async function parseCommandLineArguments() {
.command('destroy [STACKS..]', 'Destroy the stack(s) named STACKS', yargs => yargs
.option('force', { type: 'boolean', alias: 'f', desc: 'Do not ask for confirmation before destroying the stacks' }))
.command('diff [STACK]', 'Compares the specified stack with the deployed stack or a local template file', yargs => yargs
.option('template', { type: 'string', desc: 'the path to the CloudFormation template to compare with' }))
.option('template', { type: 'string', desc: 'the path to the CloudFormation template to compare with' })
.option('strict', { type: 'boolean', desc: 'do not filter out AWS::CDK::Metadata resources', default: false }))
.command('metadata [STACK]', 'Returns all metadata associated with this stack')
.command('init [TEMPLATE]', 'Create a new, empty CDK project from a template. Invoked without TEMPLATE, the app template will be used.', yargs => yargs
.option('language', { type: 'string', alias: 'l', desc: 'the language to be used for the new project (default can be configured in ~/.cdk.json)', choices: initTemplateLanuages })
Expand Down Expand Up @@ -200,7 +201,7 @@ async function initCommandLine() {
return await cliList({ long: args.long });

case 'diff':
return await diffStack(await findStack(args.STACK), args.template);
return await diffStack(await findStack(args.STACK), args.template, args.strict);

case 'bootstrap':
return await cliBootstrap(args.ENVIRONMENTS, toolkitStackName, args.roleArn);
Expand Down Expand Up @@ -592,10 +593,10 @@ async function initCommandLine() {
}
}

async function diffStack(stackName: string, templatePath?: string): Promise<number> {
async function diffStack(stackName: string, templatePath: string | undefined, strict: boolean): Promise<number> {
const stack = await synthesizeStack(stackName);
const currentTemplate = await readCurrentTemplate(stack, templatePath);
if (printStackDiff(currentTemplate, stack) === 0) {
if (printStackDiff(currentTemplate, stack, strict) === 0) {
return 0;
} else {
return 1;
Expand Down
13 changes: 12 additions & 1 deletion packages/aws-cdk/lib/diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,19 @@ import { print } from './logging';
*
* @returns the count of differences that were rendered.
*/
export function printStackDiff(oldTemplate: any, newTemplate: cxapi.SynthesizedStack): number {
export function printStackDiff(oldTemplate: any, newTemplate: cxapi.SynthesizedStack, strict: boolean): number {
const diff = cfnDiff.diffTemplate(oldTemplate, newTemplate.template);

// filter out 'AWS::CDK::Metadata' resources from the template
if (diff.resources && !strict) {
diff.resources.applyFilter(change => {
if (!change) { return true; }
if (change.newResourceType === 'AWS::CDK::Metadata') { return false; }
if (change.oldResourceType === 'AWS::CDK::Metadata') { return false; }
return true;
});
}

if (!diff.isEmpty) {
cfnDiff.formatDifferences(process.stderr, diff);
} else {
Expand Down