Skip to content

Commit

Permalink
add subcommand support
Browse files Browse the repository at this point in the history
  • Loading branch information
minrk committed May 20, 2011
1 parent 070ea8a commit a05908a
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 17 deletions.
87 changes: 77 additions & 10 deletions IPython/config/application.py
Expand Up @@ -28,8 +28,9 @@
) )


from IPython.utils.traitlets import ( from IPython.utils.traitlets import (
Unicode, List, Int, Enum, Dict Unicode, List, Int, Enum, Dict, Instance
) )
from IPython.utils.importstring import import_item
from IPython.utils.text import indent from IPython.utils.text import indent


#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
Expand Down Expand Up @@ -102,6 +103,14 @@ class Application(SingletonConfigurable):
# and the second being the help string for the flag # and the second being the help string for the flag
flags = Dict() flags = Dict()


# subcommands for launching other applications
# if this is not empty, this will be a parent Application
# this must be a dict of two-tuples, the first element being the application class/import string
# and the second being the help string for the subcommand
subcommands = Dict()
# parse_command_line will initialize a subapp, if requested
subapp = Instance('IPython.config.application.Application', allow_none=True)



def __init__(self, **kwargs): def __init__(self, **kwargs):
SingletonConfigurable.__init__(self, **kwargs) SingletonConfigurable.__init__(self, **kwargs)
Expand Down Expand Up @@ -134,7 +143,23 @@ def init_logging(self):
self._log_formatter = logging.Formatter("[%(name)s] %(message)s") self._log_formatter = logging.Formatter("[%(name)s] %(message)s")
self._log_handler.setFormatter(self._log_formatter) self._log_handler.setFormatter(self._log_formatter)
self.log.addHandler(self._log_handler) self.log.addHandler(self._log_handler)


def initialize(self, argv=None):
"""Do the basic steps to configure me.
Override in subclasses.
"""
self.parse_command_line(argv)


def start(self):
"""Start the app mainloop.
Override in subclasses.
"""
if self.subapp is not None:
return self.subapp.start()

def _log_level_changed(self, name, old, new): def _log_level_changed(self, name, old, new):
"""Adjust the log level when log_level is set.""" """Adjust the log level when log_level is set."""
self.log.setLevel(new) self.log.setLevel(new)
Expand All @@ -145,7 +170,7 @@ def print_alias_help(self):
return return


lines = ['Aliases'] lines = ['Aliases']
lines.append('_'*len(lines[0])) lines.append('-'*len(lines[0]))
lines.append(self.alias_description) lines.append(self.alias_description)
lines.append('') lines.append('')


Expand All @@ -161,11 +186,6 @@ def print_alias_help(self):
help = cls.class_get_trait_help(trait) help = cls.class_get_trait_help(trait)
help = help.replace(longname, "%s (%s)"%(alias, longname), 1) help = help.replace(longname, "%s (%s)"%(alias, longname), 1)
lines.append(help) lines.append(help)
# header = "%s (%s) : %s"%(alias, longname, trait.__class__.__name__)
# lines.append(header)
# help = cls.class_get_trait_help(trait)
# if help:
# lines.append(indent(help, flatten=True))
lines.append('') lines.append('')
print '\n'.join(lines) print '\n'.join(lines)


Expand All @@ -175,7 +195,7 @@ def print_flag_help(self):
return return


lines = ['Flags'] lines = ['Flags']
lines.append('_'*len(lines[0])) lines.append('-'*len(lines[0]))
lines.append(self.flag_description) lines.append(self.flag_description)
lines.append('') lines.append('')


Expand All @@ -185,6 +205,20 @@ def print_flag_help(self):
lines.append('') lines.append('')
print '\n'.join(lines) print '\n'.join(lines)


def print_subcommands(self):
"""print the subcommand part of the help"""
if not self.subcommands:
return

lines = ["Subcommands"]
lines.append('-'*len(lines[0]))
for subc, cls,help in self.subcommands:
lines.append("%s : %s"%(subc, cls))
if help:
lines.append(indent(help, flatten=True))
lines.append('')
print '\n'.join(lines)

def print_help(self, classes=False): def print_help(self, classes=False):
"""Print the help for each Configurable class in self.classes. """Print the help for each Configurable class in self.classes.
Expand Down Expand Up @@ -225,11 +259,44 @@ def update_config(self, config):
# Save the combined config as self.config, which triggers the traits # Save the combined config as self.config, which triggers the traits
# events. # events.
self.config = newconfig self.config = newconfig


def initialize_subcommand(self, subc, argv=None):
"""Initialize a subcommand with argv"""
if '-h' in subc:
# requested help
self.print_description()
self.print_subcommands()
self.exit(0)
subapp = self.subcommands.get(subc, None)
if subapp is None:
self.print_description()
print "No such subcommand: %r"%subc
print
self.print_subcommands()
self.exit(1)

if isinstance(subapp, basestring):
subapp = import_item(subapp)

# instantiate
self.subapp = subapp()
# and initialize subapp
self.subapp.initialize(argv)

def parse_command_line(self, argv=None): def parse_command_line(self, argv=None):
"""Parse the command line arguments.""" """Parse the command line arguments."""
argv = sys.argv[1:] if argv is None else argv argv = sys.argv[1:] if argv is None else argv


if self.subcommands:
# we have subcommands
if len(argv) == 0:
# none specified
self.print_description()
self.print_subcommands()
self.exit(1)

return self.initialize_subcommand(argv[0], argv[1:])

if '-h' in argv or '--help' in argv or '--help-all' in argv: if '-h' in argv or '--help' in argv or '--help-all' in argv:
self.print_description() self.print_description()
self.print_help('--help-all' in argv) self.print_help('--help-all' in argv)
Expand Down
19 changes: 12 additions & 7 deletions docs/examples/core/appconfig.py
Expand Up @@ -79,17 +79,22 @@ def init_bar(self):
# Pass config to other classes for them to inherit the config. # Pass config to other classes for them to inherit the config.
self.bar = Bar(config=self.config) self.bar = Bar(config=self.config)


def initialize(self, argv=None):
self.parse_command_line(argv)
if self.config_file:
self.load_config_file(self.config_file)
self.init_foo()
self.init_bar()

def start(self):
print "app.config:"
print self.config




def main(): def main():
app = MyApp() app = MyApp()
app.parse_command_line() app.initialize()
if app.config_file: app.start()
app.load_config_file(app.config_file)
app.init_foo()
app.init_bar()
print "app.config:"
print app.config




if __name__ == "__main__": if __name__ == "__main__":
Expand Down

0 comments on commit a05908a

Please sign in to comment.