Update version to 1.15.3
[bitbake.git] / lib / bb / __init__.py
1 # 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
24 __version__ = "1.15.3"
25
26 import sys
27 if sys.version_info < (2, 6, 0):
28     raise RuntimeError("Sorry, python 2.6.0 or later is required for this version of bitbake")
29
30
31 class 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
42 import os
43 import logging
44
45
46 class NullHandler(logging.Handler):
47     def emit(self, record):
48         pass
49
50 Logger = logging.getLoggerClass()
51 class 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
66 logging.raiseExceptions = False
67 logging.setLoggerClass(BBLogger)
68
69 logger = logging.getLogger("BitBake")
70 logger.addHandler(NullHandler())
71 logger.setLevel(logging.DEBUG - 2)
72
73 # This has to be imported after the setLoggerClass, as the import of bb.msg
74 # can result in construction of the various loggers.
75 import bb.msg
76
77 if "BBDEBUG" in os.environ:
78     level = int(os.environ["BBDEBUG"])
79     if level:
80         bb.msg.set_debug_level(level)
81
82 from bb import fetch2 as fetch
83 sys.modules['bb.fetch'] = sys.modules['bb.fetch2']
84
85 # Messaging convenience functions
86 def plain(*args):
87     logger.plain(''.join(args))
88
89 def debug(lvl, *args):
90     if isinstance(lvl, basestring):
91         logger.warn("Passed invalid debug level '%s' to bb.debug", lvl)
92         args = (lvl,) + args
93         lvl = 1
94     logger.debug(lvl, ''.join(args))
95
96 def note(*args):
97     logger.info(''.join(args))
98
99 def warn(*args):
100     logger.warn(''.join(args))
101
102 def error(*args):
103     logger.error(''.join(args))
104
105 def fatal(*args):
106     logger.critical(''.join(args))
107     sys.exit(1)
108
109
110 def 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 emmitted
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
133 def 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
149 deprecate_import(__name__, "bb.fetch", ("MalformedUrl", "encodeurl", "decodeurl"))
150 deprecate_import(__name__, "bb.utils", ("mkdirhier", "movefile", "copyfile", "which"))
151 deprecate_import(__name__, "bb.utils", ["vercmp_string"], ["vercmp"])