Skip to content

Commit 37dc1dd

Browse files
authored
Update colcon_core.command for generalized usage (#651)
These non-breaking API changes are helpful for creating other CLIs based on colcon's extension model.
1 parent 485f500 commit 37dc1dd

File tree

3 files changed

+76
-9
lines changed

3 files changed

+76
-9
lines changed

colcon_core/command.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,10 @@ def register_command_exit_handler(handler):
9090
_command_exit_handlers.append(handler)
9191

9292

93-
def main(*, command_name='colcon', argv=None):
93+
def main(
94+
*, command_name='colcon', argv=None, verb_group_name=None,
95+
environment_variable_group_name=None,
96+
):
9497
"""
9598
Execute the main logic of the command.
9699
@@ -113,7 +116,10 @@ def main(*, command_name='colcon', argv=None):
113116
:returns: The return code
114117
"""
115118
try:
116-
return _main(command_name=command_name, argv=argv)
119+
return _main(
120+
command_name=command_name, argv=argv,
121+
verb_group_name=verb_group_name,
122+
environment_variable_group_name=environment_variable_group_name)
117123
except KeyboardInterrupt:
118124
return signal.SIGINT
119125
finally:
@@ -123,7 +129,9 @@ def main(*, command_name='colcon', argv=None):
123129
handler()
124130

125131

126-
def _main(*, command_name, argv):
132+
def _main(
133+
*, command_name, argv, verb_group_name, environment_variable_group_name,
134+
):
127135
# default log level, for searchability: COLCON_LOG_LEVEL
128136
colcon_logger.setLevel(logging.WARNING)
129137
set_logger_level_from_env(
@@ -137,9 +145,9 @@ def _main(*, command_name, argv):
137145
path=(Path('~') / f'.{command_name}').expanduser(),
138146
env_var=f'{command_name}_HOME'.upper())
139147

140-
parser = create_parser('colcon_core.environment_variable')
148+
parser = create_parser(environment_variable_group_name)
141149

142-
verb_extensions = get_verb_extensions()
150+
verb_extensions = get_verb_extensions(group_name=verb_group_name)
143151

144152
# add subparsers for all verb extensions but without arguments for now
145153
subparser = create_subparser(
@@ -203,7 +211,7 @@ def _main(*, command_name, argv):
203211
return verb_main(context, colcon_logger)
204212

205213

206-
def create_parser(environment_variables_group_name):
214+
def create_parser(environment_variables_group_name=None):
207215
"""
208216
Create the argument parser.
209217
@@ -283,7 +291,7 @@ def _split_lines(self, text, width):
283291
return lines
284292

285293

286-
def get_environment_variables_epilog(group_name):
294+
def get_environment_variables_epilog(group_name=None):
287295
"""
288296
Get a message enumerating the registered environment variables.
289297
@@ -292,6 +300,8 @@ def get_environment_variables_epilog(group_name):
292300
:returns: The message for the argument parser epilog
293301
:rtype: str
294302
"""
303+
if group_name is None:
304+
group_name = 'colcon_core.environment_variable'
295305
# list environment variables with descriptions
296306
entry_points = load_extension_points(group_name)
297307
if not entry_points:

colcon_core/extension_point.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@
2222
from colcon_core.environment_variable import EnvironmentVariable
2323
from colcon_core.logging import colcon_logger
2424

25-
"""Environment variable to block extensions"""
26-
EXTENSION_BLOCKLIST_ENVIRONMENT_VARIABLE = EnvironmentVariable(
25+
_EXTENSION_BLOCKLIST_ENVIRONMENT_VARIABLE = EnvironmentVariable(
2726
'COLCON_EXTENSION_BLOCKLIST',
2827
'Block extensions which should not be used')
2928

29+
"""Environment variable to block extensions"""
30+
EXTENSION_BLOCKLIST_ENVIRONMENT_VARIABLE = \
31+
_EXTENSION_BLOCKLIST_ENVIRONMENT_VARIABLE
32+
3033
logger = colcon_logger.getChild(__name__)
3134

3235
"""
@@ -205,3 +208,16 @@ def load_extension_point(name, value, group):
205208
'The entry point name is listed in the environment variable '
206209
f"'{EXTENSION_BLOCKLIST_ENVIRONMENT_VARIABLE.name}'")
207210
return EntryPoint(name, value, group).load()
211+
212+
213+
def override_blocklist_variable(variable):
214+
"""
215+
Override the blocklist environment variable.
216+
217+
:param EnvironmentVariable variable: The new blocklist environment
218+
variable, or None to reset to default.
219+
"""
220+
if variable is None:
221+
variable = _EXTENSION_BLOCKLIST_ENVIRONMENT_VARIABLE
222+
global EXTENSION_BLOCKLIST_ENVIRONMENT_VARIABLE
223+
EXTENSION_BLOCKLIST_ENVIRONMENT_VARIABLE = variable

test/test_extension_point.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@
1212
# TODO: Drop this with Python 3.7 support
1313
from importlib_metadata import Distribution
1414

15+
from colcon_core.environment_variable import EnvironmentVariable
1516
from colcon_core.extension_point import clear_entry_point_cache
1617
from colcon_core.extension_point import EntryPoint
1718
from colcon_core.extension_point import EXTENSION_POINT_GROUP_NAME
1819
from colcon_core.extension_point import get_all_extension_points
1920
from colcon_core.extension_point import get_extension_points
2021
from colcon_core.extension_point import load_extension_point
2122
from colcon_core.extension_point import load_extension_points
23+
from colcon_core.extension_point import override_blocklist_variable
2224
import pytest
2325

2426
from .environment_context import EnvironmentContext
@@ -139,6 +141,45 @@ def test_extension_point_blocklist():
139141
assert load.call_count == 0
140142

141143

144+
def test_extension_point_blocklist_override():
145+
with patch.object(EntryPoint, 'load', return_value=None) as load:
146+
clear_entry_point_cache()
147+
148+
my_extension_blocklist = EnvironmentVariable(
149+
'MY_EXTENSION_BLOCKLIST', 'Foo bar baz')
150+
override_blocklist_variable(my_extension_blocklist)
151+
152+
try:
153+
# entry point in default blocklist variable can be loaded
154+
load.reset_mock()
155+
with EnvironmentContext(COLCON_EXTENSION_BLOCKLIST='group1'):
156+
clear_entry_point_cache()
157+
load_extension_point('extA', 'eA', 'group1')
158+
assert load.call_count == 1
159+
160+
# entry point in custom blocklist variable can't be loaded
161+
load.reset_mock()
162+
with EnvironmentContext(MY_EXTENSION_BLOCKLIST='group1'):
163+
clear_entry_point_cache()
164+
with pytest.raises(RuntimeError) as e:
165+
load_extension_point('extA', 'eA', 'group1')
166+
assert 'The entry point group name is listed in the ' \
167+
'environment variable' in str(e.value)
168+
assert load.call_count == 0
169+
finally:
170+
override_blocklist_variable(None)
171+
172+
# entry point in default blocklist variable can no longer be loaded
173+
load.reset_mock()
174+
with EnvironmentContext(COLCON_EXTENSION_BLOCKLIST='group1'):
175+
clear_entry_point_cache()
176+
with pytest.raises(RuntimeError) as e:
177+
load_extension_point('extA', 'eA', 'group1')
178+
assert 'The entry point group name is listed in the ' \
179+
'environment variable' in str(e.value)
180+
assert load.call_count == 0
181+
182+
142183
def test_redefined_extension_point():
143184
def _duped_distributions():
144185
yield from _distributions()

0 commit comments

Comments
 (0)