[Cvsshell-devel] CVS: cvsshell/src app.py,1.6,1.7 basic_cmds.py,1.13,1.14 configurable_app.py,1.5,1.
Status: Beta
Brought to you by:
stefanheimann
|
From: Stefan H. <ste...@us...> - 2002-03-10 23:14:02
|
Update of /cvsroot/cvsshell/cvsshell/src
In directory usw-pr-cvs1:/tmp/cvs-serv25500/src
Modified Files:
app.py basic_cmds.py configurable_app.py cvs_shell.py
interactive_app.py oo_tools.py plugable_app.py utils.py
Log Message:
* refactoring
* many small improvements
Index: app.py
===================================================================
RCS file: /cvsroot/cvsshell/cvsshell/src/app.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** app.py 8 Mar 2002 22:44:33 -0000 1.6
--- app.py 10 Mar 2002 23:13:59 -0000 1.7
***************
*** 21,70 ****
import sys, os, traceback, getopt
! AppError = 'AppError'
_thisdir = os.path.join(os.getcwd(), sys.path[0])
! class App:
def __init__(self):
# the directory this file is placed in
self.THIS_DIR = _thisdir
self.HOME = os.environ['HOME']
- self.CONTEXT = {'APP':self}
self.name = self.__class__.__name__
self.version = '0.1'
self.copyright = None
self.bugAddress = None
! self.args = sys.argv[1:]
! self.env = os.environ
! self.opts = None
! self.input = sys.stdin
! self.output = sys.stdout
! self.error = sys.stderr
! self.opt_to_doc = {} # opt_name -> doc
!
! def setName(self,name):
! self.name = name
!
! def setVersion(self,version):
! self.version = version
!
! def setCopyright(self, copyright):
! self.copyright = copyright
- def setBugAddress(self, address):
- self.bugAddress = address
-
- def closeApp(self):
- try:
- if self.input is not sys.stdin: self.input.close()
- except: pass
- try:
- if self.output is not sys.stdout: self.output.close()
- except: pass
- try:
- if self.error is not sys.stderr: self.error.close()
- except: pass
def help(self):
"""Print the help message."""
--- 21,60 ----
import sys, os, traceback, getopt
! from oo_tools import GetSetProvider
!
_thisdir = os.path.join(os.getcwd(), sys.path[0])
+ AppError = 'AppError'
!
! class App(GetSetProvider):
def __init__(self):
# the directory this file is placed in
+ GetSetProvider.__init__(self)
self.THIS_DIR = _thisdir
self.HOME = os.environ['HOME']
self.name = self.__class__.__name__
self.version = '0.1'
self.copyright = None
self.bugAddress = None
! self._args = sys.argv[1:]
! self._env = os.environ
! self._opts = None
+ def closeApp(self):
+ for x, y in [(sys.stdin, sys.__stdin__),
+ (sys.stdout, sys.__stdout__),
+ (sys.stderr, sys.__stderr__)]:
+ try:
+ if x is not y:
+ x.close()
+ except: pass
+ sys.stdin = sys.__stdin__
+ sys.stdout = sys.__stdout__
+ sys.stderr = sys.__stderr__
+
+
def help(self):
"""Print the help message."""
***************
*** 72,82 ****
print
max = 0
! for x in self.docs:
l = len(x[0])
if l > max: max = l
! for x in self.docs:
spaces = (max - len(x[0])) * ' '
print " %s%s %s" % (x[0],spaces,x[1])
print
def initOptions(self, opts=[]):
--- 62,73 ----
print
max = 0
! for x in self._docs:
l = len(x[0])
if l > max: max = l
! for x in self._docs:
spaces = (max - len(x[0])) * ' '
print " %s%s %s" % (x[0],spaces,x[1])
print
+
def initOptions(self, opts=[]):
***************
*** 91,95 ****
"""
str = ''
! self.docs = []
for x in opts:
name = x[0]
--- 82,86 ----
"""
str = ''
! self._docs = []
for x in opts:
name = x[0]
***************
*** 98,107 ****
name = '-' + name
if name[-1] == ':': name = name[:-1] + " <arg>"
! self.docs.append((name,doc))
try:
! self.opts = getopt.getopt(self.args,str)
except getopt.GetoptError, msg:
self.printErr("%s: %s" % (self.name, msg))
self.exit()
##############################
--- 89,99 ----
name = '-' + name
if name[-1] == ':': name = name[:-1] + " <arg>"
! self._docs.append((name,doc))
try:
! self._opts = getopt.getopt(self._args,str)
except getopt.GetoptError, msg:
self.printErr("%s: %s" % (self.name, msg))
self.exit()
+
##############################
***************
*** 111,117 ****
def getopt(self, tag):
"""test '-x' command arg"""
! if self.opts == None:
raise AppError, "You have to call init_options before using getopt!"
! for x in self.opts[0]:
if x[0] == tag: return 1
return 0
--- 103,109 ----
def getopt(self, tag):
"""test '-x' command arg"""
! if self._opts == None:
raise AppError, "You have to call init_options before using getopt!"
! for x in self._opts[0]:
if x[0] == tag: return 1
return 0
***************
*** 119,125 ****
def getarg(self, tag, default=None):
"""get '-x val' command arg"""
! if self.opts == None:
raise AppError, "You have to call init_options before using getarg!"
! for x in self.opts[0]:
if x[0] == tag: return x[1]
return default
--- 111,117 ----
def getarg(self, tag, default=None):
"""get '-x val' command arg"""
! if self._opts == None:
raise AppError, "You have to call init_options before using getarg!"
! for x in self._opts[0]:
if x[0] == tag: return x[1]
return default
***************
*** 127,138 ****
def restargs(self):
"""get the rest of the commandline arguments (after all options)"""
! if self.opts == None:
raise AppError, "You have to call init_options before using restargs!"
! return self.opts[1]
def getenv(self, name, default=''):
"""get '$x' environment var"""
try:
! return self.env[name]
except KeyError:
return default
--- 119,130 ----
def restargs(self):
"""get the rest of the commandline arguments (after all options)"""
! if self._opts == None:
raise AppError, "You have to call init_options before using restargs!"
! return self._opts[1]
def getenv(self, name, default=''):
"""get '$x' environment var"""
try:
! return self._env[name]
except KeyError:
return default
***************
*** 140,144 ****
def setenv(self, name, value): # convenient method
"""set '$x' environment var"""
! self.env[name] = value
def isVerbose(self):
--- 132,144 ----
def setenv(self, name, value): # convenient method
"""set '$x' environment var"""
! self._env[name] = value
!
! def cd(self, dir):
! """Changes the current working directory. Returns the old directory."""
! if not dir: return
! oldDir = os.getcwd()
! self.printVMsg('cd ' + dir)
! os.chdir(dir)
! return oldDir
def isVerbose(self):
***************
*** 152,161 ****
def printMsg(self, text='', nonl=0):
! self.output.write(str(text))
! if not nonl: self.output.write('\n')
def printErr(self, text='', nonl=0):
! self.error.write(str(text))
! if not nonl: self.error.write('\n')
def exit(self, message='', status=1):
--- 152,161 ----
def printMsg(self, text='', nonl=0):
! sys.stdout.write(str(text))
! if not nonl: sys.stdout.write('\n')
def printErr(self, text='', nonl=0):
! sys.stderr.write(str(text))
! if not nonl: sys.stderr.write('\n')
def exit(self, message='', status=1):
***************
*** 175,196 ****
pipe.write(inp) # send it input
pipe.close()
!
! #################################################
! # input/output-stream methods for the app itself;
! # redefine in subclasses if not using files, or
! # set self.input/output to file-like objects;
! #################################################
!
! def read(self, *size):
! return apply(self.input.read, size)
! def readline(self):
! return self.input.readline()
! def readlines(self):
! return self.input.readlines()
! def write(self, text):
! self.output.write(text)
! def writelines(self, text):
! self.output.writelines(text)
!
def main(self):
--- 175,179 ----
pipe.write(inp) # send it input
pipe.close()
! return None
def main(self):
Index: basic_cmds.py
===================================================================
RCS file: /cvsroot/cvsshell/cvsshell/src/basic_cmds.py,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -d -r1.13 -r1.14
*** basic_cmds.py 9 Mar 2002 10:56:20 -0000 1.13
--- basic_cmds.py 10 Mar 2002 23:13:59 -0000 1.14
***************
*** 20,35 ****
###############################################################################
! import os, string, re, getopt
! import utils
! from app import AppError
!
! ##############################
! # Errors and error messages
! ##############################
!
! noListingErrMsg = "No listing found. \nYou must run `update', `refresh' " \
! "or `status' before using this command."
! CvsError = 'CvsError'
! InternalCvsError = 'InternalCvsError'
######################################
--- 20,24 ----
###############################################################################
! import os, string, re
######################################
***************
*** 37,45 ****
#####################################
! def cmdHelp(name, opts, context):
"""Prints this help message.
If the name of a command is given as a option,
a detailed help for this command is printed."""
- app = context['APP']
so = string.split(opts)
if len(so) > 0:
--- 26,33 ----
#####################################
! def cmdHelp(app, name, opts):
"""Prints this help message.
If the name of a command is given as a option,
a detailed help for this command is printed."""
so = string.split(opts)
if len(so) > 0:
***************
*** 72,84 ****
! def exitProgram(name, opts, context):
"Terminates the program."
- app = context['APP']
return app.BREAK_REPL
! def changeDir(name, opts, context):
"Changes the current working directory."
- app = context['APP']
if len(opts) == 0:
opts = app.HOME
--- 60,70 ----
! def exitProgram(app, name, opts):
"Terminates the program."
return app.BREAK_REPL
! def changeDir(app, name, opts):
"Changes the current working directory."
if len(opts) == 0:
opts = app.HOME
***************
*** 86,90 ****
os.path.expanduser(opts)
try:
! _cd(app,opts)
except OSError, msg:
app.printErr(msg)
--- 72,76 ----
os.path.expanduser(opts)
try:
! app.cd(opts)
except OSError, msg:
app.printErr(msg)
***************
*** 93,627 ****
if root: app.setCvsRoot(root)
-
- ##############################
- # CVS commands
- ##############################
-
- def status(name, args, context):
- app = context['APP']
- entries = []
- regexHead = re.compile(r'File: (?P<name>\S+)\s+Status: (?P<status>.+)')
- regexDir = re.compile(r'.*Examining (?P<dir>\S+)')
- regexUnknown = re.compile(r'^\?\s+(?P<filename>\S+)')
- try:
- (globOpts, opts,
- myOpts, rest) = _parseArgs(args,
- app.cmdToOpts.get(name, ''))
- except getopt.GetoptError, msg:
- app.printErr(msg)
- return
- try:
- lines = _runCvsCmd(context, 'status', globOpts=globOpts,
- args=opts, getStderr=1)
- except CvsError: return
- entries = []
- dir = None
- for line in lines:
- unknownRes = regexUnknown.search(line)
- if unknownRes:
- name = os.path.basename(unknownRes.group('filename'))
- dir = os.path.dirname(unknownRes.group('filename'))
- entries.append(utils.Entry(dir, name, utils.Entry.S_UNKNOWN))
- continue
- headRes = regexHead.search(line)
- if headRes and dir is None:
- raise InternalCvsError, "Parsing of status message failed: " \
- "`dir' is not set when get file information."
- elif headRes:
- name = headRes.group('name')
- status = headRes.group('status').strip()
- entries.append(utils.Entry(dir, name, status))
- continue
- dirRes = regexDir.search(line)
- if dirRes:
- dir = dirRes.group('dir')
- if dir == '.': dir = ''
- l = context['basic_cmds.listing'] = utils.Listing(app, os.getcwd(),
- entries)
- context['basic_cmds.dirty_listing'] = 0
- l.sortEntries()
- _printListing(context)
-
- def update(name, args, context, simulate=0):
- app = context['APP']
- try:
- (globOpts, opts,
- myOpts, rest) = _parseArgs(args,
- app.cmdToOpts.get(name, ''))
- except getopt.GetoptError, msg:
- app.printErr(msg)
- return
- if simulate: globOpts += '-n'
- try:
- lines = _runCvsCmd(context, 'update', globOpts=globOpts, args=opts)
- except CvsError: return
- entries = []
- for line in lines:
- x = line.split()
- status = x[0]
- name = os.path.basename(x[1])
- dir = os.path.dirname(x[1])
- entries.append(utils.Entry(dir, name, status))
- l = context['basic_cmds.listing'] = utils.Listing(app, os.getcwd(),
- entries)
- context['basic_cmds.dirty_listing'] = 0
- l.sortEntries()
- _printListing(context)
-
- def simulateUpdate(name, args, context):
- update(name, args, context, simulate=1)
-
- def checkout(name, args, context):
- app = context['APP']
- try:
- (globOpts, opts,
- myOpts, rest) = _parseArgs(args,
- app.cmdToOpts.get(name, ''))
- except getopt.GetoptError, msg:
- app.printErr(msg)
- return
- rest = rest.split()
- if app.getCvsRoot() is None:
- setCvsRoot('','',context) # FIXME do we really need the name arg?
- if len(rest) < 1:
- module = app.prompt('enter name of module: ')
- if module is None: return
- else:
- module = args[0]
- try:
- _runCvsCmd(context, 'checkout', globOpts=globOpts,
- args=opts+' '+module)
- except CvsError: pass
-
-
- def add(name, args, context, isBinary=0):
- app = context['APP']
- try:
- (globOpts, opts,
- myOpts, rest) = _parseArgs(args,
- app.cmdToOpts.get(name, ''))
- except getopt.GetoptError, msg:
- app.printErr(msg)
- return
- if not rest:
- rest = app.prompt('enter filenumbers/filenames to add: ')
- if rest is None: return
- def __doIt(e,filename):
- e.status = utils.Entry.S_ADDED
- return filename
- (rootDir, filenames) = _applyOnEntryList(rest, context, __doIt)
- if isBinary: opts += '-kb'
- if filenames:
- try:
- _runCvsCmd(context, 'add', rootDir=rootDir, globOpts=globOpts,
- args=opts+' '+utils.list2string(filenames))
- except CvsError: pass
- else: # args do not spefiy ids in the current listing
- try:
- _runCvsCmd(context, 'add', globOpts=globOpts,
- args=opts+' '+rest)
- context['basic_cmds.dirty_listing'] = 0
- except CvsError: pass
-
-
- def addBinary(name, args, context):
- context['APP'].printMsg('The file will be added in binary mode.')
- add(name, args, context, isBinary=1)
-
-
- def commit(name, args, context):
- app = context['APP']
- try:
- (globOpts, opts,
- myOpts, rest) = _parseArgs(args,
- app.cmdToOpts.get(name, ''))
- except getopt.GetoptError, msg:
- app.printErr(msg)
- return
- if not rest: # commit without an argument
- try:
- try:
- listing = context['basic_cmds.listing']
- rootDir = listing.rootDir
- except KeyError:
- rootDir = ''
- _runCvsCmd(context, 'commit', rootDir=rootDir,
- globOpts=globOpts, args=opts, fork=1)
- context['basic_cmds.dirty_listing'] = 1
- except CvsError: pass
- return
- def __doIt(e,filename):
- if e.status == utils.Entry.S_REMOVED:
- e.status = utils.Entry.S_DELETED
- else:
- e.status = utils.Entry.S_OK
- return filename
- (rootDir, filenames) = _applyOnEntryList(rest, context, __doIt)
- if filenames:
- try:
- _runCvsCmd(context, 'commit', rootDir=rootDir, globOpts=globOpts,
- args=opts+' '+utils.list2string(filenames), fork=1)
- except CvsError: pass
- else: # args do not spefiy ids in the current listing
- try:
- _runCvsCmd(context, 'commit', globOpts=globOpts,
- args=opts+' '+rest, fork=1)
- context['basic_cmds.dirty_listing'] = 0
- except CvsError: pass
-
-
- def remove(name, args, context):
- app = context['APP']
- try:
- (globOpts, opts,
- myOpts, rest) = _parseArgs(args,
- app.cmdToOpts.get(name, ''))
- except getopt.GetoptError, msg:
- app.printErr(msg)
- return
- if not rest:
- rest = app.prompt('enter filenumber(s) to remove: ')
- if rest is None: return
- def __doIt(e,filename):
- return e
- (rootDir, toDelete) = _applyOnEntryList(rest, context, __doIt)
- toDeleteList = utils.Listing(app, rootDir, toDelete)
- filenames = []
- if toDelete:
- for e in toDeleteList.entries:
- name = os.path.join(toDeleteList.rootDir, e.dir, e.name)
- try:
- os.unlink(name)
- except OSError, msg:
- app.printErr(msg)
- # Hope that the file already has been removed
- filenames.append(os.path.join(e.dir, e.name))
- e.status = utils.Entry.S_REMOVED
- else: # args do not specify ids in the current listing
- fs = utils.splitquoted(rest)
- for name in fs:
- try:
- os.unlink(name)
- except OSError, msg:
- app.printErr(msg)
- # Hope that the file already has been removed
- filenames.append(name)
- if filenames:
- args = utils.list2string(filenames)
- try:
- _runCvsCmd(context, 'remove', rootDir=rootDir,
- globOpts=globOpts, args=opts+' '+args)
- except CvsError: return
- toDeleteList.printEntries(app.output)
- answ = app.prompt("\nThe files have been scheduled for removal.\n" \
- "Should I run `commit' to remove the files " \
- "permanently (yes|no)? ")
- if answ == 'yes':
- for e in toDeleteList.entries:
- e.status = utils.Entry.S_DELETED
- _runCvsCmd(context, 'commit', rootDir=rootDir, fork=1, args=args)
-
- def printListing(name, args, context):
- _printListing(context)
-
- def setCvsRoot(name, args, context):
- "Sets the cvsroot variable manually."
- app = context['APP']
- roots = context['basic_cmds.CVSROOTS']
- if len(args) != 0:
- newRoot = args.split()[0]
- else:
- if roots == None:
- app.printMsg("No aliases specified.")
- else:
- app.printMsg("Aliases:")
- for x in roots.items():
- print " %s => %s" % (x[0], x[1])
- newRoot = app.prompt('enter new cvsroot: ')
- if roots != None and roots.has_key(newRoot):
- newRoot = roots[newRoot]
- if not roots.has_key(newRoot):
- a = app.prompt("You can specify an alias for the cvsroot: ")
- if a:
- context.get('basic_cmds.CVSROOTS', {})[a] = newRoot
- app.appendToSection('CVSROOT', ['%s = %s' % (a, newRoot)])
- if newRoot is not None:
- app.setCvsRoot(newRoot)
-
- def readCvsRoot(name, args, context):
- "Reads the cvsroot variable from ./CVS/Root."
- app = context['APP']
- newRoot = app.readCvsRootFromFile()
- if newRoot == None:
- app.printErr('Could not read CVSROOT from file.')
- else:
- app.setCvsRoot(newRoot)
-
- def clearCvsRoot(name, args, context):
- "Unsets the cvsroot variable."
- app = context['APP']
- app.setCvsRoot(None)
-
- def toggleCvsRootAutoUpdate(name, args, context):
- """Toggles the auto-update feature for the CVSROOT var.
- If this option is set, the CVSROOT variable is automatically updated when a new
- directory is entered. Without a argument the option is toggled. You can set the
- option to a new value with `on' or `off' as argument."""
- app = context['APP']
- app.cvsRootAutoUpdate = _toggle(app, app.cvsRootAutoUpdate, args)
- if app.cvsRootAutoUpdate:
- newRoot = app.readCvsRootFromFile()
- if newRoot is not None: app.setCvsRoot(newRoot)
-
- def toggleFullPrompt(name, args, context):
- app = context['APP']
- app.showFullPrompt = _toggle(app, app.showFullPrompt, args)
-
-
- ###################################
- # Helper functions for CVS commands
- ###################################
-
- def _applyOnEntryList(opts, context, fun):
- """fun must take 2 argument as the entry and its
- filename is passed to it. Returns a tuple
- (rootdir of listing, list with the return values from fun).
- If an error occurs, (None, []) is returned."""
- app = context['APP']
- defRet = (None, [])
- try:
- nums = utils.getNumbers(opts)
- except utils.ParseError, msg:
- return defRet
- if len(nums) == 0:
- app.printMsg('No files specified.')
- return defRet
- try:
- listing = context['basic_cmds.listing']
- except KeyError:
- app.printErr(noListingErrMsg)
- return defRet
- result = []
- for x in nums:
- e = listing.entries[x]
- name = os.path.join(e.dir, e.name)
- result.append(fun(e,name))
- return listing.rootDir, result
-
-
- def _runCvsCmd(context, cmd, rootDir=None, globOpts = '',
- args='', fork=0, getStderr=0):
- """
- * cmd is the command to execute
- * rootDir is the directory the command should be executed in
- * globOpts are global options. These options
- override the default global options
- * args are the arguments that should be passed to the cvs command
- """
- app = context['APP']
-
- oldDir = None
- if rootDir is not None:
- try:
- oldDir = _cd(app,rootDir)
- except OSError,msg:
- app.printErr("Could not change to the root directory of the " \
- "current listing: %s" % str(msg))
- raise CvsError
-
- defGlobOpts,defOpts = _getOptions(context,cmd)
-
- cvsRoot = app.getCvsRoot()
- if cvsRoot != None: cvsRootOpt = "-d %s" % cvsRoot
- else: cvsRootOpt = ''
-
- globOpts = "%s %s %s" % (defGlobOpts, cvsRootOpt, globOpts)
- args = "%s %s" % (defOpts, args)
-
- cmd = 'cvs %s %s %s' % (globOpts, cmd, args)
- if getStderr: cmd += ' 2>&1'
- app.printVMsg(cmd)
- if not fork:
- f = os.popen(cmd)
- try:
- lines = f.readlines()
- except KeyboardInterrupt:
- return []
- if f.close() is not None: # cvs command caused an error
- raise CvsError
- else:
- return lines
- else:
- r = os.system(cmd)
- if r != 0:
- raise CvsError
-
- if oldDir is not None:
- try:
- _cd(app,oldDir)
- except OSError,msg:
- app.printErr(msg)
-
-
- def _isDirtyListing(context):
- try:
- return context['basic_cmds.dirty_listing']
- except KeyError:
- return 0
-
- def _printListing(context):
- app = context['APP']
- try:
- listing = context['basic_cmds.listing']
- except KeyError:
- app.printErr(noListingErrMsg)
- else:
- listing.printEntries()
- if _isDirtyListing(context):
- app.printMsg("Listing may be out-of-date. " \
- "Run `update', `refresh' or `status'.")
-
-
- def _parseArgs(args, cvsCmdOpts='', cmdOpts=''):
- """Parse args and separates it like that:
- cvsCmdOpts are the options that are allowed for the cvs command
- cmdOpts are additional options
- global options are handled automatically
- * global cvs options (as string)
- * command specific cvs options (as string)
- * other options (as dictionary)
- * other args (as string)
- These values are returned as a 4-tupel.
- A GetoptError is raised if there are unknown options."""
- cvsGlobOpts = 'HQqrwlntvb:T:e:d:fz:as:'
- s = cvsGlobOpts+cvsCmdOpts+cmdOpts
- (opts, rest) = getopt.getopt(utils.splitquoted(args), s)
- cvsGlobOptstr = cvsCmdOptstr = ''
- cmdOptDict = {}
- for x in opts:
- name, value = x
- if name[1] in cvsGlobOpts:
- cvsGlobOptstr += ' %s %s' % (name, value)
- elif name[1] in cvsCmdOpts:
- cvsCmdOptstr += ' %s %s' % (name, value)
- else:
- cmdOptDict[name] = value
- reststr = ''
- for x in rest:
- reststr += x + ' '
- if reststr: reststr = reststr[:-1]
- return (cvsGlobOptstr, cvsCmdOptstr, cmdOptDict, reststr)
-
-
-
- def _getAllowedOptions(context, cmd):
- """Returns the option string that is allowed for cmd."""
- return context['basic_cmds.allowedOptions'].get(cmd, '')
-
-
- def _getOptions(context, cmd):
- """Returns the options that should be used for cmd. The return value
- is the tupel (globalOptions, options)"""
- defGlobOpts = context['basic_cmds.ALL.defaultGlobalOptions']
- defOpts = context['basic_cmds.ALL.defaultOptions']
- defGlobOpts += context['basic_cmds.defaultGlobalOptions'].get(cmd,'')
- defOpts += context['basic_cmds.defaultOptions'].get(cmd,'')
- return defGlobOpts,defOpts
-
-
- ##############################
- # Parsing functions
- ##############################
-
- def parseCvsRootSection(lines, context):
- app = context['APP']
- splitRE = re.compile(r'\s*=\s*')
- roots = {}
- for x in lines:
- n = x[0]
- l = splitRE.split(x[1])
- if len(l) != 2:
- app.printErr("Syntax error in configuration file (line %d)." % n)
- else:
- roots[l[0]] = l[1]
- context['basic_cmds.CVSROOTS'] = roots
-
-
- def parseInitCmdsSection(lines, context):
- app = context['APP']
- for x in lines:
- cmd = x[1]
- app.evalCommand(cmd)
-
-
- def parseDefaultOptions(lines, context):
- app = context['APP']
- splitRE = re.compile(r'\s*[,=]\s*')
- defOpts = {}
- defGlobOpts = {}
- for x in lines:
- n = x[0]
- l = splitRE.split(x[1])
- if len(l) < 2:
- app.printErr("Syntax error in configuration file (line %d)." % n)
- continue
- value = l[-1]
- for y in l[:-1]:
- try:
- if y != 'ALL':
- (globOpt, opt,
- du1, du2) = _parseArgs(value, app.cmdToOpts.get(y,''))
- defOpts[y] = opt
- defGlobOpts[y] = globOpt
- else:
- (globOpt, opt, du1, du2) = _parseArgs(value)
- context['basic_cmds.ALL.defaultOptions'] = opt
- context['basic_cmds.ALL.defaultGlobalOptions'] = globOpt
- except getopt.GetoptError, msg:
- app.printErr("Bad format for default options for command "\
- "`%s': %s: %s" % (y, value, str(msg)))
- app.printVMsg("Default global options:\n" \
- + `defGlobOpts` + \
- "\nDefault options:\n" \
- + `defOpts`)
- context['basic_cmds.defaultOptions'] = defOpts
- context['basic_cmds.defaultGlobalOptions'] = defGlobOpts
-
-
- def parseConfigSection(lines, context):
- app = context['APP']
- splitRE = re.compile(r'\s*=\s*')
- for x in lines:
- n = x[0]
- l = splitRE.split(x[1])
- if len(l) != 2:
- app.printErr("Syntax error in configuration file (line %d)." % n)
- continue
- key, value = l
- app.configMap[key] = value
-
-
- ##############################
- # Helper functions
- ##############################
-
- def _cd(app, dir):
- """Changes the current working directory. Returns the old directory."""
- if not dir: return
- oldDir = os.getcwd()
- app.printVMsg('cd ' + dir)
- os.chdir(dir)
- return oldDir
-
-
- def _toggle(app, oldVal, args):
- if len(args) == 0:
- return not oldVal
- else:
- if args == 'on': return 1
- elif args == 'off': return 0
- else:
- app.printErr("argument must be `on' or `off'")
- return oldVal
--- 79,82 ----
Index: configurable_app.py
===================================================================
RCS file: /cvsroot/cvsshell/cvsshell/src/configurable_app.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** configurable_app.py 9 Mar 2002 10:56:20 -0000 1.5
--- configurable_app.py 10 Mar 2002 23:13:59 -0000 1.6
***************
*** 27,34 ****
class ConfigurableApp(App):
def __init__(self):
App.__init__(self)
! self._configsection_to_fun = {}
def setConfigFile(self, filename, default=None):
"""Set the name of the configfile. If the configfile
--- 27,46 ----
class ConfigurableApp(App):
+ class Section:
+ def __init__(self, name, start):
+ self.name = name
+ self.start = start
+ self.end = None
+ self.content = []
+
+
def __init__(self):
App.__init__(self)
! self._configsectionToFun = {}
! self.keyValSplitRE = re.compile(r'\s*=\s*')
! self.keysValSplitRE = re.compile(r'\s*[,=]\s*')
! self.commentRE = re.compile(r'^(\s*|\s*#.*)$')
+
def setConfigFile(self, filename, default=None):
"""Set the name of the configfile. If the configfile
***************
*** 45,56 ****
f.close()
def registerConfigSectionParser(self, name, fun):
"""Registers `fun' for the section `name' in the config file.
The function must accept 2 arguments: The 1st one is
! the lines of the section, the 2nd is the application context.
`fun' is either a function or the name of a function."""
fun = self._getFun(fun)
if fun != None:
! self._configsection_to_fun[name] = fun
def readConfigFile(self):
--- 57,70 ----
f.close()
+
def registerConfigSectionParser(self, name, fun):
"""Registers `fun' for the section `name' in the config file.
The function must accept 2 arguments: The 1st one is
! the lines of the section, the 2nd is the application itself.
`fun' is either a function or the name of a function."""
fun = self._getFun(fun)
if fun != None:
! self._configsectionToFun[name] = fun
!
def readConfigFile(self):
***************
*** 64,71 ****
for x in sections.values():
try:
! self._configsection_to_fun[x.name](x.content, self.CONTEXT)
except KeyError:
self.printErr("Unknown section in configuration file: %s"
! % name)
f.close()
except IOError, msg:
--- 78,85 ----
for x in sections.values():
try:
! self._configsectionToFun[x.name](x.content, self)
except KeyError:
self.printErr("Unknown section in configuration file: %s"
! % x.name)
f.close()
except IOError, msg:
***************
*** 94,98 ****
i = 0
for x in lines:
- print "inserting %s" % x
l.insert(n+i-1, x + '\n')
i += 1
--- 108,111 ----
***************
*** 130,139 ****
return fun
- class Section:
- def __init__(self, name, start):
- self.name = name
- self.start = start
- self.end = None
- self.content = []
def _splitSections(self,lines):
--- 143,146 ----
***************
*** 143,147 ****
Leading and trailing whitespace is also removed from every line
If a syntax exception is encountered, a SyntaxError is raised."""
- comment_re= re.compile(r'^(\s*|\s*#.*)$')
section_start_re = re.compile(r"""
^\s* # matches leading whitespace
--- 150,153 ----
***************
*** 161,165 ****
for l in lines:
n += 1
! if comment_re.match(l):
continue
start = section_start_re.match(l)
--- 167,171 ----
for l in lines:
n += 1
! if self.commentRE.match(l):
continue
start = section_start_re.match(l)
Index: cvs_shell.py
===================================================================
RCS file: /cvsroot/cvsshell/cvsshell/src/cvs_shell.py,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** cvs_shell.py 9 Mar 2002 10:56:20 -0000 1.11
--- cvs_shell.py 10 Mar 2002 23:13:59 -0000 1.12
***************
*** 20,40 ****
###############################################################################
! import os, sys, re, string, types
! from configurable_app import SyntaxError
from interactive_app import InteractiveApp
from plugable_app import PlugableApp
VERSION = '0.1'
! class CvsShell(PlugableApp, InteractiveApp):
def __init__(self):
PlugableApp.__init__(self)
InteractiveApp.__init__(self)
! self.setName('CvsShell')
self.setVersion(VERSION)
! self.setCopyright('Copyright 2002 Stefan Heimann (ma...@st...).\n' \
! 'This software is released under the GPL.')
! self.setBugAddress('http://sourceforge.net/tracker/?group_id=48175&atid=452212')
etcDir = os.path.join(self.THIS_DIR, '..', 'etc')
self.setConfigFile(os.path.join(self.HOME,'.cvsshellrc'),
--- 20,48 ----
###############################################################################
! import os, sys, re, string, types, getopt, utils
! from oo_tools import GetSetProvider
! from app import AppError
from interactive_app import InteractiveApp
from plugable_app import PlugableApp
VERSION = '0.1'
+ NAME ='CvsShell'
+ COPYRIGHT = 'Copyright 2002 Stefan Heimann (ma...@st...).\n' \
+ 'This software is released under the GPL.'
+ BUG_ADDRESS = 'http://sourceforge.net/tracker/?group_id=48175&atid=452212'
+ CvsError = 'CvsError'
+ InternalCvsError = 'InternalCvsError'
! class CvsShell(GetSetProvider, PlugableApp, InteractiveApp):
def __init__(self):
+ GetSetProvider.__init__(self)
PlugableApp.__init__(self)
InteractiveApp.__init__(self)
! sys.stderr = sys.stdout
! self.setName(NAME)
self.setVersion(VERSION)
! self.setCopyright(COPYRIGHT)
! self.setBugAddress(BUG_ADDRESS)
etcDir = os.path.join(self.THIS_DIR, '..', 'etc')
self.setConfigFile(os.path.join(self.HOME,'.cvsshellrc'),
***************
*** 47,50 ****
--- 55,59 ----
self.cmdRegex = re.compile(r"""
^\s* # matches leading whitespace
+ (?!\#) # line is not a comment (negative lookahead!)
(?P<name>\S+) # matches the first word of the command
(
***************
*** 53,69 ****
)? # options are optional
""", re.VERBOSE)
self.cvsRoot = None
self.cvsRootAutoUpdate = 0
self.showFullPrompt = 0
self.configMap = {}
self.readCommandFile()
self.readConfigFile()
-
- def setCvsRoot(self, root):
- self.cvsRoot = root
-
- def getCvsRoot(self):
- return self.cvsRoot
def readCvsRootFromFile(self):
s = None
--- 62,85 ----
)? # options are optional
""", re.VERBOSE)
+ self.cvsChangeCmdRE = re.compile(r"""\s+
+ (ad(d)?|new|ci|com(mit)?|delete|remove)
+ \s+""", re.VERBOSE)
+ self.noListingErrMsg = """No listing found.
+ You must run `update', `refresh' or `status' before using this command."""
self.cvsRoot = None
self.cvsRootAutoUpdate = 0
self.showFullPrompt = 0
+ self.listing = None
+ self.dirtyListing = 1
+ self.cvsRootAliases = {}
self.configMap = {}
+ self.cmdToDefOpts = {}
+ self.cmdToDefGlobOpts = {}
+ self.defOpts = '' # options for all commands
+ self.defGlobOpts = '' # global options for all commands
self.readCommandFile()
self.readConfigFile()
+
def readCvsRootFromFile(self):
s = None
***************
*** 72,75 ****
--- 88,92 ----
return s
+
def getPrompt(self):
status = ''
***************
*** 77,81 ****
else: status += 'A'
root = self.getCvsRoot() or '--'
! dir = os.getcwd().replace(self.HOME, '~')
if not self.showFullPrompt:
# make to prompt match on one line
--- 94,102 ----
else: status += 'A'
root = self.getCvsRoot() or '--'
! try:
! dir = os.getcwd().replace(self.HOME, '~')
! # if you delete the dir you are in, getcwd raise an error
! except OSError:
! dir = 'ERROR'
if not self.showFullPrompt:
# make to prompt match on one line
***************
*** 100,103 ****
--- 121,125 ----
root)
+
def evalCommand(self, cmd):
result = self.cmdRegex.match(cmd)
***************
*** 109,114 ****
cmdOpts = ''
cmdOpts = cmdOpts.strip()
! fun = self.getCmdFun(cmdName, self.execShellCmd)
! return fun(cmdName, cmdOpts, self.CONTEXT)
--- 131,136 ----
cmdOpts = ''
cmdOpts = cmdOpts.strip()
! fun = self.getCmdFun(cmdName, CvsShell.execShellCmd)
! return fun(self, cmdName, cmdOpts)
***************
*** 117,149 ****
! _cvsChangeCmdRE = re.compile(r"""\s+
! (ad(d)?|new|ci|com(mit)?|delete|remove)
! \s+""", re.VERBOSE)
! def execShellCmd(self, name, opts, context):
! app = context['APP']
! if name == 'cvs' and CvsShell._cvsChangeCmdRE.search(opts):
# command may change the status
! context['basic_cmds.dirty_listing'] = 1
! app.shell('%s %s' % (name, opts))
! def more(self, lines=None, str=None, numlines=24):
if lines is not None:
! str = string.join(lines, '')
! elif str is not None:
! lines = str.split('\n')
else:
raise AppError, \
! "Illegal argument: One of lines or str must be given"
if len(lines) <= numlines or not self.configMap.has_key('pager'):
! self.printMsg(str)
else:
pager = self.configMap['pager']
try:
! os.popen(pager, 'w').write(str)
! except IOError: pass
! except OSError, msg:
! self.printMsg(str)
! self.printErr("Error invoking pager: %s" % str(msg))
--- 139,386 ----
! def execShellCmd(self, name, opts):
! if name == 'cvs' and self.cvsChangeCmdRE.search(opts):
# command may change the status
! self.setDirtyListing(1)
! self.shell('%s %s' % (name, opts))
! def toggle(self, oldVal, args):
! if len(args) == 0:
! return not oldVal
! else:
! if args == 'on': return 1
! elif args == 'off': return 0
! else:
! self.printErr("argument must be `on' or `off'")
! return oldVal
!
!
! def more(self, lines=None, s=None, numlines=22):
if lines is not None:
! s = string.join(lines, '')
! elif s is not None:
! lines = s.split('\n')
else:
raise AppError, \
! "Illegal argument: One of lines or s must be given"
if len(lines) <= numlines or not self.configMap.has_key('pager'):
! self.printMsg(s, nonl=1)
else:
+ import tempfile
pager = self.configMap['pager']
try:
! tmp = tempfile.mktemp()
! open(tmp,'w').write(s)
! self.shell(pager + ' ' + tmp)
! except (IOError,OSError), msg:
! self.printMsg(s, nonl=1)
! self.printErr("Error invoking pager `%s': %s" % (pager,str(msg)))
!
!
! ##############################
! # CVS helper methods
! ##############################
!
! def runCvsCmd(self, cmd, rootDir=None, cvsRoot=None, globOpts = '',
! args='', fork=1, getStderr=0):
! """
! * cmd is the command to execute
! * rootDir is the directory the command should be executed in
! * globOpts are global options. These options
! override the default global options
! * args are the arguments that should be passed to the cvs command
! """
! oldDir = None
! if rootDir is not None:
! try:
! oldDir = self.cd(rootDir)
! except OSError,msg:
! self.printErr("Could not change to the root directory of " \
! "the current listing: %s" % str(msg))
! raise CvsError
! #
! defGlobOpts,defOpts = self.getOptions(cmd)
! cvsRoot = cvsRoot or self.getCvsRoot()
! if cvsRoot != None: cvsRootOpt = "-d %s" % cvsRoot
! else: cvsRootOpt = ''
! #
! globOpts = "%s %s %s" % (defGlobOpts, cvsRootOpt, globOpts)
! args = "%s %s" % (defOpts, args)
! cmd = 'cvs %s %s %s' % (globOpts, cmd, args)
! if getStderr: cmd += ' 2>&1' # FIXME: does not work on win!
! self.printVMsg(cmd)
! if fork:
! f = os.popen(cmd)
! try:
! lines = f.readlines()
! except KeyboardInterrupt:
! return []
! if f.close() is not None: # cvs command caused an error
! raise CvsError
! else:
! return lines
! else:
! r = os.system(cmd)
! if r != 0:
! raise CvsError
! if oldDir is not None:
! try:
! self.cd(oldDir)
! except OSError,msg:
! self.printErr(msg)
! return None
!
!
! def applyOnEntryList(self, opts, fun):
! """Applies fun to the entries of the current listing selected by opts.
! opts is a string that may specify some numbers
! which refers to entries in the listing.
! fun must take 2 argument as the entry and its
! filename is passed to it. Returns a
! list with the return values from fun.
! If a error occurs, an AppError is raised. If this error is
! encountered while parsing opts, a ParseError is raised."""
! nums = utils.parseNumberStr(opts)
! if len(nums) == 0:
! raise AppError, 'No files specified.'
! if not self.listing:
! raise AppError, self.noListingErrMsg
! result = []
! max = len(self.listing.entries)
! for x in nums:
! if x < 0 or x > max: continue
! e = self.listing.entries[x]
! name = os.path.join(e.dir, e.name)
! result.append(fun(e,name))
! return result
!
!
! def printListing(self):
! if not self.listing:
! self.printErr(self.noListingErrMsg)
! else:
! self.listing.printEntries()
! if self.getDirtyListing():
! self.printMsg("Listing may be out-of-date. " \
! "Run `update', `refresh' or `status'.")
!
!
! def parseArgs(self, args, cvsCmdOpts='', cmdOpts=''):
! """Parse args and separates it like that:
! cvsCmdOpts are the options that are allowed for the cvs command
! cmdOpts are additional options (provided by cvsshell)
! global options are handled automatically
! * global cvs options (as string)
! * command specific cvs options (as string)
! * other options (as dictionary)
! * other args (as string)
! These values are returned as a 4-tupel.
! A GetoptError is raised if there are unknown options."""
! cvsGlobOpts = 'HQqrwlntvb:T:e:d:fz:as:'
! s = cvsGlobOpts+cvsCmdOpts+cmdOpts
! (opts, rest) = getopt.getopt(utils.splitquoted(args), s)
! cvsGlobOptstr = cvsCmdOptstr = ''
! cmdOptDict = {}
! for x in opts:
! name, value = x
! # getopt prepends '-' to every option
! if name[1] in cvsGlobOpts:
! cvsGlobOptstr += ' ' + name
! if value: cvsGlobOptstr += ' ' + value
! elif name[1] in cvsCmdOpts:
! cvsCmdOptstr += ' ' + name
! if value: cvsCmdOptstr += ' ' + value
! else:
! cmdOptDict[name] = value
! if cvsGlobOptstr: cvsGlobOptstr = cvsGlobOptstr[1:] # remove trailing ' '
! if cvsCmdOptstr: cvsCmdOptstr = cvsCmdOptstr[1:] # remove trailing ' '
! reststr = ''
! for x in rest:
! reststr += x + ' '
! if reststr: reststr = reststr[:-1]
! return (cvsGlobOptstr, cvsCmdOptstr, cmdOptDict, reststr)
!
!
! def getOptions(self, cmd):
! """Returns the options that should be used for cmd. The return value
! is the tupel (globalOptions, options)"""
! defGlobOpts = self.getDefGlobOpts()
! defOpts = self.getDefOpts()
! defGlobOpts += ' ' + self.getCmdToDefGlobOpts().get(cmd,'')
! defOpts += ' ' + self.getCmdToDefOpts().get(cmd,'')
! return defGlobOpts,defOpts
!
!
!
! ##############################
! # Listing
! ##############################
!
! class Listing(GetSetProvider):
!
! def __init__(self, app, rootDir, entries=[]):
! GetSetProvider.__init__(self)
! self.app = app
! self.rootDir = rootDir
! self.entries = entries
! self.sortOrder = ['dir', 'status', 'name']
!
! def sortEntries(self):
! class __EntrySorter:
! def __init__(self, order): self.order = order
! def cmp(self,x,y):
! try:
! i = 0
! for attr in self.order:
! i = eval("cmp(x.%s, y.%s)" % (attr,attr))
! if i != 0: return i
! return i
! except AttributeError:
! return -1
! self.entries.sort(__EntrySorter(self.sortOrder).cmp)
!
! def printEntries(self, verbose=1):
! if not self.entries:
! if verbose: self.app.printMsg('No entries available.')
! return
! max = 0
! for e in self.entries:
! l = len(e.status)
! if l > max: max = l
! formatStr = " %%%dd %%-%ds %%s\n" % (len(`len(self.entries)`), max)
! oldDir = None
! id = 0
! lines = []
! for e in self.entries:
! newDir = e.dir
! if oldDir != newDir:
! lines.append("%s:\n" % newDir)
! lines.append(formatStr % (id, e.status, e.name))
! id += 1
! oldDir = newDir
! self.app.more(lines)
!
! ##############################
! # Entry
! ##############################
!
! class Entry(GetSetProvider):
! S_NEW = 'N'
! S_ADDED = 'A'
! S_CONFLICT = 'C'
! S_MODIFIED = 'M'
! S_PATCHED = 'P'
! S_REMOVED = 'R'
! S_UPDATED = 'U'
! S_UNKNOWN = '?'
! S_OK = 'OK' # file on the sandbox is in sync with repository
! S_DELETED = 'D' # file scheduled for removal has been commited
! def __init__(self, dir, name, status):
! GetSetProvider.__init__(self)
! self.dir = dir
! self.name = name
! self.status = status
!
Index: interactive_app.py
===================================================================
RCS file: /cvsroot/cvsshell/cvsshell/src/interactive_app.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** interactive_app.py 7 Mar 2002 15:09:26 -0000 1.4
--- interactive_app.py 10 Mar 2002 23:13:59 -0000 1.5
***************
*** 57,61 ****
if result is self.BREAK_REPL: break
elif result is None: continue
! else: self.printMsg(`result`)
def readCommand(self): # subclass hooks + App.start,stop
--- 57,61 ----
if result is self.BREAK_REPL: break
elif result is None: continue
! else: self.printMsg(result)
def readCommand(self): # subclass hooks + App.start,stop
***************
*** 67,78 ****
def prompt(self, msg):
"""Displayes msg and prompts the user for input.
! If input is EOF, None is returned."""
!
try:
a = raw_input(msg)
! except EOFError, KeyboardInterrupt:
self.printMsg()
return None
a = os.path.expandvars(a)
return a.strip()
--- 67,78 ----
def prompt(self, msg):
"""Displayes msg and prompts the user for input.
! If input is EOF, None is returned."""
try:
a = raw_input(msg)
! except (EOFError, KeyboardInterrupt):
self.printMsg()
return None
a = os.path.expandvars(a)
+ a = os.path.expanduser(a)
return a.strip()
Index: oo_tools.py
===================================================================
RCS file: /cvsroot/cvsshell/cvsshell/src/oo_tools.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** oo_tools.py 9 Mar 2002 17:24:46 -0000 1.1
--- oo_tools.py 10 Mar 2002 23:13:59 -0000 1.2
***************
*** 32,36 ****
#
# To make it thread-safe, one must lock all access-points of the variable
! # GetSetProvider.__storage.
AccessError = 'AccessError'
--- 32,36 ----
#
# To make it thread-safe, one must lock all access-points of the variable
! # _GetSetProvider__storage.
AccessError = 'AccessError'
***************
*** 40,43 ****
--- 40,64 ----
get/set methods for all their variables.
"""
+ _GetSetProvider__storage = None
+
+ class Getter:
+ def __init__(self, dict, attrname, classname):
+ self.dict = dict
+ self.attrname = attrname
+ self.classname = classname
+ def __call__(self):
+ try:
+ return self.dict[self.attrname]
+ except KeyError:
+ raise AttributeError, "%s instance has no attribute '%s'" % \
+ (self.classname, self.attrname)
+
+
+ class Setter:
+ def __init__(self, dict, name):
+ self.dict = dict
+ self.name = name
+ def __call__(self, val):
+ self.dict[self.name] = val
def __init__(self):
***************
*** 47,58 ****
def __getattr__(self, name):
if len(name) > 3:
! pre, attr = name[:3], name[3].lower() + name[4:]
if attr[0] == '_':
self.__raiseAccessError(attr, 'private')
if pre == 'get':
if attr in self.__private:
self.__raiseAccessError(attr, 'private')
! GetSetProvider.__storage = eval('self.' + attr)
! return lambda : GetSetProvider.__storage
if pre == 'set':
if attr in self.__private:
--- 68,81 ----
def __getattr__(self, name):
if len(name) > 3:
! pre, attr = name[:3], name[3:]
if attr[0] == '_':
self.__raiseAccessError(attr, 'private')
+ if not self.__dict__.has_key(attr):
+ attr = attr[0].lower() + attr[1:]
if pre == 'get':
if attr in self.__private:
self.__raiseAccessError(attr, 'private')
! return GetSetProvider.Getter(self.__dict__, attr,
! self.__class__.__name__)
if pre == 'set':
if attr in self.__private:
***************
*** 60,69 ****
elif attr in self.__readonly:
self.__raiseAccessError(attr, 'readonly')
! GetSetProvider.__storage = (self.__dict__, attr)
! def __set(val):
! dict, name = GetSetProvider.__storage
! dict[name] = val
! return __set
! raise AttributeError, "class %s has no attribute '%s'" % \
(self.__class__.__name__, name)
--- 83,88 ----
elif attr in self.__readonly:
self.__raiseAccessError(attr, 'readonly')
! return GetSetProvider.Setter(self.__dict__, attr)
! raise AttributeError, "%s instance has no attribute '%s'" % \
(self.__class__.__name__, name)
***************
*** 113,116 ****
--- 132,137 ----
self.t.setAge(23)
self.assertEqual(self.t.getAge(), 23)
+ self.t.QName = 'foo'
+ self.assertEqual(self.t.getQName(), 'foo')
def testAccess(self):
self.assertEqual(self.t.getReadonly(), 'readonly')
***************
*** 127,131 ****
fail('should raise exception here.')
except AccessError: pass
!
unittest.main()
--- 148,155 ----
fail('should raise exception here.')
except AccessError: pass
! def testDelayedInvocation(self):
! fun = self.t.getStreet
! self.t.setStreet('xy')
! self.assertEqual(fun(), 'xy')
unittest.main()
Index: plugable_app.py
===================================================================
RCS file: /cvsroot/cvsshell/cvsshell/src/plugable_app.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** plugable_app.py 8 Mar 2002 22:31:01 -0000 1.4
--- plugable_app.py 10 Mar 2002 23:13:59 -0000 1.5
***************
*** 27,35 ****
def __init__(self):
ConfigurableApp.__init__(self)
! self.cmdOpts = {}
! self.cmdToFun = {}
self.cmdToDoc = {}
self.cmdToCmds = {}
! self.cmdToOpts = {}
def setCommandFile(self,filename):
--- 27,34 ----
def __init__(self):
ConfigurableApp.__init__(self)
! self._cmdToFun = {}
self.cmdToDoc = {}
self.cmdToCmds = {}
! self.cmdToAllowedOpts = {} # cmd -> options possible for this cmd
def setCommandFile(self,filename):
***************
*** 63,72 ****
l = splitRE.split(x[1])
if len(l) < 2:
! app.printErr("Syntax error in configuration file (line %d)."
% n)
continue
value = l[-1]
for y in l[:-1]:
! self.cmdToOpts[y] = value
prs = sections.get('PARSERS', [])
--- 62,71 ----
l = splitRE.split(x[1])
if len(l) < 2:
! self.printErr("Syntax error in configuration file (line %d)."
% n)
continue
value = l[-1]
for y in l[:-1]:
! self.cmdToAllowedOpts[y] = value
prs = sections.get('PARSERS', [])
***************
*** 84,88 ****
def getCmdFun(self, cmdName, default=None):
! return self.cmdToFun.get(cmdName, default)
def registerCmdFun(self, cmdName, fun, doc=None):
--- 83,87 ----
def getCmdFun(self, cmdName, default=None):
! return self._cmdToFun.get(cmdName, default)
def registerCmdFun(self, cmdName, fun, doc=None):
***************
*** 95,105 ****
funtion by supplying a list of names in `cmdName'.
`fun' is either a function or the name of a function in the
! currrent namespace. The function must take 3 arguments: the
! 1st argument is the name of the command, the 2nd argument is
! the option-string that was passed to the command and
! the 3rd argument is the application context. To avoid
! naming-conflicts in this dictionary, all commands should
! prepend the name of the module they are defined in
! followed by `.' to the keys."""
if type(cmdName) is types.ListType:
l = cmdName
--- 94,101 ----
funtion by supplying a list of names in `cmdName'.
`fun' is either a function or the name of a function in the
! currrent namespace. The function must take 3 arguments:
! the 1st argument is the application itself, ths
! 2nd argument is the name of the command, the 3rd argument is
! the option-string that was passed to the command"""
if type(cmdName) is types.ListType:
l = cmdName
***************
*** 113,117 ****
cmds = ''
for x in l:
! self.cmdToFun[x] = fun
self.cmdToDoc[x] = doc
cmds += "%s, " % x
--- 109,113 ----
cmds = ''
for x in l:
! self._cmdToFun[x] = fun
self.cmdToDoc[x] = doc
cmds += "%s, " % x
Index: utils.py
===================================================================
RC...
[truncated message content] |