blob: f019d4831d37ff8f6a927766c20858779725417d [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# BitBake Build System Python Library
5#
6# Copyright (C) 2003 Holger Schurig
7# Copyright (C) 2003, 2004 Chris Larson
8#
9# Based on Gentoo's portage.py.
10#
11# This program is free software; you can redistribute it and/or modify
12# it under the terms of the GNU General Public License version 2 as
13# published by the Free Software Foundation.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License along
21# with this program; if not, write to the Free Software Foundation, Inc.,
22# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23
Patrick Williamsc0f7c042017-02-23 20:41:17 -060024__version__ = "1.32.0"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050025
26import sys
Patrick Williamsc0f7c042017-02-23 20:41:17 -060027if sys.version_info < (3, 4, 0):
28 raise RuntimeError("Sorry, python 3.4.0 or later is required for this version of bitbake")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050029
30
31class BBHandledException(Exception):
32 """
33 The big dilemma for generic bitbake code is what information to give the user
34 when an exception occurs. Any exception inheriting this base exception class
35 has already provided information to the user via some 'fired' message type such as
36 an explicitly fired event using bb.fire, or a bb.error message. If bitbake
37 encounters an exception derived from this class, no backtrace or other information
38 will be given to the user, its assumed the earlier event provided the relevant information.
39 """
40 pass
41
42import os
43import logging
44
45
46class NullHandler(logging.Handler):
47 def emit(self, record):
48 pass
49
50Logger = logging.getLoggerClass()
51class BBLogger(Logger):
52 def __init__(self, name):
53 if name.split(".")[0] == "BitBake":
54 self.debug = self.bbdebug
55 Logger.__init__(self, name)
56
57 def bbdebug(self, level, msg, *args, **kwargs):
58 return self.log(logging.DEBUG - level + 1, msg, *args, **kwargs)
59
60 def plain(self, msg, *args, **kwargs):
61 return self.log(logging.INFO + 1, msg, *args, **kwargs)
62
63 def verbose(self, msg, *args, **kwargs):
64 return self.log(logging.INFO - 1, msg, *args, **kwargs)
65
66logging.raiseExceptions = False
67logging.setLoggerClass(BBLogger)
68
69logger = logging.getLogger("BitBake")
70logger.addHandler(NullHandler())
71logger.setLevel(logging.DEBUG - 2)
72
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050073mainlogger = logging.getLogger("BitBake.Main")
74
Patrick Williamsc124f4f2015-09-15 14:41:29 -050075# This has to be imported after the setLoggerClass, as the import of bb.msg
76# can result in construction of the various loggers.
77import bb.msg
78
79from bb import fetch2 as fetch
80sys.modules['bb.fetch'] = sys.modules['bb.fetch2']
81
82# Messaging convenience functions
83def plain(*args):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050084 mainlogger.plain(''.join(args))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050085
86def debug(lvl, *args):
Patrick Williamsc0f7c042017-02-23 20:41:17 -060087 if isinstance(lvl, str):
88 mainlogger.warning("Passed invalid debug level '%s' to bb.debug", lvl)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050089 args = (lvl,) + args
90 lvl = 1
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050091 mainlogger.debug(lvl, ''.join(args))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050092
93def note(*args):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050094 mainlogger.info(''.join(args))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050095
96def warn(*args):
Patrick Williamsc0f7c042017-02-23 20:41:17 -060097 mainlogger.warning(''.join(args))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050098
99def error(*args, **kwargs):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500100 mainlogger.error(''.join(args), extra=kwargs)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500101
102def fatal(*args, **kwargs):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500103 mainlogger.critical(''.join(args), extra=kwargs)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500104 raise BBHandledException()
105
106def deprecated(func, name=None, advice=""):
107 """This is a decorator which can be used to mark functions
108 as deprecated. It will result in a warning being emitted
109 when the function is used."""
110 import warnings
111
112 if advice:
113 advice = ": %s" % advice
114 if name is None:
115 name = func.__name__
116
117 def newFunc(*args, **kwargs):
118 warnings.warn("Call to deprecated function %s%s." % (name,
119 advice),
120 category=DeprecationWarning,
121 stacklevel=2)
122 return func(*args, **kwargs)
123 newFunc.__name__ = func.__name__
124 newFunc.__doc__ = func.__doc__
125 newFunc.__dict__.update(func.__dict__)
126 return newFunc
127
128# For compatibility
129def deprecate_import(current, modulename, fromlist, renames = None):
130 """Import objects from one module into another, wrapping them with a DeprecationWarning"""
131 import sys
132
133 module = __import__(modulename, fromlist = fromlist)
134 for position, objname in enumerate(fromlist):
135 obj = getattr(module, objname)
136 newobj = deprecated(obj, "{0}.{1}".format(current, objname),
137 "Please use {0}.{1} instead".format(modulename, objname))
138 if renames:
139 newname = renames[position]
140 else:
141 newname = objname
142
143 setattr(sys.modules[current], newname, newobj)
144