aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xlib/bb/main.py60
1 files changed, 38 insertions, 22 deletions
diff --git a/lib/bb/main.py b/lib/bb/main.py
index 910cd6444..8762f7220 100755
--- a/lib/bb/main.py
+++ b/lib/bb/main.py
@@ -41,10 +41,35 @@ logger = logging.getLogger("BitBake")
class BBMainException(Exception):
pass
+def present_options(optionlist):
+ if len(optionlist) > 1:
+ return ' or '.join([', '.join(optionlist[:-1]), optionlist[-1]])
+ else:
+ return optionlist[0]
+
+class BitbakeHelpFormatter(optparse.IndentedHelpFormatter):
+ def format_option(self, option):
+ # We need to do this here rather than in the text we supply to
+ # add_option() because we don't want to call list_extension_modules()
+ # on every execution (since it imports all of the modules)
+ # Note also that we modify option.help rather than the returned text
+ # - this is so that we don't have to re-format the text ourselves
+ if option.dest == 'ui':
+ valid_uis = list_extension_modules(bb.ui, 'main')
+ option.help = option.help.replace('@CHOICES@', present_options(valid_uis))
+ elif option.dest == 'servertype':
+ valid_server_types = list_extension_modules(bb.server, 'BitBakeServer')
+ option.help = option.help.replace('@CHOICES@', present_options(valid_server_types))
+
+ return optparse.IndentedHelpFormatter.format_option(self, option)
+
def list_extension_modules(pkg, checkattr):
"""
Lists extension modules in a specific Python package
- (e.g. UIs, servers)
+ (e.g. UIs, servers). NOTE: Calling this function will import all of the
+ submodules of the specified module in order to check for the specified
+ attribute; this can have unusual side-effects. As a result, this should
+ only be called when displaying help text or error messages.
Parameters:
pkg: previously imported Python package to list
checkattr: attribute to look for in module to determine if it's valid
@@ -60,7 +85,7 @@ def list_extension_modules(pkg, checkattr):
continue
try:
module = __import__(pkg.__name__, fromlist=[modulename])
- except (ImportError, SystemExit, RuntimeError):
+ except:
# If we can't import it, it's not valid
continue
module_if = getattr(module, modulename)
@@ -70,7 +95,7 @@ def list_extension_modules(pkg, checkattr):
modules.append(modulename)
return modules
-def import_extension_module(pkg, modulename):
+def import_extension_module(pkg, modulename, checkattr):
try:
# Dynamically load the UI based on the ui name. Although we
# suggest a fixed set this allows you to have flexibility in which
@@ -78,7 +103,7 @@ def import_extension_module(pkg, modulename):
module = __import__(pkg.__name__, fromlist = [modulename])
return getattr(module, modulename)
except AttributeError:
- raise BBMainException("FATAL: Unable to import extension module %s from %s" % (modulename, pkg.__name__))
+ raise BBMainException('FATAL: Unable to import extension module "%s" from %s. Valid extension modules: %s' % (modulename, pkg.__name__, present_options(list_extension_modules(pkg, checkattr))))
# Display bitbake/OE warnings via the BitBake.Warnings logger, ignoring others"""
@@ -104,6 +129,7 @@ class BitBakeConfigParameters(cookerdata.ConfigParameters):
def parseCommandLine(self, argv=sys.argv):
parser = optparse.OptionParser(
+ formatter = BitbakeHelpFormatter(),
version = "BitBake Build Tool Core version %s" % bb.__version__,
usage = """%prog [options] [recipename/target recipe:do_task ...]
@@ -168,24 +194,14 @@ class BitBakeConfigParameters(cookerdata.ConfigParameters):
parser.add_option("-P", "--profile", help = "Profile the command and save reports.",
action = "store_true", dest = "profile", default = False)
- def present_options(optionlist):
- if len(optionlist) > 1:
- return ' or '.join([', '.join(optionlist[:-1]), optionlist[-1]])
- else:
- return optionlist[0]
-
env_ui = os.environ.get('BITBAKE_UI', None)
- valid_uis = list_extension_modules(bb.ui, 'main')
default_ui = env_ui or 'knotty'
- if env_ui and not env_ui in valid_uis:
- raise BBMainException('Invalid UI "%s" specified in BITBAKE_UI environment variable - valid choices: %s' % (env_ui, present_options(valid_uis)))
- elif not default_ui in valid_uis:
- raise BBMainException('Default UI "%s" could not be found')
- parser.add_option("-u", "--ui", help = "The user interface to use (%s - default %%default)." % present_options(valid_uis),
- action="store", dest="ui", type="choice", choices=valid_uis, default=default_ui)
-
- valid_server_types = list_extension_modules(bb.server, 'BitBakeServer')
- parser.add_option("-t", "--servertype", help = "Choose which server type to use (%s - default %%default)." % present_options(valid_server_types),
+ # @CHOICES@ is substituted out by BitbakeHelpFormatter above
+ parser.add_option("-u", "--ui", help = "The user interface to use (@CHOICES@ - default %default).",
+ action="store", dest="ui", default=default_ui)
+
+ # @CHOICES@ is substituted out by BitbakeHelpFormatter above
+ parser.add_option("-t", "--servertype", help = "Choose which server type to use (@CHOICES@ - default %default).",
action = "store", dest = "servertype", default = "process")
parser.add_option("", "--token", help = "Specify the connection token to be used when connecting to a remote server.",
@@ -315,8 +331,8 @@ def bitbake_main(configParams, configuration):
configuration.setConfigParameters(configParams)
- ui_module = import_extension_module(bb.ui, configParams.ui)
- servermodule = import_extension_module(bb.server, configParams.servertype)
+ ui_module = import_extension_module(bb.ui, configParams.ui, 'main')
+ servermodule = import_extension_module(bb.server, configParams.servertype, 'BitBakeServer')
if configParams.server_only:
if configParams.servertype != "xmlrpc":