Skip to content

Commit 91bbad2

Browse files
authored
add JobUnselected event to the build verb (#326)
* add pre_execution callback * add JobUnselected event and generate it in the build verb * add coverage for callback argument
1 parent 4ff2203 commit 91bbad2

File tree

4 files changed

+47
-6
lines changed

4 files changed

+47
-6
lines changed

colcon_core/event/job.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,20 @@
22
# Licensed under the Apache License, Version 2.0
33

44

5+
class JobUnselected:
6+
"""An event containing the identifier of the unselected job."""
7+
8+
__slots__ = ('identifier', )
9+
10+
def __init__(self, identifier):
11+
"""
12+
Construct a JobUnselected.
13+
14+
:param str identifier: The job identifier
15+
"""
16+
self.identifier = identifier
17+
18+
519
class JobQueued:
620
"""An event containing the identifier of the queued job."""
721

colcon_core/executor/__init__.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,8 @@ def add_executor_arguments(parser):
263263

264264

265265
def execute_jobs(
266-
context, jobs, *, on_error: OnError = None, abort_on_error=None
266+
context, jobs, *, on_error: OnError = None, abort_on_error=None,
267+
pre_execution_callback=None
267268
):
268269
"""
269270
Execute jobs.
@@ -282,6 +283,9 @@ def execute_jobs(
282283
:param on_error: The decision how to proceed when one job fails
283284
:param abort_on_error: The flag if pending jobs should be aborted in case
284285
of individual jobs failing (deprecated, use `on_error` instead)
286+
:param pre_execution_callback: An optional callable taking a keyword
287+
argument `event_queue` which will be invoked before the executors
288+
`execute()` method
285289
:returns: The return code
286290
"""
287291
assert on_error is None or abort_on_error is None, \
@@ -304,6 +308,10 @@ def execute_jobs(
304308
with create_event_reactor(context) as event_controller:
305309
executor.set_event_controller(event_controller)
306310

311+
# allow the caller to post additional events
312+
if pre_execution_callback is not None:
313+
pre_execution_callback(event_queue=event_controller.get_queue())
314+
307315
# pass queue to jobs to publish events
308316
for job in jobs.values():
309317
job.set_event_queue(event_controller.get_queue())

colcon_core/verb/build.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from colcon_core.argument_parser.destination_collector \
1010
import DestinationCollectorDecorator
11+
from colcon_core.event.job import JobUnselected
1112
from colcon_core.event_handler import add_event_handler_arguments
1213
from colcon_core.executor import add_executor_arguments
1314
from colcon_core.executor import execute_jobs
@@ -128,11 +129,22 @@ def main(self, *, context): # noqa: D102
128129

129130
install_base = os.path.abspath(os.path.join(
130131
os.getcwd(), context.args.install_base))
131-
jobs = self._get_jobs(context.args, decorators, install_base)
132+
jobs, unselected_packages = self._get_jobs(
133+
context.args, decorators, install_base)
132134

133135
on_error = OnError.interrupt \
134136
if not context.args.continue_on_error else OnError.skip_downstream
135-
rc = execute_jobs(context, jobs, on_error=on_error)
137+
138+
def post_unselected_packages(*, event_queue):
139+
nonlocal unselected_packages
140+
names = [pkg.name for pkg in unselected_packages]
141+
for name in sorted(names):
142+
event_queue.put(
143+
(JobUnselected(name), None))
144+
145+
rc = execute_jobs(
146+
context, jobs, on_error=on_error,
147+
pre_execution_callback=post_unselected_packages)
136148

137149
self._create_prefix_scripts(install_base, context.args.merge_install)
138150

@@ -153,11 +165,14 @@ def _create_path(self, path):
153165

154166
def _get_jobs(self, args, decorators, install_base):
155167
jobs = OrderedDict()
168+
unselected_packages = set()
156169
for decorator in decorators:
170+
pkg = decorator.descriptor
171+
157172
if not decorator.selected:
173+
unselected_packages.add(pkg)
158174
continue
159175

160-
pkg = decorator.descriptor
161176
extension = get_task_extension('colcon_core.task.build', pkg.type)
162177
if not extension:
163178
logger.warning(
@@ -192,7 +207,7 @@ def _get_jobs(self, args, decorators, install_base):
192207
task=extension, task_context=task_context)
193208

194209
jobs[pkg.name] = job
195-
return jobs
210+
return jobs, unselected_packages
196211

197212
def _create_prefix_scripts(self, install_base, merge_install):
198213
extensions = get_shell_extensions()

test/test_executor.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,12 @@ def test_execute_jobs():
230230
extensions = get_executor_extensions()
231231
extensions[110]['extension2'].execute = \
232232
lambda args, jobs, on_error: 0
233-
rc = execute_jobs(context, jobs, on_error=OnError.interrupt)
233+
callback = Mock()
234+
rc = execute_jobs(
235+
context, jobs, on_error=OnError.interrupt,
236+
pre_execution_callback=callback)
234237
assert rc == 0
235238
assert event_reactor.get_queue().put.call_count == 1
236239
assert isinstance(
237240
event_reactor.get_queue().put.call_args[0][0][0], JobQueued)
241+
assert callback.call_count == 1

0 commit comments

Comments
 (0)