summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSylvain <syt@logilab.fr>2006-08-24 17:36:46 +0200
committerSylvain <syt@logilab.fr>2006-08-24 17:36:46 +0200
commite34641bbb4a58335fd294f5e36adfad09f240388 (patch)
tree816e9b529ba51a86545777f3dc886da2cddd4dc8
parent4d59831d47ba0298059feb1a84d6b07fdceefaba (diff)
downloadlogilab-common-e34641bbb4a58335fd294f5e36adfad09f240388.tar.gz
command line commands fetched from erudi
-rw-r--r--clcommands.py120
1 files changed, 120 insertions, 0 deletions
diff --git a/clcommands.py b/clcommands.py
new file mode 100644
index 0000000..c30e0a6
--- /dev/null
+++ b/clcommands.py
@@ -0,0 +1,120 @@
+# Copyright (c) 2004-2006 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.
+"""provides helper functions to handle a command line tool providing more than
+one command
+e.g called as "tool command [options] args..." where <options> and <args> are
+command'specific
+"""
+
+import sys
+from os.path import basename
+
+from logilab.common.configuration import Configuration
+
+
+DEFAULT_COPYRIGHT = '''\
+Copyright (c) 2004-2006 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+http://www.logilab.fr/ -- mailto:contact@logilab.fr'''
+
+
+class BadCommandUsage(Exception):
+ """Raised when an unknown command is used or when a command is not
+ correctly used
+ """
+
+
+class Command(Configuration):
+ """base class for command line commands"""
+ arguments = ''
+ name = ''
+
+ def __init__(self, __doc__=None, version=None):
+ if __doc__:
+ usage = __doc__ % (self.name, self.arguments,
+ self.__doc__.replace(' ', ''))
+ else:
+ usage = self.__doc__.replace(' ', '')
+ Configuration.__init__(self, usage=usage, version=version)
+
+ def run(self, args):
+ """run the command with its specific arguments"""
+ raise NotImplementedError()
+
+
+def pop_arg(args_list, expected_size_after=0, msg="Missing argument"):
+ """helper function to get and check command line arguments"""
+ try:
+ value = args_list.pop(0)
+ except IndexError:
+ raise BadCommandUsage(msg)
+ if len(args_list) > expected_size_after:
+ raise BadCommandUsage('Too much arguments')
+ return value
+
+
+_COMMANDS = {}
+
+def register_commands(commands):
+ """register existing commands"""
+ for command_klass in commands:
+ _COMMANDS[command_klass.name] = command_klass
+
+
+def main_usage(status=0, __doc__=None, copyright=DEFAULT_COPYRIGHT):
+ """display usage for the main program (ie when no command supplied)
+ and exit
+ """
+ commands = _COMMANDS.keys()
+ commands.sort()
+ doc = __doc__ % ('<command>', '<command arguments>',
+ '''\
+Type "%%prog <command> --help" for more information about a specific
+command. Available commands are :\n * %s.
+''' % '\n * '.join(commands))
+ doc = doc.replace('%prog', basename(sys.argv[0]))
+ print 'usage:', doc
+ print copyright
+ sys.exit(status)
+
+
+def cmd_run(cmdname, *args):
+ try:
+ command = _COMMANDS[cmdname](__doc__='%%prog %s %s\n\n%s')
+ except KeyError:
+ raise BadCommandUsage('no %s command' % cmdname)
+ args = command.load_command_line_configuration(args)
+ try:
+ command.run(args)
+ except KeyboardInterrupt:
+ print 'interrupted'
+ except BadCommandUsage, err:
+ print 'ERROR: ', err
+ print command.help()
+
+
+def main_run(args, doc):
+ """command line tool"""
+ try:
+ arg = args.pop(0)
+ except IndexError:
+ main_usage(status=1, __doc__=doc)
+ if arg in ('-h', '--help'):
+ main_usage(__doc__=doc)
+ try:
+ cmd_run(arg, *args)
+ except BadCommandUsage, err:
+ print 'ERROR: ', err
+ main_usage(1, doc)