[Zope3-checkins] CVS: Zope3/src/zope/fssync - command.py:1.1
main.py:1.28
Fred L. Drake, Jr.
fred at zope.com
Mon Aug 11 17:55:57 EDT 2003
Update of /cvs-repository/Zope3/src/zope/fssync
In directory cvs.zope.org:/tmp/cvs-serv27084
Modified Files:
main.py
Added Files:
command.py
Log Message:
Refactor the command-line handling from the command implementation.
This facilitates implementing a new bundle management tool that uses a similar command
structure but all-different commands.
=== Added File Zope3/src/zope/fssync/command.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Table-based program command dispatcher.
This dispatcher supports a 'named command' dispatch similar to that
found in the standard CVS and Subversion client applications.
$Id: command.py,v 1.1 2003/08/11 20:55:21 fdrake Exp $
"""
import getopt
import os.path
import sys
from zope.fssync.fsutil import Error
class Usage(Error):
"""Subclass for usage error (command-line syntax).
You should return an exit status of 2 rather than 1 when catching this.
"""
class Command:
def __init__(self, name=None, usage=None):
if name is None:
name = os.path.basename(sys.argv[0])
self.program = name
if usage is None:
import __main__
usage = __main__.__doc__
self.helptext = usage
self.command_table = {}
self.global_options = []
self.local_options = []
self.command = None
def addCommand(self, name, function, short="", long="", aliases=""):
names = [name] + aliases.split()
cmdinfo = short, long.split(), function
for n in names:
assert n not in self.command_table
self.command_table[n] = cmdinfo
def realize(self, args=None):
if args is None:
args = sys.argv[1:]
self.global_options, args = self.getopt("global",
args, "h", ["help"],
self.helptext)
if not args:
raise Usage("missing command argument")
self.command = args.pop(0)
if self.command not in self.command_table:
raise Usage("unrecognized command")
cmdinfo = self.command_table[self.command]
short, long, func = cmdinfo
short = "h" + short
long = ["help"] + list(long)
self.local_options, self.args = self.getopt(self.command,
args, short, long,
func.__doc__)
def getopt(self, cmd, args, short, long, helptext):
try:
opts, args = getopt.getopt(args, short, long)
except getopt.error, e:
raise Usage("%s option error: %s", cmd, e)
for opt, arg in opts:
if opt in ("-h", "--help"):
self.usage(sys.stdout, helptext)
sys.exit()
return opts, args
def run(self):
_, _, func = self.command_table[self.command]
func(self.local_options, self.args)
def usage(self, file, text):
print >>file, text % {"program": self.program}
=== Zope3/src/zope/fssync/main.py 1.27 => 1.28 ===
--- Zope3/src/zope/fssync/main.py:1.27 Fri Aug 8 17:45:39 2003
+++ Zope3/src/zope/fssync/main.py Mon Aug 11 16:55:21 2003
@@ -53,73 +53,26 @@
srcdir = join(rootdir, "src")
sys.path.append(srcdir)
+from zope.fssync.command import Command, Usage
from zope.fssync.fsutil import Error
from zope.fssync.fssync import FSSync
-class Usage(Error):
- """Subclass for usage error (command-line syntax).
- You should return an exit status of 2 rather than 1 when catching this.
- """
-
-def main(argv=None):
+def main():
"""Main program.
- You can pass it an argument list (which must include the command
- name as argv[0]); it defaults to sys.argv.
-
The return value is the suggested sys.exit() status code:
0 or None for success
2 for command line syntax errors
1 or other for later errors
"""
- try:
- if argv is None:
- argv = sys.argv
+ cmd = Command()
+ for func, aliases, short, long in command_table:
+ cmd.addCommand(func.__name__, func, short, long, aliases)
- progname = os.path.basename(argv[0])
-
- try:
- opts, args = getopt.getopt(argv[1:], "h", ["help"])
- except getopt.error, msg:
- raise Usage("global option error: %s", msg)
-
- for o, a in opts:
- if o in ("-h", "--help"):
- print __doc__ % {"program": progname}
- return 0
-
- if not args:
- raise Usage("missing command argument")
-
- command = args[0]
- if command not in command_table:
- hits = []
- for c in command_table:
- if c.startswith(command):
- hits.append(c)
- if not hits:
- raise Usage("unrecognized command", command)
- if len(hits) > 1:
- raise Usage("ambiguous command abbreviation %r (%s)",
- command, "|".join(hits))
- command = hits[0]
-
- short_opts, long_opts, handler = command_table[command]
-
- try:
- opts, args = getopt.getopt(args[1:],
- "h"+short_opts,
- ["help"] + long_opts)
- except getopt.error, msg:
- raise Usage("%s option error: %s", command, msg)
-
- if ("-h", "") in opts or ("--help", "") in opts:
- message = handler.__doc__ or "No help for %s" % handler.__name__
- print message % {"program": progname}
- return 0
-
- return handler(opts, args)
+ try:
+ cmd.realize()
+ cmd.run()
except Usage, msg:
print >>sys.stderr, msg
@@ -356,22 +309,20 @@
raise Usage(cmd + " requires at most one of -F/--file or -m/--message")
return message, L
-command_table = {
- "checkout": ("", [], checkout),
- "co": ("", [], checkout),
- "update": ("", [], update),
- "commit": ("F:m:r", ["file=", "message=", "raise-on-conflicts"], commit),
- "add": ("f:t:", ["factory=", "type="], add),
- "remove": ("", [], remove),
- "rm": ("", [], remove),
- "r": ("", [], remove),
- "diff": ("bBcC:iNuU:", ["brief", "context=", "unified="], diff),
- "status": ("", [], status),
- "checkin": ("F:m:", ["file=", "message="], checkin),
- "ci": ("F:m:", ["file=", "message="], checkin),
- "revert": ("", [], revert),
- "mkdir": ("", [], mkdir),
- }
+command_table = [
+ # name is taken from the function name
+ # function, aliases, short opts, long opts
+ (add, "", "f:t:", "factory= type="),
+ (checkin, "", "F:m:", "file= message="),
+ (checkout, "co", "", ""),
+ (commit, "ci", "F:m:r", "file= message= raise-on-conflicts"),
+ (diff, "di", "bBcC:iNuU:", "brief context= unified="),
+ (mkdir, "", "", ""),
+ (remove, "del delete rm", "", ""),
+ (revert, "", "", ""),
+ (status, "stat st", "", ""),
+ (update, "up", "", ""),
+ ]
if __name__ == "__main__":
- sys.exit(main(sys.argv))
+ sys.exit(main())
More information about the Zope3-Checkins
mailing list