summaryrefslogtreecommitdiff
path: root/optparser.py
diff options
context:
space:
mode:
authorNicolas Chauvat <nicolas.chauvat@logilab.fr>2006-08-05 18:14:02 +0200
committerNicolas Chauvat <nicolas.chauvat@logilab.fr>2006-08-05 18:14:02 +0200
commit3d7cf5240258c1d3ae126d6d19a20a1f07bca2c6 (patch)
treef3d8b098ab8a917f97a0db384d152d081380540f /optparser.py
parentc74c15e6eb1240ed5622b43bc05adf0b6be649cd (diff)
downloadlogilab-common-3d7cf5240258c1d3ae126d6d19a20a1f07bca2c6.tar.gz
added a OptionParser that extends optparse's with commands
Diffstat (limited to 'optparser.py')
-rw-r--r--optparser.py81
1 files changed, 81 insertions, 0 deletions
diff --git a/optparser.py b/optparser.py
new file mode 100644
index 0000000..7184993
--- /dev/null
+++ b/optparser.py
@@ -0,0 +1,81 @@
+# -*- encoding: iso-8859-15 -*-
+# Copyright (c) 2003-2004 LOGILAB S.A. (Paris, FRANCE).
+# http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# 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.
+"""Extend OptionParser with commands.
+
+Example:
+
+>>> parser = OptionParser()
+>>> parser.usage = '%prog COMMAND [options] <arg> ...'
+>>> parser.add_command('build', 'mymod.build')
+>>> parser.add_command('clean', run_clean, add_opt_clean)
+>>> run, options, args = parser.parse_command(sys.argv[1:])
+>>> return run(options, args[1:])
+
+With mymod.build that defines two functions run and add_options
+"""
+
+# XXX merge with optik_ext ?
+
+import optparse
+
+class OptionParser(optparse.OptionParser):
+
+ def __init__(self, *args, **kwargs):
+ optparse.OptionParser.__init__(self, *args, **kwargs)
+ self._commands = {}
+ self.min_args, self.max_args = 0, 1
+
+ def add_command(self, name, mod_or_funcs, help=''):
+ """name of the command
+ name of module or tuple of functions (run, add_options)
+ """
+ assert isinstance(mod_or_funcs, str) or isinstance(mod_or_funcs, tuple), \
+ "mod_or_funcs has to be a module name or a tuple of functions"
+ self._commands[name] = (mod_or_funcs, help)
+
+ def print_main_help(self):
+ optparse.OptionParser.print_help(self)
+ print '\ncommands:'
+ for cmdname, (_, help) in self._commands.items():
+ print '% 10s - %s' % (cmdname, help)
+
+ def parse_command(self, args):
+ if len(args) == 0:
+ self.print_main_help()
+ sys.exit(1)
+ cmd = args[0]
+ args = args[1:]
+ if cmd not in self._commands:
+ if cmd in ('-h', '--help'):
+ self.print_main_help()
+ sys.exit(0)
+ self.error('unknow command')
+ self.prog = '%s %s' % (self.prog, cmd)
+ mod_or_f, help = self._commands[cmd]
+ # optparse inserts self.description between usage and options help
+ self.description = help
+ if isinstance(mod_or_f, str):
+ exec('from %s import run, add_options'%module)
+ else:
+ run, add_options = mod_or_f
+ add_options(self)
+ (options, args) = self.parse_args(args)
+ if not (self.min_args <= len(args) <= self.max_args):
+ self.error('incorrect number of arguments')
+ return run, options, args
+
+