Skip to content

Commit a57d9ca

Browse files
authored
Fix Docker output by moving colorama init for ECS expressgateway commands (aws#9878)
1 parent 13d13a9 commit a57d9ca

File tree

5 files changed

+180
-174
lines changed

5 files changed

+180
-174
lines changed

awscli/customizations/ecs/expressgateway/color_utils.py

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,70 +15,64 @@
1515

1616
from colorama import Fore, Style, init
1717

18-
# Initialize colorama for cross-platform support
19-
init()
20-
2118
# Status symbols
2219
CHECK_MARK = '✓'
2320

2421

2522
class ColorUtils:
2623
"""Utility class for applying colors to text using colorama."""
2724

28-
@staticmethod
29-
def make_green(text, use_color=True):
25+
def __init__(self):
26+
# Initialize colorama
27+
init(autoreset=True, strip=False)
28+
29+
def make_green(self, text, use_color=True):
3030
if not use_color:
3131
return text
3232
return f"{Fore.GREEN}{text}{Style.RESET_ALL}"
3333

34-
@staticmethod
35-
def make_red(text, use_color=True):
34+
def make_red(self, text, use_color=True):
3635
if not use_color:
3736
return text
3837
return f"{Fore.RED}{text}{Style.RESET_ALL}"
3938

40-
@staticmethod
41-
def make_purple(text, use_color=True):
39+
def make_purple(self, text, use_color=True):
4240
if not use_color:
4341
return text
4442
return f"{Fore.MAGENTA}{text}{Style.RESET_ALL}"
4543

46-
@staticmethod
47-
def make_yellow(text, use_color=True):
44+
def make_yellow(self, text, use_color=True):
4845
if not use_color:
4946
return text
5047
return f"{Fore.YELLOW}{text}{Style.RESET_ALL}"
5148

52-
@staticmethod
53-
def make_cyan(text, use_color=True):
49+
def make_cyan(self, text, use_color=True):
5450
if not use_color:
5551
return text
5652
return f"{Fore.CYAN}{text}{Style.RESET_ALL}"
5753

58-
@staticmethod
59-
def color_by_status(text, status, use_color=True):
54+
def color_by_status(self, text, status, use_color=True):
6055
"""Color text based on resource status."""
6156
if not status or status == "ACTIVE" or status == "SUCCESSFUL":
62-
return ColorUtils.make_green(text, use_color)
57+
return self.make_green(text, use_color)
6358
elif status == "FAILED":
64-
return ColorUtils.make_red(text, use_color)
59+
return self.make_red(text, use_color)
6560
elif status == "DELETED":
66-
return ColorUtils.make_yellow(text, use_color)
61+
return self.make_yellow(text, use_color)
6762
else:
68-
return ColorUtils.make_purple(text, use_color)
63+
return self.make_purple(text, use_color)
6964

70-
@staticmethod
71-
def make_status_symbol(status, spinner_char, use_color=True):
65+
def make_status_symbol(self, status, spinner_char, use_color=True):
7266
"""Create status symbol with appropriate color."""
7367
if not status or status == "ACTIVE" or status == "SUCCESSFUL":
74-
return ColorUtils.make_green(f"{CHECK_MARK} ", use_color)
68+
return self.make_green(f"{CHECK_MARK} ", use_color)
7569
elif status == "FAILED" or status == "ROLLBACK_FAILED":
76-
return ColorUtils.make_red("X ", use_color)
70+
return self.make_red("X ", use_color)
7771
elif (
7872
status == "DELETED"
7973
or status == "STOPPED"
8074
or status == "ROLLBACK_SUCCESSFUL"
8175
):
82-
return ColorUtils.make_yellow("— ", use_color)
76+
return self.make_yellow("— ", use_color)
8377
else:
84-
return ColorUtils.make_purple(f"{spinner_char} ", use_color)
78+
return self.make_purple(f"{spinner_char} ", use_color)

awscli/customizations/ecs/expressgateway/managedresource.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def __init__(
5151
self.updated_at = updated_at
5252
self.reason = reason
5353
self.additional_info = additional_info
54+
self.color_utils = ColorUtils()
5455

5556
def is_terminal(self):
5657
return self.status in TERMINAL_RESOURCE_STATUSES
@@ -67,23 +68,23 @@ def get_status_string(self, spinner_char, depth=0, use_color=True):
6768
str: Formatted status string with resource information
6869
"""
6970
lines = []
70-
resource_header = " " * depth + ColorUtils.make_cyan(
71+
resource_header = " " * depth + self.color_utils.make_cyan(
7172
self.resource_type, use_color
7273
)
7374

7475
resource_header += ": " if self.identifier else " "
75-
resource_header += ColorUtils.make_status_symbol(
76+
resource_header += self.color_utils.make_status_symbol(
7677
self.status, spinner_char, use_color
7778
)
7879
if self.identifier:
7980
resource_header += (
80-
ColorUtils.color_by_status(
81+
self.color_utils.color_by_status(
8182
self.identifier, self.status, use_color
8283
)
8384
+ " "
8485
)
8586
if self.status:
86-
resource_header += "- " + ColorUtils.color_by_status(
87+
resource_header += "- " + self.color_utils.color_by_status(
8788
self.status, self.status, use_color
8889
)
8990
lines.append(resource_header)

awscli/customizations/ecs/expressgateway/managedresourcegroup.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def __init__(
4848
}
4949
self.status = status
5050
self.reason = reason
51+
self.color_utils = ColorUtils()
5152

5253
def _create_key(self, resource):
5354
resource_type = (
@@ -78,29 +79,29 @@ def get_status_string(self, spinner_char, depth=0, use_color=True):
7879
lines = []
7980

8081
if self.resource_type:
81-
header = " " * depth + ColorUtils.make_cyan(
82+
header = " " * depth + self.color_utils.make_cyan(
8283
str(self.resource_type), use_color
8384
)
8485

8586
if self.identifier:
8687
header += ": "
8788
if self.status:
88-
header += ColorUtils.make_status_symbol(
89+
header += self.color_utils.make_status_symbol(
8990
self.status, spinner_char, use_color
9091
)
91-
header += ColorUtils.color_by_status(
92+
header += self.color_utils.color_by_status(
9293
self.identifier, self.status, use_color
9394
)
94-
header += " - " + ColorUtils.color_by_status(
95+
header += " - " + self.color_utils.color_by_status(
9596
self.status, self.status, use_color
9697
)
9798
else:
9899
header += self.identifier
99100
elif self.status:
100-
header += " " + ColorUtils.make_status_symbol(
101+
header += " " + self.color_utils.make_status_symbol(
101102
self.status, spinner_char, use_color
102103
)
103-
header += "- " + ColorUtils.color_by_status(
104+
header += "- " + self.color_utils.color_by_status(
104105
self.status, self.status, use_color
105106
)
106107

tests/functional/test_output.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727

2828
class TestOutput(BaseAWSCommandParamsTest):
2929
def setUp(self):
30-
super(TestOutput, self).setUp()
30+
# Patch this before super, in case called on import
31+
self.patch_colorama_init = mock.patch('colorama.init')
32+
self.mock_colorama_init = self.patch_colorama_init.start()
33+
34+
super().setUp()
3135
self.files = FileCreator()
3236

3337
self.patch_popen = mock.patch('awscli.utils.Popen')
@@ -49,7 +53,7 @@ def setUp(self):
4953
self.expected_content = self.get_expected_content(self.parsed_response)
5054

5155
def tearDown(self):
52-
super(TestOutput, self).tearDown()
56+
super().tearDown()
5357
self.files.remove_all()
5458
self.patch_popen.stop()
5559
self.patch_tty.stop()
@@ -61,7 +65,7 @@ def get_expected_content(self, response):
6165

6266
def write_cli_pager_config(self, pager):
6367
config_file = self.files.create_file(
64-
'config', '[default]\n' 'cli_pager = %s\n' % pager
68+
'config', '[default]\n' f'cli_pager = {pager}\n'
6569
)
6670
self.environ['AWS_CONFIG_FILE'] = config_file
6771
self.driver = create_clidriver()
@@ -194,6 +198,15 @@ def test_raises_exception_when_pager_cannot_be_opened(self):
194198
self.assertIn('Unable to redirect output to pager', stderr)
195199
self.assertIn(pager_error_message, stderr)
196200

201+
def test_colorama_init_not_called(self):
202+
"""
203+
For https://github.com/aws/aws-cli/issues/9864,
204+
we had an issue where colorama was always being initialized, instead of
205+
just during the custom commands or modes that use it
206+
"""
207+
self.run_cmd(self.cmdline)
208+
self.mock_colorama_init.assert_not_called()
209+
197210

198211
class TestYAMLStream(BaseAWSCommandParamsTest):
199212
def assert_yaml_response_equal(self, response, expected):

0 commit comments

Comments
 (0)