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": |