From 0081a12803bfb28b19f21b1d4f604802a8ff92d7 Mon Sep 17 00:00:00 2001 From: Bruce Dawson Date: Sat, 26 Sep 2020 19:13:23 +0000 Subject: [PATCH] Miscellaneous fixes to post_build_ninja_summary.py In Python 3 dict.values() is not a sortable type so it must be converted to a list prior to returning targets data from the ReadTargets function. In Python 3 you cannot compare arbitrary objects. This could happen when sorting task_start_stop_times if the time and types were identical. This is fixed by using the first two entries in the tuple as the sorting key. When a .ninja_log file is corrupt it triggers a diagnostic message which has only caused confusion. This changes that message to suggest the most likely root cause (corruption) since that is the only cause I have seen. If a build step generates multiple targets with long names then wrapping of lines may occur. To avoid that the target description size is capped. Bug: 941669 Change-Id: I2a808d2629a639e231ce2dbf2dab41251110b156 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/2432409 Auto-Submit: Bruce Dawson Commit-Queue: Dirk Pranke Reviewed-by: Dirk Pranke --- post_build_ninja_summary.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/post_build_ninja_summary.py b/post_build_ninja_summary.py index 25c479778..99cbc858a 100644 --- a/post_build_ninja_summary.py +++ b/post_build_ninja_summary.py @@ -104,17 +104,14 @@ class Target: def DescribeTargets(self): """Returns a printable string that summarizes the targets.""" - if len(self.targets) == 1: - return self.targets[0] # Some build steps generate dozens of outputs - handle them sanely. - # It's a bit odd that if there are three targets we return all three - # but if there are more than three we just return two, but this works - # well in practice. - elif len(self.targets) > 3: - return '(%d items) ' % len(self.targets) + ( - ', '.join(self.targets[:2]) + ', ...') - else: - return ', '.join(self.targets) + # The max_length was chosen so that it can fit most of the long + # single-target names, while minimizing word wrapping. + result = ', '.join(self.targets) + max_length = 65 + if len(result) > max_length: + result = result[:max_length] + '...' + return result # Copied with some modifications from ninjatracing @@ -161,7 +158,7 @@ def ReadTargets(log, show_all): targets_dict[cmdhash] = target = Target(start, end) last_end_seen = end target.targets.append(name) - return targets_dict.values() + return list(targets_dict.values()) def GetExtension(target, extra_patterns): @@ -236,7 +233,8 @@ def SummarizeEntries(entries, extra_step_types): length = latest - earliest weighted_total = 0.0 - task_start_stop_times.sort() + # Sort by the time/type records and ignore |target| + task_start_stop_times.sort(key=lambda times: times[:2]) # Now we have all task start/stop times sorted by when they happen. If a # task starts and stops on the same time stamp then the start will come # first because of the alphabet, which is important for making this work @@ -271,7 +269,8 @@ def SummarizeEntries(entries, extra_step_types): # Warn if the sum of weighted times is off by more than half a second. if abs(length - weighted_total) > 500: - print('Discrepancy!!! Length = %.3f, weighted total = %.3f' % ( + print('Warning: Possible corrupt ninja log, results may be ' + 'untrustworthy. Length = %.3f, weighted total = %.3f' % ( length, weighted_total)) # Print the slowest build steps (by weighted time).