-
Notifications
You must be signed in to change notification settings - Fork 10.1k
Description
The hashicorp/helm
provider's resource type helm_release
has an argument values
which accepts a list of strings where each string is typically an entire YAML document, and therefore a multi-line string. It seems that typical usage of this includes only one element of values
, but it supports multiple as an option to match the underlying system capabilities.
At the time of writing this (Terraform v1.6.0 is in its prerelease phase) the Terraform CLI diff-rendering heuristics render changes to the first element of a single-element list in a non-ideal way, such as:
~ values = [
- <<-EOT
(the whole old YAML document)
EOT
+ <<-EOT
(the whole new YAML document)
EOT
]
This presentation makes it hard to notice small changes when most of the document is unchanged. There are some issues over in the provider repository reporting this already, which include some more realistic examples:
- Make values diffs more useful, possibly by accepting maps. terraform-provider-helm#686
- Provide richer diff of values changes terraform-provider-helm#1121
It would be possible for the Helm provider itself to avoid this problem by accepting a map of strings or a single string as other options, since both of those would show as individual element diffs under the current diff heuristics.
However, this does show an opportunity to potentially improve the CLI heuristics to better handle this case. As usual with diffing heuristics, there is no objective correct answer here and the game is always to do our best to infer the most intuitive interpretation of differences, but I think it's fair to say that the current situation is not meeting that goal.
I have a proposed new addition to the heuristics that I think will improve this situation without any significant degradation of the output in other cases:
- When rendering a list for a diff, first check whether the old and new lists have the same length.
- If the list lengths differ, use the current presentation which diffs the list itself to try to show additions and removals as usefully as possible.
- If the list lengths are equal, skip the list-level diff and instead compare the elements by correlated indices and show the diff for each individual element.
Although my main motivation for this idea is multi-line strings, I think this interpretation would also work better for lists of lists, lists of maps, etc.
My assumption/hypothesis with the above heuristic is that if the list length hasn't changed then it's more likely that the author interprets this as editing an existing item in-place rather than as adding and removing elements from the list.
One situation where that assumption would not hold is if the author has just reordered elements in the list rather than editing any of them. If we're worried about that then we could add a further rule that first checks if the new list seems to be just a reordering of the old list, which I think would mean counting the number of appearances of each distinct element value and treating it as a reordering if those counts are equal across both lists. However, I'd suggest that we experiment with both renderings of the reordering case to see, since neither of these two renderings directly represents reordering and I'm unsure which one represents the best approximation that would be intuitive to the person reviewing the plan.