Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
e9c13be
Add stack-whatif commands.
kalbert312 Feb 20, 2026
a7ba6d2
Add no pretty print argument.
kalbert312 Feb 20, 2026
5202227
Add boilerplate for print deployment stack what-if results.
kalbert312 Feb 20, 2026
c3bb51b
Implement legend output.
kalbert312 Feb 23, 2026
fdcea30
Progress on what-if formatting.
kalbert312 Feb 23, 2026
04b91ef
Add --no-color parameter.
kalbert312 Feb 23, 2026
7a08708
What-if output progress.
kalbert312 Feb 24, 2026
098994f
What-if resource change progress.
kalbert312 Feb 24, 2026
bbea709
What-if potential resource change progress.
kalbert312 Feb 25, 2026
31db7ab
What-if resource deletion summary progress.
kalbert312 Feb 25, 2026
2cb3c3b
Add indents automatically.
kalbert312 Feb 25, 2026
2018396
Type hints.
kalbert312 Feb 25, 2026
158e79b
Diagnostics formatting progress.
kalbert312 Feb 25, 2026
9243a11
Fix type logic.
kalbert312 Feb 25, 2026
9d9d64f
Fix count.
kalbert312 Feb 25, 2026
376f3ac
Split into methods.
kalbert312 Feb 26, 2026
cd5c818
Extensible resource output support.
kalbert312 Feb 26, 2026
38a237c
Array children rendering fixes and misc refactors.
kalbert312 Feb 26, 2026
ddc1813
Array children rendering fixes and misc refactors.
kalbert312 Feb 26, 2026
1683673
Remove redundant "change" label.
kalbert312 Feb 27, 2026
0870961
Add exclusions for wait command + rg. Is consistent with stack commands.
kalbert312 Feb 27, 2026
8a460a7
Fix lint errors. Add resource class formatting method.
kalbert312 Feb 27, 2026
679778c
Update extensible resource display.
kalbert312 Feb 27, 2026
a3b1e91
Lint fixes.
kalbert312 Feb 27, 2026
11a4e68
Add unit test for stacks what-if formatter.
kalbert312 Mar 2, 2026
d75a2d1
Add live test class for deployment stack what-ifs.
kalbert312 Mar 2, 2026
5fd01a6
Add stack-whatif to service_name.json
kalbert312 Mar 2, 2026
5cbbac2
Add missing required params in the stack-whatif help examples.
kalbert312 Mar 2, 2026
7f68947
Add missing stack-whatif help entries and adjust examples & descripti…
kalbert312 Mar 2, 2026
5c867c3
Adjust help entries. Fix some params on delete.
kalbert312 Mar 3, 2026
9718945
Style fixes.
kalbert312 Mar 3, 2026
0077f9a
Merge branch 'dev' into kylea/stacks-what-if
kalbert312 Mar 3, 2026
40112c2
Fix management group ID parameter.
kalbert312 Mar 3, 2026
2c9307c
Add some coverage for printing arguments.
kalbert312 Mar 3, 2026
1b0f8b0
Fix test issues. Add stack whatif RG recording.
kalbert312 Mar 4, 2026
a24faaa
Merge branch 'dev' into kylea/stacks-what-if
kalbert312 Mar 17, 2026
c7ef104
Merge branch 'dev' into kylea/stacks-what-if
kalbert312 Mar 23, 2026
429de5f
Minimal changes to ignore extensible resources.
kalbert312 Mar 26, 2026
f94a995
Merge branch 'dev' into kylea/stacks-what-if
kalbert312 Mar 27, 2026
e63bbea
Run update index script.
kalbert312 Mar 27, 2026
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
6 changes: 4 additions & 2 deletions src/azure-cli-core/azure/cli/core/commandIndex.latest.json
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,7 @@
"azure.cli.command_modules.netappfiles"
],
"network": [
"azure.cli.command_modules.network",
"azure.cli.command_modules.privatedns"
"azure.cli.command_modules.network"
],
"policy": [
"azure.cli.command_modules.policyinsights",
Expand Down Expand Up @@ -322,6 +321,9 @@
"webapp": [
"azure.cli.command_modules.appservice",
"azure.cli.command_modules.serviceconnector"
],
"stack-whatif": [
"azure.cli.command_modules.resource"
]
}
}
4 changes: 4 additions & 0 deletions src/azure-cli-core/azure/cli/core/helpIndex.latest.json
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,10 @@
"webapp": {
"summary": "Manage web apps.",
"tags": ""
},
"stack-whatif": {
"summary": "A deployment stack What-If is a preview of an operation to be performed on a new or existing deployment stack.",
"tags": ""
}
},
"commands": {
Expand Down
60 changes: 55 additions & 5 deletions src/azure-cli/azure/cli/command_modules/resource/_color.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class Color(Enum):
GREEN = "\033[38;5;77m"
PURPLE = "\033[38;5;141m"
BLUE = "\033[38;5;39m"
CYAN = "\033[38;5;51m"
GRAY = "\033[38;5;246m"
RED = "\033[38;5;203m"
DARK_YELLOW = "\033[38;5;136m"
Expand All @@ -26,11 +27,15 @@ def __init__(self, enable_color=True):
self._enable_color = enable_color
self._contents = []
self._colors = deque()
self._indents = []

def build(self):
return "".join(self._contents)

def append(self, value, color=None):
def append(self, value, color=None, no_indent=False):
if not no_indent and self._should_indent():
self._contents.append(''.join(self._indents))

if color:
self._push_color(color)

Expand All @@ -41,14 +46,55 @@ def append(self, value, color=None):

return self

def append_line(self, value="", color=None):
self.append(f"{str(value)}\n", color)

return self
def append_line(self, value="", color=None, no_indent=False):
self.append(value, color, no_indent)
return self.append("\n", no_indent=True)

def new_color_scope(self, color):
return self.ColorScope(self, color)

def insert(self, index, value="", color=None, no_indent=False):
if color and self._enable_color:
self._contents.insert(index, str(Color.RESET))

self._contents.insert(index, str(value))

if color and self._enable_color:
self._contents.insert(index, str(color))

if not no_indent and self._should_indent(index, True):
self._contents.insert(index, ''.join(self._indents))

return self

def insert_line(self, index, value="", color=None, no_indent=False):
self.insert(index, "\n", no_indent=no_indent)
return self.insert(index, value, color, no_indent)

def get_current_index(self):
return len(self._contents)

def push_indent(self, indent):
self._indents.append(indent)

def pop_indent(self):
self._indents.pop()

def ensure_num_new_lines(self, num_new_lines):
if len(self._contents) == 0:
self.append("\n" * num_new_lines)
return

last_entry = self._contents[-1]
existing_newlines = len(last_entry) - len(last_entry.rstrip('\n'))
remaining_newlines = num_new_lines - existing_newlines

if remaining_newlines > 0:
self._contents.append("\n" * remaining_newlines)

def clear(self):
self._contents = []

def _push_color(self, color):
if not self._enable_color:
return
Expand All @@ -63,6 +109,10 @@ def _pop_color(self):
self._colors.pop()
self._contents.append(str(self._colors[-1] if self._colors else Color.RESET))

def _should_indent(self, index=-1, is_insert=False):
return len(self._indents) > 0 and (
not self._contents or self._contents[max(index - 1, 0) if is_insert else index].endswith("\n"))

# pylint: disable=protected-access
class ColorScope:
def __init__(self, color_string_builder, color):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,8 @@ def _format_resource_changes(builder, resource_changes, definite_changes=True):
for _, resource_changes_in_scope in resource_changes_by_scope:
resource_changes_in_scope_list = list(resource_changes_in_scope)
scope = _get_scope(resource_changes_in_scope_list[0])
_format_resource_changes_in_scope(builder, scope, resource_changes_in_scope_list)
if scope != "Unknown":
_format_resource_changes_in_scope(builder, scope, resource_changes_in_scope_list)


def _format_resource_changes_in_scope(builder, scope, resource_changes_in_scope):
Expand All @@ -248,6 +249,9 @@ def _format_resource_changes_in_scope(builder, scope, resource_changes_in_scope)
def _format_resource_change(builder, resource_change, is_last):
change_type = resource_change.change_type
relative_resource_id = _get_relative_resource_id(resource_change)
if relative_resource_id is None:
return

api_version = _get_api_version(resource_change)

builder.append_line()
Expand Down Expand Up @@ -447,7 +451,7 @@ def _get_api_version(resource_change):

def _get_scope(resource_change):
scope, _ = split_resource_id(resource_change.resource_id)
return scope
return scope or "Unknown" # TODO: extensible resource support


def _get_scope_uppercase(resource_change):
Expand Down
Loading
Loading