summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/ui/knotty.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/ui/knotty.py')
-rw-r--r--bitbake/lib/bb/ui/knotty.py53
1 files changed, 42 insertions, 11 deletions
diff --git a/bitbake/lib/bb/ui/knotty.py b/bitbake/lib/bb/ui/knotty.py
index f86999bb09..9a589a5c8e 100644
--- a/bitbake/lib/bb/ui/knotty.py
+++ b/bitbake/lib/bb/ui/knotty.py
@@ -24,6 +24,12 @@ import atexit
24from itertools import groupby 24from itertools import groupby
25 25
26from bb.ui import uihelper 26from bb.ui import uihelper
27import bb.build
28import bb.command
29import bb.cooker
30import bb.event
31import bb.runqueue
32import bb.utils
27 33
28featureSet = [bb.cooker.CookerFeatures.SEND_SANITYEVENTS, bb.cooker.CookerFeatures.BASEDATASTORE_TRACKING] 34featureSet = [bb.cooker.CookerFeatures.SEND_SANITYEVENTS, bb.cooker.CookerFeatures.BASEDATASTORE_TRACKING]
29 35
@@ -103,7 +109,7 @@ def new_progress(msg, maxval):
103 return NonInteractiveProgress(msg, maxval) 109 return NonInteractiveProgress(msg, maxval)
104 110
105def pluralise(singular, plural, qty): 111def pluralise(singular, plural, qty):
106 if(qty == 1): 112 if qty == 1:
107 return singular % qty 113 return singular % qty
108 else: 114 else:
109 return plural % qty 115 return plural % qty
@@ -112,6 +118,7 @@ def pluralise(singular, plural, qty):
112class InteractConsoleLogFilter(logging.Filter): 118class InteractConsoleLogFilter(logging.Filter):
113 def __init__(self, tf): 119 def __init__(self, tf):
114 self.tf = tf 120 self.tf = tf
121 super().__init__()
115 122
116 def filter(self, record): 123 def filter(self, record):
117 if record.levelno == bb.msg.BBLogFormatter.NOTE and (record.msg.startswith("Running") or record.msg.startswith("recipe ")): 124 if record.levelno == bb.msg.BBLogFormatter.NOTE and (record.msg.startswith("Running") or record.msg.startswith("recipe ")):
@@ -346,7 +353,7 @@ def print_event_log(event, includelogs, loglines, termfilter):
346 termfilter.clearFooter() 353 termfilter.clearFooter()
347 bb.error("Logfile of failure stored in: %s" % logfile) 354 bb.error("Logfile of failure stored in: %s" % logfile)
348 if includelogs and not event.errprinted: 355 if includelogs and not event.errprinted:
349 print("Log data follows:") 356 bb.plain("Log data follows:")
350 f = open(logfile, "r") 357 f = open(logfile, "r")
351 lines = [] 358 lines = []
352 while True: 359 while True:
@@ -359,11 +366,11 @@ def print_event_log(event, includelogs, loglines, termfilter):
359 if len(lines) > int(loglines): 366 if len(lines) > int(loglines):
360 lines.pop(0) 367 lines.pop(0)
361 else: 368 else:
362 print('| %s' % l) 369 bb.plain('| %s' % l)
363 f.close() 370 f.close()
364 if lines: 371 if lines:
365 for line in lines: 372 for line in lines:
366 print(line) 373 bb.plain(line)
367 374
368def _log_settings_from_server(server, observe_only): 375def _log_settings_from_server(server, observe_only):
369 # Get values of variables which control our output 376 # Get values of variables which control our output
@@ -555,13 +562,23 @@ def main(server, eventHandler, params, tf = TerminalFilter):
555 } 562 }
556 }) 563 })
557 564
558 bb.utils.mkdirhier(os.path.dirname(consolelogfile)) 565 consolelogdirname = os.path.dirname(consolelogfile)
559 loglink = os.path.join(os.path.dirname(consolelogfile), 'console-latest.log') 566 # `bb.utils.mkdirhier` has this check, but it reports failure using bb.fatal, which logs
567 # to the very logger we are trying to set up.
568 if '${' in str(consolelogdirname):
569 print(
570 "FATAL: Directory name {} contains unexpanded bitbake variable. This may cause build failures and WORKDIR pollution.".format(
571 consolelogdirname))
572 if '${MACHINE}' in consolelogdirname:
573 print("HINT: It looks like you forgot to set MACHINE in local.conf.")
574
575 bb.utils.mkdirhier(consolelogdirname)
576 loglink = os.path.join(consolelogdirname, 'console-latest.log')
560 bb.utils.remove(loglink) 577 bb.utils.remove(loglink)
561 try: 578 try:
562 os.symlink(os.path.basename(consolelogfile), loglink) 579 os.symlink(os.path.basename(consolelogfile), loglink)
563 except OSError: 580 except OSError:
564 pass 581 pass
565 582
566 # Add the logging domains specified by the user on the command line 583 # Add the logging domains specified by the user on the command line
567 for (domainarg, iterator) in groupby(params.debug_domains): 584 for (domainarg, iterator) in groupby(params.debug_domains):
@@ -577,6 +594,8 @@ def main(server, eventHandler, params, tf = TerminalFilter):
577 else: 594 else:
578 log_exec_tty = False 595 log_exec_tty = False
579 596
597 should_print_hyperlinks = sys.stdout.isatty() and os.environ.get('NO_COLOR', '') == ''
598
580 helper = uihelper.BBUIHelper() 599 helper = uihelper.BBUIHelper()
581 600
582 # Look for the specially designated handlers which need to be passed to the 601 # Look for the specially designated handlers which need to be passed to the
@@ -640,7 +659,7 @@ def main(server, eventHandler, params, tf = TerminalFilter):
640 return_value = 0 659 return_value = 0
641 errors = 0 660 errors = 0
642 warnings = 0 661 warnings = 0
643 taskfailures = [] 662 taskfailures = {}
644 663
645 printintervaldelta = 10 * 60 # 10 minutes 664 printintervaldelta = 10 * 60 # 10 minutes
646 printinterval = printintervaldelta 665 printinterval = printintervaldelta
@@ -726,6 +745,8 @@ def main(server, eventHandler, params, tf = TerminalFilter):
726 if isinstance(event, bb.build.TaskFailed): 745 if isinstance(event, bb.build.TaskFailed):
727 return_value = 1 746 return_value = 1
728 print_event_log(event, includelogs, loglines, termfilter) 747 print_event_log(event, includelogs, loglines, termfilter)
748 k = "{}:{}".format(event._fn, event._task)
749 taskfailures[k] = event.logfile
729 if isinstance(event, bb.build.TaskBase): 750 if isinstance(event, bb.build.TaskBase):
730 logger.info(event._message) 751 logger.info(event._message)
731 continue 752 continue
@@ -821,7 +842,7 @@ def main(server, eventHandler, params, tf = TerminalFilter):
821 842
822 if isinstance(event, bb.runqueue.runQueueTaskFailed): 843 if isinstance(event, bb.runqueue.runQueueTaskFailed):
823 return_value = 1 844 return_value = 1
824 taskfailures.append(event.taskstring) 845 taskfailures.setdefault(event.taskstring)
825 logger.error(str(event)) 846 logger.error(str(event))
826 continue 847 continue
827 848
@@ -942,11 +963,21 @@ def main(server, eventHandler, params, tf = TerminalFilter):
942 try: 963 try:
943 termfilter.clearFooter() 964 termfilter.clearFooter()
944 summary = "" 965 summary = ""
966 def format_hyperlink(url, link_text):
967 if should_print_hyperlinks:
968 start = f'\033]8;;{url}\033\\'
969 end = '\033]8;;\033\\'
970 return f'{start}{link_text}{end}'
971 return link_text
972
945 if taskfailures: 973 if taskfailures:
946 summary += pluralise("\nSummary: %s task failed:", 974 summary += pluralise("\nSummary: %s task failed:",
947 "\nSummary: %s tasks failed:", len(taskfailures)) 975 "\nSummary: %s tasks failed:", len(taskfailures))
948 for failure in taskfailures: 976 for (failure, log_file) in taskfailures.items():
949 summary += "\n %s" % failure 977 summary += "\n %s" % failure
978 if log_file:
979 hyperlink = format_hyperlink(f"file://{log_file}", log_file)
980 summary += "\n log: {}".format(hyperlink)
950 if warnings: 981 if warnings:
951 summary += pluralise("\nSummary: There was %s WARNING message.", 982 summary += pluralise("\nSummary: There was %s WARNING message.",
952 "\nSummary: There were %s WARNING messages.", warnings) 983 "\nSummary: There were %s WARNING messages.", warnings)