From 4651e6cf84fea69c52d88b57f7ccc9a322933d7b Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sat, 8 Jul 2006 16:30:02 +0000 Subject: bitbake/lib/bb/__init__.py: bitbake/lib/bb/build.py: bitbake/lib/bb/utils.py: bitbake/lib/bb/shell.py: bitbake/lib/bb/providers.py: bitbake/lib/bb/msg.py: bitbake/bin/bitbake: bitbake/bin/bitdoc: bitbake/classes/base.bbclass: Start an overhaul of the message handling in bitbake: - Introduce a new msg module to replace the existing simple calls. - The msg module adds the conncept of message domains so ultimately we can select which kinds of debug messages we want to see (it uses an Enum class for this) - Add a warn logging level for things the user should really pay attention to as note is a little overloaded at present - Start converting to use the new fuctions --- bin/bitbake | 142 +++++++++++++++++++++++++-------------------------- bin/bitdoc | 2 +- classes/base.bbclass | 2 +- lib/bb/__init__.py | 22 +++----- lib/bb/build.py | 10 ++-- lib/bb/msg.py | 84 ++++++++++++++++++++++++++++++ lib/bb/providers.py | 13 +++-- lib/bb/shell.py | 4 +- lib/bb/utils.py | 40 +++++++++++++++ 9 files changed, 215 insertions(+), 104 deletions(-) create mode 100644 lib/bb/msg.py diff --git a/bin/bitbake b/bin/bitbake index 5a9ee428b..e5f152757 100755 --- a/bin/bitbake +++ b/bin/bitbake @@ -24,12 +24,11 @@ import sys, os, getopt, glob, copy, os.path, re, time sys.path.insert(0,os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib')) import bb -from bb import utils, data, parse, debug, event, fatal, cache, providers +from bb import utils, data, parse, event, cache, providers from sets import Set import itertools, optparse parsespin = itertools.cycle( r'|/-\\' ) -bbdebug = 0 __version__ = "1.5.0" @@ -229,14 +228,14 @@ class BBCooker: return True except bb.build.FuncFailed: self.stats.fail += 1 - bb.error("task stack execution failed") + bb.msg.error(bb.msg.domain.Build, "task stack execution failed") bb.event.fire(bb.event.PkgFailed(item, the_data)) self.build_cache_fail.append(fn) raise except bb.build.EventException, e: self.stats.fail += 1 event = e.args[1] - bb.error("%s event exception, aborting" % bb.event.getName(event)) + bb.msg.error(bb.msg.domain.Build, "%s event exception, aborting" % bb.event.getName(event)) bb.event.fire(bb.event.PkgFailed(item, the_data)) self.build_cache_fail.append(fn) raise @@ -256,8 +255,8 @@ class BBCooker: # Error on build time dependency loops if build_depends and build_depends.count(fn) > 1: - bb.error("%s depends on itself (eventually)" % fn) - bb.error("upwards chain is: %s" % (" -> ".join(self.build_path))) + bb.msg.error(bb.msg.domain.Depends, "%s depends on itself (eventually)" % fn) + bb.msg.error(bb.msg.domain.Depends, "upwards chain is: %s" % (" -> ".join(self.build_path))) return False # See if this is a runtime dependency we've already built @@ -274,9 +273,8 @@ class BBCooker: depends_list = (bb.data.getVar('DEPENDS', the_data, True) or "").split() - if self.configuration.verbose: - bb.note("current path: %s" % (" -> ".join(self.build_path))) - bb.note("dependencies for %s are: %s" % (item, " ".join(depends_list))) + bb.msg.note(2, bb.msg.domain.Depends, "current path: %s" % (" -> ".join(self.build_path))) + bb.msg.note(2, bb.msg.domain.Depends, "dependencies for %s are: %s" % (item, " ".join(depends_list))) try: failed = False @@ -299,7 +297,7 @@ class BBCooker: if not depcmd: continue if self.buildProvider( dependency , buildAllDeps , build_depends ) == 0: - bb.error("dependency %s (for %s) not satisfied" % (dependency,item)) + bb.msg.error(bb.msg.domain.Depends, "dependency %s (for %s) not satisfied" % (dependency,item)) failed = True if self.configuration.abort: break @@ -360,15 +358,15 @@ class BBCooker: try: self.configuration.data = self.bb_cache.loadDataFull(self.configuration.buildfile, self) except IOError, e: - fatal("Unable to read %s: %s" % ( self.configuration.buildfile, e )) + bb.msg.fatal(bb.msg.domain.Parsing, "Unable to read %s: %s" % ( self.configuration.buildfile, e )) except Exception, e: - fatal("%s" % e) + bb.msg.fatal(bb.msg.domain.Parsing, "%s" % e) # emit variables and shell functions try: data.update_data( self.configuration.data ) data.emit_env(sys.__stdout__, self.configuration.data, True) except Exception, e: - fatal("%s" % e) + bb.msg.fatal(bb.msg.domain.Parsing, "%s" % e) # emit the metadata which isnt valid shell for e in self.configuration.data.keys(): if data.getVarFlag( e, 'python', self.configuration.data ): @@ -401,7 +399,7 @@ class BBCooker: pkg_pn[pn] = [] pkg_pn[pn].append(p) - bb.debug(1, "providers for %s are: %s" % (item, pkg_pn.keys())) + bb.msg.debug(1, bb.msg.domain.Provider, "providers for %s are: %s" % (item, pkg_pn.keys())) for pn in pkg_pn.keys(): preferred_versions[pn] = self.findBestProvider(pn, pkg_pn)[2:4] @@ -409,11 +407,11 @@ class BBCooker: for p in eligible: if p in self.build_cache_fail: - bb.debug(1, "rejecting already-failed %s" % p) + bb.msg.debug(1, bb.msg.domain.Provider, "rejecting already-failed %s" % p) eligible.remove(p) if len(eligible) == 0: - bb.error("no eligible providers for %s" % item) + bb.msg.error(bb.msg.domain.Provider, "no eligible providers for %s" % item) return 0 prefervar = bb.data.getVar('PREFERRED_PROVIDER_%s' % item, self.configuration.data, 1) @@ -422,7 +420,7 @@ class BBCooker: if prefervar: for p in eligible: if prefervar == self.status.pkg_fn[p]: - bb.note("Selecting PREFERRED_PROVIDER %s" % prefervar) + bb.msg.note(1, bb.msg.domain.Provider, "Selecting PREFERRED_PROVIDER %s" % prefervar) eligible.remove(p) eligible = [p] + eligible @@ -554,7 +552,7 @@ class BBCooker: discriminated = False if not item in self.status.providers: - bb.error("Nothing provides dependency %s" % item) + bb.msg.error(bb.msg.domain.Depends, "Nothing provides dependency %s" % item) bb.event.fire(bb.event.NoProvider(item,self.configuration.data)) return 0 @@ -562,10 +560,10 @@ class BBCooker: for p in all_p: if p in self.build_cache: - bb.debug(1, "already built %s in this run\n" % p) + bb.msg.debug(1, bb.msg.domain.Provider, "already built %s in this run" % p) return 1 - eligible = bb.providers.filterProviders(all_p, item, self.configuration.data, self.status, self.build_cache_fail, self.configuration.verbose) + eligible = bb.providers.filterProviders(all_p, item, self.configuration.data, self.status, self.build_cache_fail) if not eligible: return 0 @@ -578,8 +576,7 @@ class BBCooker: for p in eligible: pn = self.status.pkg_fn[p] if self.preferred[item] == pn: - if self.configuration.verbose: - bb.note("selecting %s to satisfy %s due to PREFERRED_PROVIDERS" % (pn, item)) + bb.msg.note(2, bb.msg.domain.Provider, "selecting %s to satisfy %s due to PREFERRED_PROVIDERS" % (pn, item)) eligible.remove(p) eligible = [p] + eligible discriminated = True @@ -590,19 +587,19 @@ class BBCooker: providers_list = [] for fn in eligible: providers_list.append(self.status.pkg_fn[fn]) - bb.note("multiple providers are available (%s);" % ", ".join(providers_list)) - bb.note("consider defining PREFERRED_PROVIDER_%s" % item) + bb.msg.note(1, bb.msg.domain.Provider, "multiple providers are available (%s);" % ", ".join(providers_list)) + bb.msg.note(1, bb.msg.domain.Provider, "consider defining PREFERRED_PROVIDER_%s" % item) bb.event.fire(bb.event.MultipleProviders(item,providers_list,self.configuration.data)) self.consider_msgs_cache.append(item) # run through the list until we find one that we can build for fn in eligible: - bb.debug(2, "selecting %s to satisfy %s" % (fn, item)) + bb.msg.debug(2, bb.msg.domain.Provider, "selecting %s to satisfy %s" % (fn, item)) if self.tryBuild(fn, item, buildAllDeps, build_depends + [fn]): return 1 - bb.note("no buildable providers for %s" % item) + bb.msg.note(1, bb.msg.domain.Provider, "no buildable providers for %s" % item) bb.event.fire(bb.event.NoProvider(item,self.configuration.data)) return 0 @@ -622,19 +619,19 @@ class BBCooker: all_p = self.getProvidersRun(item) if not all_p: - bb.error("Nothing provides runtime dependency %s" % (item)) + bb.msg.error(bb.msg.domain.Provider, "Nothing provides runtime dependency %s" % (item)) bb.event.fire(bb.event.NoProvider(item,self.configuration.data,runtime=True)) return False for p in all_p: if p in self.rbuild_cache: - bb.debug(2, "Already built %s providing runtime %s\n" % (p,item)) + bb.msg.debug(2, bb.msg.domain.Provider, "Already built %s providing runtime %s" % (p,item)) return True if p in self.build_cache: - bb.debug(2, "Already built %s but adding any further RDEPENDS for %s\n" % (p, item)) + bb.msg.debug(2, bb.msg.domain.Provider, "Already built %s but adding any further RDEPENDS for %s" % (p, item)) return self.addRunDeps(p, item , buildAllDeps) - eligible = bb.providers.filterProviders(all_p, item, self.configuration.data, self.status, self.build_cache_fail, self.configuration.verbose) + eligible = bb.providers.filterProviders(all_p, item, self.configuration.data, self.status, self.build_cache_fail) if not eligible: return 0 @@ -645,8 +642,7 @@ class BBCooker: for provide in provides: prefervar = bb.data.getVar('PREFERRED_PROVIDER_%s' % provide, self.configuration.data, 1) if prefervar == pn: - if self.configuration.verbose: - bb.note("selecting %s to satisfy runtime %s due to PREFERRED_PROVIDERS" % (pn, item)) + bb.msg.note(2, bb.msg.domain.Provider, "selecting %s to satisfy runtime %s due to PREFERRED_PROVIDERS" % (pn, item)) eligible.remove(p) eligible = [p] + eligible preferred.append(p) @@ -656,8 +652,8 @@ class BBCooker: providers_list = [] for fn in eligible: providers_list.append(self.status.pkg_fn[fn]) - bb.note("multiple providers are available (%s);" % ", ".join(providers_list)) - bb.note("consider defining a PREFERRED_PROVIDER to match runtime %s" % item) + bb.msg.note(1, bb.msg.domain.Provider, "multiple providers are available (%s);" % ", ".join(providers_list)) + bb.msg.note(1, bb.msg.domain.Provider, "consider defining a PREFERRED_PROVIDER to match runtime %s" % item) bb.event.fire(bb.event.MultipleProviders(item,providers_list,self.configuration.data,runtime=True)) self.consider_msgs_cache.append(item) @@ -666,18 +662,18 @@ class BBCooker: providers_list = [] for fn in preferred: providers_list.append(self.status.pkg_fn[fn]) - bb.note("multiple preferred providers are available (%s);" % ", ".join(providers_list)) - bb.note("consider defining only one PREFERRED_PROVIDER to match runtime %s" % item) + bb.msg.note(1, bb.msg.domain.Provider, "multiple preferred providers are available (%s);" % ", ".join(providers_list)) + bb.msg.note(1, bb.msg.domain.Provider, "consider defining only one PREFERRED_PROVIDER to match runtime %s" % item) bb.event.fire(bb.event.MultipleProviders(item,providers_list,self.configuration.data,runtime=True)) self.consider_msgs_cache.append(item) # run through the list until we find one that we can build for fn in eligible: - bb.debug(2, "selecting %s to satisfy runtime %s" % (fn, item)) + bb.msg.debug(2, bb.msg.domain.Provider, "selecting %s to satisfy runtime %s" % (fn, item)) if self.tryBuild(fn, item, buildAllDeps): return True - bb.error("No buildable providers for runtime %s" % item) + bb.msg.error(bb.msg.domain.Provider, "No buildable providers for runtime %s" % item) bb.event.fire(bb.event.NoProvider(item,self.configuration.data)) return False @@ -724,7 +720,7 @@ class BBCooker: if fn in self.status.runrecs and item in self.status.runrecs[fn]: rdepends += self.status.runrecs[fn][item].keys() - bb.debug(2, "Additional runtime dependencies for %s are: %s" % (item, " ".join(rdepends))) + bb.msg.debug(2, bb.msg.domain.Provider, "Additional runtime dependencies for %s are: %s" % (item, " ".join(rdepends))) for rdepend in rdepends: if rdepend in self.status.ignored_dependencies: @@ -750,7 +746,7 @@ class BBCooker: for p in (bb.data.getVar('PREFERRED_PROVIDERS', localdata, 1) or "").split(): (providee, provider) = p.split(':') if providee in self.preferred and self.preferred[providee] != provider: - bb.error("conflicting preferences for %s: both %s and %s specified" % (providee, provider, self.preferred[providee])) + bb.msg.error(bb.msg.domain.Provider, "conflicting preferences for %s: both %s and %s specified" % (providee, provider, self.preferred[providee])) self.preferred[providee] = provider # Calculate priorities for each file @@ -763,19 +759,19 @@ class BBCooker: """ all_depends = self.status.all_depends pn_provides = self.status.pn_provides - bb.debug(1, "collating packages for \"world\"") + bb.msg.debug(1, bb.msg.domain.Parsing, "collating packages for \"world\"") for f in self.status.possible_world: terminal = True pn = self.status.pkg_fn[f] for p in pn_provides[pn]: if p.startswith('virtual/'): - bb.debug(2, "skipping %s due to %s provider starting with virtual/" % (f, p)) + bb.msg.debug(2, bb.msg.domain.Parsing, "World build skipping %s due to %s provider starting with virtual/" % (f, p)) terminal = False break for pf in self.status.providers[p]: if self.status.pkg_fn[pf] != pn: - bb.debug(2, "skipping %s due to both us and %s providing %s" % (f, pf, p)) + bb.msg.debug(2, bb.msg.domain.Parsing, "World build skipping %s due to both us and %s providing %s" % (f, pf, p)) terminal = False break if terminal: @@ -790,8 +786,6 @@ class BBCooker: self.status.handle_bb_data(f, bb_cache, from_cache) - if bbdebug > 0: - return if os.isatty(sys.stdout.fileno()): sys.stdout.write("\rNOTE: Handling BitBake files: %s (%04d/%04d) [%2d %%]" % ( parsespin.next(), x, y, x*100/y ) ) sys.stdout.flush() @@ -808,7 +802,7 @@ class BBCooker: try: from bb import shell except ImportError, details: - bb.fatal("Sorry, shell not available (%s)" % details ) + bb.msg.fatal(bb.msg.domain.Parsing, "Sorry, shell not available (%s)" % details ) else: bb.data.update_data( self.configuration.data ) shell.start( self ) @@ -833,9 +827,9 @@ class BBCooker: bb.event.register(var,bb.data.getVar(var, data)) except IOError: - bb.fatal( "Unable to open %s" % afile ) + bb.msg.fatal(bb.msg.domain.Parsing, "Unable to open %s" % afile ) except bb.parse.ParseError, details: - bb.fatal( "Unable to parse %s (%s)" % (afile, details) ) + bb.msg.fatal(bb.msg.domain.Parsing, "Unable to parse %s (%s)" % (afile, details) ) def handleCollections( self, collections ): """Handle collections""" @@ -844,22 +838,22 @@ class BBCooker: for c in collection_list: regex = bb.data.getVar("BBFILE_PATTERN_%s" % c, self.configuration.data, 1) if regex == None: - bb.error("BBFILE_PATTERN_%s not defined" % c) + bb.msg.error(bb.msg.domain.Parsing, "BBFILE_PATTERN_%s not defined" % c) continue priority = bb.data.getVar("BBFILE_PRIORITY_%s" % c, self.configuration.data, 1) if priority == None: - bb.error("BBFILE_PRIORITY_%s not defined" % c) + bb.msg.error(bb.msg.domain.Parsing, "BBFILE_PRIORITY_%s not defined" % c) continue try: cre = re.compile(regex) except re.error: - bb.error("BBFILE_PATTERN_%s \"%s\" is not a valid regular expression" % (c, regex)) + bb.msg.error(bb.msg.domain.Parsing, "BBFILE_PATTERN_%s \"%s\" is not a valid regular expression" % (c, regex)) continue try: pri = int(priority) self.status.bbfile_config_priorities.append((cre, pri)) except ValueError: - bb.error("invalid value for BBFILE_PRIORITY_%s: \"%s\"" % (c, priority)) + bb.msg.error(bb.msg.domain.Parsing, "invalid value for BBFILE_PRIORITY_%s: \"%s\"" % (c, priority)) def cook( self, configuration, args ): @@ -871,11 +865,14 @@ class BBCooker: self.configuration = configuration + if self.configuration.verbose: + bb.msg.set_verbose(True) + if not self.configuration.cmd: self.configuration.cmd = "build" if self.configuration.debug: - bb.debug_level = self.configuration.debug + bb.msg.set_debug_level(self.configuration.debug) self.configuration.data = bb.data.init() @@ -910,13 +907,13 @@ class BBCooker: try: bbfile_data = bb.parse.handle(bf, self.configuration.data) except IOError: - bb.fatal("Unable to open %s" % bf) + bb.msg.fatal(bb.msg.domain.Parsing, "Unable to open %s" % bf) item = bb.data.getVar('PN', bbfile_data, 1) try: self.tryBuildPackage( bf, item, bbfile_data ) except bb.build.EventException: - bb.error( "Build of '%s' failed" % item ) + bb.msg.error(bb.msg.domain.Build, "Build of '%s' failed" % item ) sys.exit( self.stats.show() ) @@ -949,21 +946,19 @@ class BBCooker: try: import psyco except ImportError: - if bbdebug == 0: - bb.note("Psyco JIT Compiler (http://psyco.sf.net) not available. Install it to increase performance.") + bb.msg.note(1, bb.msg.domain.Collection, "Psyco JIT Compiler (http://psyco.sf.net) not available. Install it to increase performance.") else: psyco.bind( self.collect_bbfiles ) else: - bb.note("You have disabled Psyco. This decreases performance.") + bb.msg.note(1, bb.msg.domain.Collection, "You have disabled Psyco. This decreases performance.") try: - bb.debug(1, "collecting .bb files") + bb.msg.debug(1, bb.msg.domain.Collection, "collecting .bb files") self.collect_bbfiles( self.myProgressCallback ) - bb.debug(1, "parsing complete") - if bbdebug == 0: - print + bb.msg.debug(1, bb.msg.domain.Collection, "parsing complete") + print if self.configuration.parse_only: - print "Requested parsing .bb files only. Exiting." + bb.msg.note(1, bb.msg.domain.Collection, "Requested parsing .bb files only. Exiting.") return @@ -993,7 +988,7 @@ class BBCooker: # already diagnosed failed = True except bb.build.EventException: - bb.error("Build of " + k + " failed") + bb.msg.error(bb.msg.domain.Build, "Build of " + k + " failed") failed = True if failed: @@ -1006,7 +1001,7 @@ class BBCooker: sys.exit( self.stats.show() ) except KeyboardInterrupt: - print "\nNOTE: KeyboardInterrupt - Build not completed." + bb.msg.note(1, bb.msg.domain.Collection, "KeyboardInterrupt - Build not completed.") sys.exit(1) def get_bbfiles( self, path = os.getcwd() ): @@ -1041,7 +1036,7 @@ class BBCooker: files = self.get_bbfiles() if not len(files): - bb.error("no files to build.") + bb.msg.error(bb.msg.domain.Collection, "no files to build.") newfiles = [] for f in files: @@ -1056,22 +1051,22 @@ class BBCooker: try: bbmask_compiled = re.compile(bbmask) except sre_constants.error: - bb.fatal("BBMASK is not a valid regular expression.") + bb.msg.fatal(bb.msg.domain.Collection, "BBMASK is not a valid regular expression.") for i in xrange( len( newfiles ) ): f = newfiles[i] if bbmask and bbmask_compiled.search(f): - bb.debug(1, "bbmake: skipping %s" % f) + bb.msg.debug(1, bb.msg.domain.Collection, "bbmake: skipping %s" % f, f) masked += 1 continue - debug(1, "bbmake: parsing %s" % f) + bb.msg.debug(1, bb.msg.domain.Collection, "bbmake: parsing %s" % f, f) # read a file's metadata try: fromCache, skip = self.bb_cache.loadData(f, self) if skip: skipped += 1 - #bb.note("Skipping %s" % f) + bb.msg.debug(2, bb.msg.domain.Collection, "Skipping %s" % f, f) self.bb_cache.skip(f) continue elif fromCache: cached += 1 @@ -1094,20 +1089,21 @@ class BBCooker: except IOError, e: self.bb_cache.remove(f) - bb.error("opening %s: %s" % (f, e)) + bb.msg.error(bb.msg.domain.Collection, "opening %s: %s" % (f, e), f) pass except KeyboardInterrupt: self.bb_cache.sync() raise except Exception, e: self.bb_cache.remove(f) - bb.error("%s while parsing %s" % (e, f)) + bb.msg.error(bb.msg.domain.Collection, "%s while parsing %s" % (e, f), f) except: self.bb_cache.remove(f) raise if self.cb is not None: - print "\rNOTE: Parsing finished. %d cached, %d parsed, %d skipped, %d masked." % ( cached, parsed, skipped, masked ), + print "\r" # need newline after Handling Bitbake files message + bb.msg.note(1, bb.msg.domain.Collection, "Parsing finished. %d cached, %d parsed, %d skipped, %d masked." % ( cached, parsed, skipped, masked )) self.bb_cache.sync() diff --git a/bin/bitdoc b/bin/bitdoc index 84d2ee23c..e865e1b99 100755 --- a/bin/bitdoc +++ b/bin/bitdoc @@ -442,7 +442,7 @@ Create a set of html pages (documentation) for a bitbake.conf.... options, args = parser.parse_args( sys.argv ) if options.debug: - bb.debug_level = options.debug + bb.msg.set_debug_level(options.debug) return options.config, options.output diff --git a/classes/base.bbclass b/classes/base.bbclass index 1d75964f5..cfb82a41c 100644 --- a/classes/base.bbclass +++ b/classes/base.bbclass @@ -41,7 +41,7 @@ bbdebug() { exit 1 } - test ${@bb.debug_level} -ge $1 && { + test ${@bb.msg.debug_level} -ge $1 && { shift echo "DEBUG:" $* } diff --git a/lib/bb/__init__.py b/lib/bb/__init__.py index 8d825dbe8..46043239f 100644 --- a/lib/bb/__init__.py +++ b/lib/bb/__init__.py @@ -69,19 +69,16 @@ __all__ = [ whitespace = '\t\n\x0b\x0c\r ' lowercase = 'abcdefghijklmnopqrstuvwxyz' -import sys, os, types, re, string +import sys, os, types, re, string, bb +from bb import msg #projectdir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0]))) projectdir = os.getcwd() -debug_level = 0 - if "BBDEBUG" in os.environ: level = int(os.environ["BBDEBUG"]) if level: - debug_level = level - else: - debug_level = 0 + bb.msg.set_debug_level(level) class VarExpandError(Exception): pass @@ -100,22 +97,17 @@ class MalformedUrl(Exception): ####################################################################### ####################################################################### -debug_prepend = '' - - def debug(lvl, *args): - if debug_level >= lvl: - print debug_prepend + 'DEBUG:', ''.join(args) + bb.msg.std_debug(lvl, ''.join(args)) def note(*args): - print debug_prepend + 'NOTE:', ''.join(args) + bb.msg.std_note(''.join(args)) def error(*args): - print debug_prepend + 'ERROR:', ''.join(args) + bb.msg.std_error(''.join(args)) def fatal(*args): - print debug_prepend + 'ERROR:', ''.join(args) - sys.exit(1) + bb.msg.std_fatal(''.join(args)) ####################################################################### diff --git a/lib/bb/build.py b/lib/bb/build.py index c8928deb1..99fb29079 100644 --- a/lib/bb/build.py +++ b/lib/bb/build.py @@ -25,7 +25,7 @@ You should have received a copy of the GNU General Public License along with Based on functions from the base bb module, Copyright 2003 Holger Schurig """ -from bb import debug, data, fetch, fatal, error, note, event, mkdirhier, utils +from bb import data, fetch, fatal, error, note, event, mkdirhier, utils import bb, os # events @@ -146,7 +146,7 @@ def exec_func_shell(func, d): f = open(runfile, "w") f.write("#!/bin/sh -e\n") - if bb.debug_level > 0: f.write("set -x\n") + if bb.msg.debug_level > 0: f.write("set -x\n") data.emit_env(f, d) f.write("cd %s\n" % os.getcwd()) @@ -160,7 +160,7 @@ def exec_func_shell(func, d): # open logs si = file('/dev/null', 'r') try: - if bb.debug_level > 0: + if bb.msg.debug_level > 0: so = os.popen("tee \"%s\"" % logfile, "w") else: so = file(logfile, 'w') @@ -208,7 +208,7 @@ def exec_func_shell(func, d): os.close(ose[0]) if ret==0: - if bb.debug_level > 0: + if bb.msg.debug_level > 0: os.remove(runfile) # os.remove(logfile) return @@ -265,7 +265,7 @@ def exec_task(task, d): return 1 try: - debug(1, "Executing task %s" % item) + bb.msg.debug(1, bb.msg.domain.Build, "Executing task %s" % item) old_overrides = data.getVar('OVERRIDES', d, 0) localdata = data.createCopy(d) data.setVar('OVERRIDES', 'task_%s:%s' % (item, old_overrides), localdata) diff --git a/lib/bb/msg.py b/lib/bb/msg.py new file mode 100644 index 000000000..1de0e4591 --- /dev/null +++ b/lib/bb/msg.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python +# ex:ts=4:sw=4:sts=4:et +# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- +""" +BitBake 'msg' implementation + +Message handling infrastructure for bitbake + +# Copyright (C) 2006 Richard Purdie + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA. + +""" + +import os, re, bb +from bb import utils + +debug_level = 0 + +verbose = False + +domain = bb.utils.Enum('Depends', 'Provider', 'Build', 'Parsing', 'Collection') + +# +# Message control functions +# + +def set_debug_level(level): + bb.msg.debug_level = level + +def set_verbose(level): + bb.msg.verbose = level + +# +# Message handling functions +# + +def debug(level, domain, msg, fn = None): + std_debug(level, msg) + +def note(level, domain, msg, fn = None): + if level == 1 or verbose: + std_note(msg) + +def warn(domain, msg, fn = None): + std_warn(msg) + +def error(domain, msg, fn = None): + std_error(msg) + +def fatal(domain, msg, fn = None): + std_fatal(msg) + +# +# Compatibility functions for the original message interface +# +def std_debug(lvl, msg): + if debug_level >= lvl: + print 'DEBUG: ' + msg + +def std_note(msg): + print 'NOTE: ' + msg + +def std_warn(msg): + print 'WARNING: ' + msg + +def std_error(msg): + print 'ERROR: ' + msg + +def std_fatal(msg): + print 'ERROR: ' + msg + sys.exit(1) + diff --git a/lib/bb/providers.py b/lib/bb/providers.py index 10190b186..b97b3ee9d 100644 --- a/lib/bb/providers.py +++ b/lib/bb/providers.py @@ -76,9 +76,9 @@ def findBestProvider(pn, cfgData, dataCache, pkg_pn = None): else: pv_str = preferred_v if preferred_file is None: - bb.note("preferred version %s of %s not available" % (pv_str, pn)) + bb.msg.note(1, bb.msg.domain.Provider, "preferred version %s of %s not available" % (pv_str, pn)) else: - bb.debug(1, "selecting %s as PREFERRED_VERSION %s of package %s" % (preferred_file, pv_str, pn)) + bb.msg.debug(1, bb.msg.domain.Provider, "selecting %s as PREFERRED_VERSION %s of package %s" % (preferred_file, pv_str, pn)) del localdata @@ -101,7 +101,7 @@ def findBestProvider(pn, cfgData, dataCache, pkg_pn = None): return (latest,latest_f,preferred_ver, preferred_file) -def filterProviders(providers, item, cfgData, dataCache, build_cache_fail, verbose): +def filterProviders(providers, item, cfgData, dataCache, build_cache_fail): """ Take a list of providers and filter/reorder according to the environment variables and previous build results @@ -117,7 +117,7 @@ def filterProviders(providers, item, cfgData, dataCache, build_cache_fail, verbo pkg_pn[pn] = [] pkg_pn[pn].append(p) - bb.debug(1, "providers for %s are: %s" % (item, pkg_pn.keys())) + bb.msg.debug(1, bb.msg.domain.Provider, "providers for %s are: %s" % (item, pkg_pn.keys())) for pn in pkg_pn.keys(): preferred_versions[pn] = bb.providers.findBestProvider(pn, cfgData, dataCache, pkg_pn)[2:4] @@ -126,7 +126,7 @@ def filterProviders(providers, item, cfgData, dataCache, build_cache_fail, verbo for p in eligible: if p in build_cache_fail: - bb.debug(1, "rejecting already-failed %s" % p) + bb.msg.debug(1, bb.msg.domain.Provider, "rejecting already-failed %s" % p) eligible.remove(p) if len(eligible) == 0: @@ -152,8 +152,7 @@ def filterProviders(providers, item, cfgData, dataCache, build_cache_fail, verbo else: extra_chat = "Selecting already-staged %s (%s) to satisfy %s" % (pn, oldver, item) - if verbose: - bb.note("%s" % extra_chat) + bb.msg.note(2, bb.msg.domain.Provider, "%s" % extra_chat) eligible.remove(fn) eligible = [fn] + eligible discriminated = True diff --git a/lib/bb/shell.py b/lib/bb/shell.py index 5db488554..803b8f971 100644 --- a/lib/bb/shell.py +++ b/lib/bb/shell.py @@ -107,7 +107,7 @@ class BitBakeShellCommands: preferred = data.getVar( "PREFERRED_PROVIDER_%s" % item, cooker.configuration.data, 1 ) if not preferred: preferred = item try: - lv, lf, pv, pf = bb.providers.findBestProvider(preferred, cooker.configuration.data, cooker.status, cooker.build_cache_fail, cooker.configuration.verbose) + lv, lf, pv, pf = bb.providers.findBestProvider(preferred, cooker.configuration.data, cooker.status, cooker.build_cache_fail) except KeyError: if item in cooker.status.providers: pf = cooker.status.providers[item][0] @@ -537,7 +537,7 @@ SRC_URI = "" if not preferred: preferred = item try: - lv, lf, pv, pf = bb.providers.findBestProvider(preferred, cooker.configuration.data, cooker.status, cooker.build_cache_fail, cooker.configuration.verbose) + lv, lf, pv, pf = bb.providers.findBestProvider(preferred, cooker.configuration.data, cooker.status, cooker.build_cache_fail) except KeyError: lv, lf, pv, pf = (None,)*4 diff --git a/lib/bb/utils.py b/lib/bb/utils.py index 5b3cb38d8..b63c4e530 100644 --- a/lib/bb/utils.py +++ b/lib/bb/utils.py @@ -160,3 +160,43 @@ def better_exec(code, context, text, realfile): _print_trace( text.split('\n'), line ) raise + +def Enum(*names): + """ + A simple class to give Enum support + """ + + assert names, "Empty enums are not supported" + + class EnumClass(object): + __slots__ = names + def __iter__(self): return iter(constants) + def __len__(self): return len(constants) + def __getitem__(self, i): return constants[i] + def __repr__(self): return 'Enum' + str(names) + def __str__(self): return 'enum ' + str(constants) + + class EnumValue(object): + __slots__ = ('__value') + def __init__(self, value): self.__value = value + Value = property(lambda self: self.__value) + EnumType = property(lambda self: EnumType) + def __hash__(self): return hash(self.__value) + def __cmp__(self, other): + # C fans might want to remove the following assertion + # to make all enums comparable by ordinal value {;)) + assert self.EnumType is other.EnumType, "Only values from the same enum are comparable" + return cmp(self.__value, other.__value) + def __invert__(self): return constants[maximum - self.__value] + def __nonzero__(self): return bool(self.__value) + def __repr__(self): return str(names[self.__value]) + + maximum = len(names) - 1 + constants = [None] * len(names) + for i, each in enumerate(names): + val = EnumValue(i) + setattr(EnumClass, each, val) + constants[i] = val + constants = tuple(constants) + EnumType = EnumClass() + return EnumType -- cgit 1.2.3-korg