Skip to content

Commit 8427681

Browse files
committed
Summarize package statistics, not jobs
To date, the colcon task model has always had a one-to-one relationship between packages and jobs, despite separation at the code level. All jobs are associated with a single package, but it is possible to associate multiple jobs with a single job. Likely because of this one-to-one relationship, the job identifier and package name have often been used interchangeably throughout the colcon codebase. Because all job identifiers must be unique, we'll need to break this pattern. This change re-orients the statistics presented in the `console_summary` event handler around packages by treating multiple jobs for a single package as if they were a single job, meaning that a package isn't finished building until ALL of the jobs finish. Because all _current_ use cases maintain the one-to-one relationship, this change should not result in any difference in behavior today.
1 parent e44b5c1 commit 8427681

1 file changed

Lines changed: 32 additions & 17 deletions

File tree

colcon_output/event_handler/summary.py

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -71,47 +71,62 @@ def _print_summary(self):
7171
duration = time.monotonic() - self._start_time
7272
duration_string = format_duration(duration)
7373

74-
count, job_type, _ = _msg_arguments(
75-
self._ended - self._interrupted - self._failed)
74+
blocked_jobs = self._queued - self._ended
75+
76+
# convert jobs to package names
77+
ended = {j.task_context.pkg for j in self._ended}
78+
interrupted = {j.task_context.pkg for j in self._interrupted}
79+
failed = {j.task_context.pkg for j in self._failed}
80+
with_stderr = {j.task_context.pkg for j in self._with_stderr}
81+
with_test_failures = {
82+
j.task_context.pkg for j in self._with_test_failures}
83+
blocked = {j.task_context.pkg for j in blocked_jobs}
84+
85+
# packages with successful jobs and blocked jobs are "interrupted"
86+
interrupted |= ended & blocked - failed
87+
88+
# truly "blocked" packages have no jobs attempted
89+
blocked -= ended
90+
91+
count, job_type, _ = _msg_arguments(ended - interrupted - failed)
7692
print('Summary: {count} {job_type} finished '
7793
'[{duration_string}]'.format_map(locals()))
7894

79-
if self._failed:
80-
count, job_type, names = _msg_arguments(self._failed)
95+
if failed:
96+
count, job_type, names = _msg_arguments(failed)
8197
print(' {count} {job_type} failed: {names}'
8298
.format_map(locals()))
8399

84-
if self._interrupted:
85-
count, job_type, names = _msg_arguments(self._interrupted)
100+
if interrupted:
101+
count, job_type, names = _msg_arguments(interrupted)
86102
print(' {count} {job_type} aborted: {names}'
87103
.format_map(locals()))
88104

89-
if self._with_stderr:
90-
count, job_type, names = _msg_arguments(self._with_stderr)
105+
if with_stderr:
106+
count, job_type, names = _msg_arguments(with_stderr)
91107
print(
92108
' {count} {job_type} had stderr output: {names}'
93109
.format_map(locals()))
94110

95-
if self._with_test_failures:
96-
count, job_type, names = _msg_arguments(
97-
self._with_test_failures)
111+
if with_test_failures:
112+
count, job_type, names = _msg_arguments(with_test_failures)
98113
print(
99114
' {count} {job_type} had test failures: {names}'
100115
.format_map(locals()))
101116

102-
if len(self._queued) > len(self._ended):
103-
count = len(self._queued - self._ended)
117+
if blocked:
118+
count = len(blocked)
104119
job_type = get_job_type_word_form(count)
105120
print(
106121
' {count} {job_type} not processed'
107122
.format_map(locals()))
108123

109124

110-
def _msg_arguments(jobs):
125+
def _msg_arguments(packages):
111126
return (
112-
len(jobs),
113-
get_job_type_word_form(len(jobs)),
114-
' '.join(sorted(j.task.context.pkg.name for j in jobs)),
127+
len(packages),
128+
get_job_type_word_form(len(packages)),
129+
' '.join(sorted(p.name for p in packages)),
115130
)
116131

117132

0 commit comments

Comments
 (0)