blob: c144311be4c4b24b4058cab4d15c4509707734a3 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#
2# BitBake Build System Python Library
3#
4# Copyright (C) 2003 Holger Schurig
5# Copyright (C) 2003, 2004 Chris Larson
6#
7# Based on Gentoo's portage.py.
8#
Brad Bishopc342db32019-05-15 21:57:59 -04009# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc124f4f2015-09-15 14:41:29 -050010#
Patrick Williamsc124f4f2015-09-15 14:41:29 -050011
Brad Bishopf3f93bb2019-10-16 14:33:32 -040012__version__ = "1.44.0"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050013
14import sys
Patrick Williamsc0f7c042017-02-23 20:41:17 -060015if sys.version_info < (3, 4, 0):
16 raise RuntimeError("Sorry, python 3.4.0 or later is required for this version of bitbake")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050017
18
19class BBHandledException(Exception):
20 """
21 The big dilemma for generic bitbake code is what information to give the user
22 when an exception occurs. Any exception inheriting this base exception class
23 has already provided information to the user via some 'fired' message type such as
24 an explicitly fired event using bb.fire, or a bb.error message. If bitbake
25 encounters an exception derived from this class, no backtrace or other information
26 will be given to the user, its assumed the earlier event provided the relevant information.
27 """
28 pass
29
30import os
31import logging
32
33
34class NullHandler(logging.Handler):
35 def emit(self, record):
36 pass
37
38Logger = logging.getLoggerClass()
39class BBLogger(Logger):
40 def __init__(self, name):
41 if name.split(".")[0] == "BitBake":
42 self.debug = self.bbdebug
43 Logger.__init__(self, name)
44
45 def bbdebug(self, level, msg, *args, **kwargs):
46 return self.log(logging.DEBUG - level + 1, msg, *args, **kwargs)
47
48 def plain(self, msg, *args, **kwargs):
49 return self.log(logging.INFO + 1, msg, *args, **kwargs)
50
51 def verbose(self, msg, *args, **kwargs):
52 return self.log(logging.INFO - 1, msg, *args, **kwargs)
53
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080054 def verbnote(self, msg, *args, **kwargs):
55 return self.log(logging.INFO + 2, msg, *args, **kwargs)
56
57
Patrick Williamsc124f4f2015-09-15 14:41:29 -050058logging.raiseExceptions = False
59logging.setLoggerClass(BBLogger)
60
61logger = logging.getLogger("BitBake")
62logger.addHandler(NullHandler())
63logger.setLevel(logging.DEBUG - 2)
64
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050065mainlogger = logging.getLogger("BitBake.Main")
66
Patrick Williamsc124f4f2015-09-15 14:41:29 -050067# This has to be imported after the setLoggerClass, as the import of bb.msg
68# can result in construction of the various loggers.
69import bb.msg
70
71from bb import fetch2 as fetch
72sys.modules['bb.fetch'] = sys.modules['bb.fetch2']
73
74# Messaging convenience functions
75def plain(*args):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050076 mainlogger.plain(''.join(args))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050077
78def debug(lvl, *args):
Patrick Williamsc0f7c042017-02-23 20:41:17 -060079 if isinstance(lvl, str):
80 mainlogger.warning("Passed invalid debug level '%s' to bb.debug", lvl)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050081 args = (lvl,) + args
82 lvl = 1
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050083 mainlogger.debug(lvl, ''.join(args))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050084
85def note(*args):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050086 mainlogger.info(''.join(args))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050087
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080088#
89# A higher prioity note which will show on the console but isn't a warning
90#
91# Something is happening the user should be aware of but they probably did
92# something to make it happen
93#
94def verbnote(*args):
95 mainlogger.verbnote(''.join(args))
96
97#
98# Warnings - things the user likely needs to pay attention to and fix
99#
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500100def warn(*args):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600101 mainlogger.warning(''.join(args))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500102
103def error(*args, **kwargs):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500104 mainlogger.error(''.join(args), extra=kwargs)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500105
106def fatal(*args, **kwargs):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500107 mainlogger.critical(''.join(args), extra=kwargs)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500108 raise BBHandledException()
109
110def deprecated(func, name=None, advice=""):
111 """This is a decorator which can be used to mark functions
112 as deprecated. It will result in a warning being emitted
113 when the function is used."""
114 import warnings
115
116 if advice:
117 advice = ": %s" % advice
118 if name is None:
119 name = func.__name__
120
121 def newFunc(*args, **kwargs):
122 warnings.warn("Call to deprecated function %s%s." % (name,
123 advice),
124 category=DeprecationWarning,
125 stacklevel=2)
126 return func(*args, **kwargs)
127 newFunc.__name__ = func.__name__
128 newFunc.__doc__ = func.__doc__
129 newFunc.__dict__.update(func.__dict__)
130 return newFunc
131
132# For compatibility
133def deprecate_import(current, modulename, fromlist, renames = None):
134 """Import objects from one module into another, wrapping them with a DeprecationWarning"""
135 import sys
136
137 module = __import__(modulename, fromlist = fromlist)
138 for position, objname in enumerate(fromlist):
139 obj = getattr(module, objname)
140 newobj = deprecated(obj, "{0}.{1}".format(current, objname),
141 "Please use {0}.{1} instead".format(modulename, objname))
142 if renames:
143 newname = renames[position]
144 else:
145 newname = objname
146
147 setattr(sys.modules[current], newname, newobj)
148