-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
fix(aws-cdk): Improvements to IAM diff rendering #1542
Conversation
This ensure so that the diff output and the prompt don't interleave.
Calculcate column widths so that the table will not overflow the terminal anymore. Switch back to 'table' library which now has newline support and not the rendering bug that 'cli-table' had.
We used to modify the new template in place, causing changes to "logicalIDs" of replaced resources, which would trigger downstream changes and potential downstream replacements, etc. This would lead to the changed logical ID popping up in the IAM diff which was not desirable. In this change, we do the same processing but we throw away the template after all changes have been propagated, and only copy the resultant property STATUSES onto the diff object that gets returned to the user. This leads to the same displayed result without the changes to the template actually propagating. In the course of this modification, the diff classes have been changed to also have objects in places of resources and properties that didn't actually change (so that they could be modified in-place), and diff objects have a boolean telling whether they are actual changes or not. Fixes #1495.
Could you please upload a nice little screenshot? |
This PR is blocked on gajus/table#89 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Table looks beautiful! I had some comments but nothing worth blocking on.
count += this.outputs.differenceCount; | ||
count += this.parameters.differenceCount; | ||
count += this.resources.differenceCount; | ||
count += this.unknown.differenceCount; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: scope these under a single object so you can enumerate
and reduce
?
[ResourceImpact.WILL_ORPHAN]: 3, | ||
[ResourceImpact.MAY_REPLACE]: 4, | ||
[ResourceImpact.WILL_REPLACE]: 5, | ||
[ResourceImpact.WILL_DESTROY]: 6, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why declare this in the function scope?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not? It's only used here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it optimized away? :)
widths.forEach((width, i) => { | ||
ret[i] = { width, useWordWrap: true } as any; // 'useWordWrap' is not in @types/table | ||
if (width === undefined) { | ||
delete ret[i].width; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This undefined
terminal width has penetrated the logic everywhere. Can we not switch it on/off in a simpler way to avoid delete ret[i].width
and Array<number | undefined>
? It seems to have a single source: formatTable(_, columns: number | undefined)
.
const columns = rows[0].map((_, i) => Math.max(...rows.map(row => stringWidth(row[i])))); | ||
|
||
// If we have no terminal width, do nothing | ||
if (terminalWidth === undefined) { return columns.map(_ => undefined); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
array of undefined? Is this the optimal signal?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did it this way because I wanted the useWordWrap: true
for every column.
But I suppose that's silly, because if there's no width
, what does it even matter how you wrap?
return ret; | ||
} | ||
|
||
function sum(xs: number[]): number { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
xs.reduce((a,b) => a + b, 0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did it this way on purpose because I believe V8 JITs this better. But I will agree it's a micro-optimization :)
packages/aws-cdk/lib/util/tables.ts
Outdated
return table.toString(); | ||
if (options.colWidths) { | ||
options.colWidths.forEach((width, i) => { | ||
columns[i] = { width, useWordWrap: true } as any; // @types doesn't have this type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need to cast to any
here? You have the type, table.ColumnConfig
, is this not the correct shape?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the comment says, The @types
package for this library is for 4.x.x
and we're using 5.x.x
. There is no newer one and I don't really feel like writing it... :(
packages/aws-cdk/lib/util/tables.ts
Outdated
joinLeft: tableColor('├'), | ||
joinRight: tableColor('┤'), | ||
joinJoin: tableColor('┼') | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've seen this table twice .. redundant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One is in @aws-cdk/cloudformation-diff
and the other one is in aws-cdk
. I'd prefer to keep the table rendering private to the package, because it doesn't seem like an exportable feature of @aws-cdk/cloudformationd-diff`, and extracting to another package just to share seemed a bit too much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But, otoh, terminal width wrapping now only works for the IAM changes table, not for the others. Maybe I should share...
Rewrite 'undefined' logic to make it less onerous. Print a message instead of an empty table if 'cdk context' has no information in it (fixes #1549).
Contains the following changes:
table
library (instead ofcli-table
) which now has in-cell newline support, to get rid of the rendering bugs incli-table
that would occasionally eat newlines.replace
impact as red instead of yellow, to indicate that data loss will be happening here (fixes diff ui:replace
is as dangerous asdestroy
- so should be in red #1458).Explanation:
We used to modify the new target template in place, causing changes to
the logical ids of replaced resources, which would trigger downstream
changes, which would further trigger potential downstream replacements, etc.
This would properly calculate the set of impacted resources, but would also lead to the modified logical ID popping up in the IAM diff, which was not desirable.
In this change, we do the same processing but we throw away the
template after all changes have been propagated, and only copy
the resultant property statuses onto the diff object that gets
returned to the user. This leads to the same displayed result
without the changes to the template actually propagating.
In the course of this modification, the diff classes have been changed
to also have objects in places of resources and properties that
didn't actually change (so that they could be modified in-place),
and diff objects have a boolean telling whether they are actual
changes or not.
Pull Request Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license.