diff options
| -rwxr-xr-x | bitbake/lib/bb/main.py | 60 |
1 files changed, 38 insertions, 22 deletions
diff --git a/bitbake/lib/bb/main.py b/bitbake/lib/bb/main.py index 910cd64444..8762f7220a 100755 --- a/bitbake/lib/bb/main.py +++ b/bitbake/lib/bb/main.py | |||
| @@ -41,10 +41,35 @@ logger = logging.getLogger("BitBake") | |||
| 41 | class BBMainException(Exception): | 41 | class BBMainException(Exception): |
| 42 | pass | 42 | pass |
| 43 | 43 | ||
| 44 | def present_options(optionlist): | ||
| 45 | if len(optionlist) > 1: | ||
| 46 | return ' or '.join([', '.join(optionlist[:-1]), optionlist[-1]]) | ||
| 47 | else: | ||
| 48 | return optionlist[0] | ||
| 49 | |||
| 50 | class BitbakeHelpFormatter(optparse.IndentedHelpFormatter): | ||
| 51 | def format_option(self, option): | ||
| 52 | # We need to do this here rather than in the text we supply to | ||
| 53 | # add_option() because we don't want to call list_extension_modules() | ||
| 54 | # on every execution (since it imports all of the modules) | ||
| 55 | # Note also that we modify option.help rather than the returned text | ||
| 56 | # - this is so that we don't have to re-format the text ourselves | ||
| 57 | if option.dest == 'ui': | ||
| 58 | valid_uis = list_extension_modules(bb.ui, 'main') | ||
| 59 | option.help = option.help.replace('@CHOICES@', present_options(valid_uis)) | ||
| 60 | elif option.dest == 'servertype': | ||
| 61 | valid_server_types = list_extension_modules(bb.server, 'BitBakeServer') | ||
| 62 | option.help = option.help.replace('@CHOICES@', present_options(valid_server_types)) | ||
| 63 | |||
| 64 | return optparse.IndentedHelpFormatter.format_option(self, option) | ||
| 65 | |||
| 44 | def list_extension_modules(pkg, checkattr): | 66 | def list_extension_modules(pkg, checkattr): |
| 45 | """ | 67 | """ |
| 46 | Lists extension modules in a specific Python package | 68 | Lists extension modules in a specific Python package |
| 47 | (e.g. UIs, servers) | 69 | (e.g. UIs, servers). NOTE: Calling this function will import all of the |
| 70 | submodules of the specified module in order to check for the specified | ||
| 71 | attribute; this can have unusual side-effects. As a result, this should | ||
| 72 | only be called when displaying help text or error messages. | ||
| 48 | Parameters: | 73 | Parameters: |
| 49 | pkg: previously imported Python package to list | 74 | pkg: previously imported Python package to list |
| 50 | checkattr: attribute to look for in module to determine if it's valid | 75 | checkattr: attribute to look for in module to determine if it's valid |
| @@ -60,7 +85,7 @@ def list_extension_modules(pkg, checkattr): | |||
| 60 | continue | 85 | continue |
| 61 | try: | 86 | try: |
| 62 | module = __import__(pkg.__name__, fromlist=[modulename]) | 87 | module = __import__(pkg.__name__, fromlist=[modulename]) |
| 63 | except (ImportError, SystemExit, RuntimeError): | 88 | except: |
| 64 | # If we can't import it, it's not valid | 89 | # If we can't import it, it's not valid |
| 65 | continue | 90 | continue |
| 66 | module_if = getattr(module, modulename) | 91 | module_if = getattr(module, modulename) |
| @@ -70,7 +95,7 @@ def list_extension_modules(pkg, checkattr): | |||
| 70 | modules.append(modulename) | 95 | modules.append(modulename) |
| 71 | return modules | 96 | return modules |
| 72 | 97 | ||
| 73 | def import_extension_module(pkg, modulename): | 98 | def import_extension_module(pkg, modulename, checkattr): |
| 74 | try: | 99 | try: |
| 75 | # Dynamically load the UI based on the ui name. Although we | 100 | # Dynamically load the UI based on the ui name. Although we |
| 76 | # suggest a fixed set this allows you to have flexibility in which | 101 | # suggest a fixed set this allows you to have flexibility in which |
| @@ -78,7 +103,7 @@ def import_extension_module(pkg, modulename): | |||
| 78 | module = __import__(pkg.__name__, fromlist = [modulename]) | 103 | module = __import__(pkg.__name__, fromlist = [modulename]) |
| 79 | return getattr(module, modulename) | 104 | return getattr(module, modulename) |
| 80 | except AttributeError: | 105 | except AttributeError: |
| 81 | raise BBMainException("FATAL: Unable to import extension module %s from %s" % (modulename, pkg.__name__)) | 106 | 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)))) |
| 82 | 107 | ||
| 83 | 108 | ||
| 84 | # Display bitbake/OE warnings via the BitBake.Warnings logger, ignoring others""" | 109 | # Display bitbake/OE warnings via the BitBake.Warnings logger, ignoring others""" |
| @@ -104,6 +129,7 @@ class BitBakeConfigParameters(cookerdata.ConfigParameters): | |||
| 104 | 129 | ||
| 105 | def parseCommandLine(self, argv=sys.argv): | 130 | def parseCommandLine(self, argv=sys.argv): |
| 106 | parser = optparse.OptionParser( | 131 | parser = optparse.OptionParser( |
| 132 | formatter = BitbakeHelpFormatter(), | ||
| 107 | version = "BitBake Build Tool Core version %s" % bb.__version__, | 133 | version = "BitBake Build Tool Core version %s" % bb.__version__, |
| 108 | usage = """%prog [options] [recipename/target recipe:do_task ...] | 134 | usage = """%prog [options] [recipename/target recipe:do_task ...] |
| 109 | 135 | ||
| @@ -168,24 +194,14 @@ class BitBakeConfigParameters(cookerdata.ConfigParameters): | |||
| 168 | parser.add_option("-P", "--profile", help = "Profile the command and save reports.", | 194 | parser.add_option("-P", "--profile", help = "Profile the command and save reports.", |
| 169 | action = "store_true", dest = "profile", default = False) | 195 | action = "store_true", dest = "profile", default = False) |
| 170 | 196 | ||
| 171 | def present_options(optionlist): | ||
| 172 | if len(optionlist) > 1: | ||
| 173 | return ' or '.join([', '.join(optionlist[:-1]), optionlist[-1]]) | ||
| 174 | else: | ||
| 175 | return optionlist[0] | ||
| 176 | |||
| 177 | env_ui = os.environ.get('BITBAKE_UI', None) | 197 | env_ui = os.environ.get('BITBAKE_UI', None) |
| 178 | valid_uis = list_extension_modules(bb.ui, 'main') | ||
| 179 | default_ui = env_ui or 'knotty' | 198 | default_ui = env_ui or 'knotty' |
| 180 | if env_ui and not env_ui in valid_uis: | 199 | # @CHOICES@ is substituted out by BitbakeHelpFormatter above |
| 181 | raise BBMainException('Invalid UI "%s" specified in BITBAKE_UI environment variable - valid choices: %s' % (env_ui, present_options(valid_uis))) | 200 | parser.add_option("-u", "--ui", help = "The user interface to use (@CHOICES@ - default %default).", |
| 182 | elif not default_ui in valid_uis: | 201 | action="store", dest="ui", default=default_ui) |
| 183 | raise BBMainException('Default UI "%s" could not be found') | 202 | |
| 184 | parser.add_option("-u", "--ui", help = "The user interface to use (%s - default %%default)." % present_options(valid_uis), | 203 | # @CHOICES@ is substituted out by BitbakeHelpFormatter above |
| 185 | action="store", dest="ui", type="choice", choices=valid_uis, default=default_ui) | 204 | parser.add_option("-t", "--servertype", help = "Choose which server type to use (@CHOICES@ - default %default).", |
| 186 | |||
| 187 | valid_server_types = list_extension_modules(bb.server, 'BitBakeServer') | ||
| 188 | parser.add_option("-t", "--servertype", help = "Choose which server type to use (%s - default %%default)." % present_options(valid_server_types), | ||
| 189 | action = "store", dest = "servertype", default = "process") | 205 | action = "store", dest = "servertype", default = "process") |
| 190 | 206 | ||
| 191 | parser.add_option("", "--token", help = "Specify the connection token to be used when connecting to a remote server.", | 207 | 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): | |||
| 315 | 331 | ||
| 316 | configuration.setConfigParameters(configParams) | 332 | configuration.setConfigParameters(configParams) |
| 317 | 333 | ||
| 318 | ui_module = import_extension_module(bb.ui, configParams.ui) | 334 | ui_module = import_extension_module(bb.ui, configParams.ui, 'main') |
| 319 | servermodule = import_extension_module(bb.server, configParams.servertype) | 335 | servermodule = import_extension_module(bb.server, configParams.servertype, 'BitBakeServer') |
| 320 | 336 | ||
| 321 | if configParams.server_only: | 337 | if configParams.server_only: |
| 322 | if configParams.servertype != "xmlrpc": | 338 | if configParams.servertype != "xmlrpc": |
