[Cvsshell-devel] CVS: cvsshell/src basic_cmds.py,1.9,1.10 cvs_shell.py,1.8,1.9 plugable_app.py,1.2,1
Status: Beta
Brought to you by:
stefanheimann
From: Stefan H. <ste...@us...> - 2002-03-08 11:12:33
|
Update of /cvsroot/cvsshell/cvsshell/src In directory usw-pr-cvs1:/tmp/cvs-serv22728/src Modified Files: basic_cmds.py cvs_shell.py plugable_app.py utils.py Log Message: Added support for better handling of arguments to cvs commands Index: basic_cmds.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/basic_cmds.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** basic_cmds.py 7 Mar 2002 15:10:51 -0000 1.9 --- basic_cmds.py 8 Mar 2002 11:12:29 -0000 1.10 *************** *** 20,24 **** ############################################################################### ! import os, string, re import utils from app import AppError --- 20,24 ---- ############################################################################### ! import os, string, re, getopt import utils from app import AppError *************** *** 105,109 **** regexUnknown = re.compile(r'^\?\s+(?P<filename>\S+)') try: ! lines = _runCvsCmd(context, 'status', args=args, getStderr=1) except CvsError: return entries = [] --- 105,117 ---- 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 = [] *************** *** 137,144 **** def update(name, args, context, simulate=0): app = context['APP'] - if simulate: globOpts = '-n' - else: globOpts = '' try: ! lines = _runCvsCmd(context, 'update', globOpts=globOpts, args=args) except CvsError: return entries = [] --- 145,158 ---- 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 = [] *************** *** 160,165 **** def checkout(name, args, context): app = context['APP'] ! args = args.split() ! if len(args) < 1: module = app.prompt('enter name of module: ') if module is None: return --- 174,186 ---- 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 len(rest) < 1: module = app.prompt('enter name of module: ') if module is None: return *************** *** 167,171 **** module = args[0] try: ! _runCvsCmd(context, 'checkout', args=module) except CvsError: pass --- 188,193 ---- module = args[0] try: ! _runCvsCmd(context, 'checkout', globOpts=globOpts, ! args=opts+' '+module) except CvsError: pass *************** *** 173,188 **** def add(name, args, context, isBinary=0): app = context['APP'] ! if not args: ! args = app.prompt('enter filenumber(s) to add: ') ! if args is None: return def __doIt(e,filename): e.status = utils.Entry.S_ADDED return filename ! (rootDir, filenames) = _applyOnEntryList(args, context, __doIt) if filenames: ! if isBinary: opts = '-kb' ! else: opts = '' try: ! _runCvsCmd(context, 'add', rootDir=rootDir, opts=opts, args=utils.list2string(filenames)) except CvsError: pass --- 195,217 ---- 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: ! number = app.prompt('enter filenumber(s) to add: ') ! if numbers is None: return def __doIt(e,filename): e.status = utils.Entry.S_ADDED return filename ! (rootDir, filenames) = _applyOnEntryList(numbers, context, __doIt) if filenames: ! if isBinary: opts += '-kb' try: ! _runCvsCmd(context, 'add', rootDir=rootDir, globOpts=globOpts, ! args=opts+' '+utils.list2string(filenames)) except CvsError: pass *************** *** 195,199 **** def commit(name, args, context): app = context['APP'] ! if not args: try: try: --- 224,237 ---- def commit(name, args, context): app = context['APP'] ! try: ! (globOpts, opts, ! myOpts, rest) = _parseArgs(args, ! app.cmdToOpts.get(name, '')) ! print "opts = %s" % opts ! print "rest = %s" % rest ! except getopt.GetoptError, msg: ! app.printErr(msg) ! return ! if not rest: try: try: *************** *** 202,206 **** except KeyError: rootDir = '' ! _runCvsCmd(context, 'commit', rootDir=rootDir, fork=1) context['basic_cmds.dirty_listing'] = 1 except CvsError: pass --- 240,245 ---- except KeyError: rootDir = '' ! _runCvsCmd(context, 'commit', rootDir=rootDir, ! globOpts=globOpts, args=opts, fork=1) context['basic_cmds.dirty_listing'] = 1 except CvsError: pass *************** *** 212,229 **** e.status = utils.Entry.S_OK return filename ! (rootDir, filenames) = _applyOnEntryList(args, context, __doIt) if filenames: try: ! _runCvsCmd(context, 'commit', rootDir=rootDir, args=utils.list2string(filenames), fork=1) except CvsError: pass def remove(name, args, context): app = context['APP'] ! if args == '': ! args = app.prompt('enter filenumber(s) to remove: ') ! if args is None: return def __doIt(e,filename): return e ! (rootDir, toDelete) = _applyOnEntryList(args, context, __doIt) toDeleteList = utils.Listing(rootDir, toDelete) filenames = [] --- 251,276 ---- 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 def remove(name, args, context): app = context['APP'] ! try: ! (globOpts, opts, ! myOpts, numbers) = _parseArgs(args, ! app.cmdToOpts.get(name, '')) ! except getopt.GetoptError, msg: ! app.printErr(msg) ! return ! if not numbers: ! numbers = app.prompt('enter filenumber(s) to remove: ') ! if numbers is None: return def __doIt(e,filename): return e ! (rootDir, toDelete) = _applyOnEntryList(numbers, context, __doIt) toDeleteList = utils.Listing(rootDir, toDelete) filenames = [] *************** *** 240,244 **** args = utils.list2string(filenames) try: ! _runCvsCmd(context, 'remove', rootDir=rootDir, args=args) except CvsError: return toDeleteList.printEntries(app.output) --- 287,292 ---- args = utils.list2string(filenames) try: ! _runCvsCmd(context, 'remove', rootDir=rootDir, ! globOpts=globOpts, args=opts+' '+args) except CvsError: return toDeleteList.printEntries(app.output) *************** *** 334,348 **** ! def _runCvsCmd(context, cmd, rootDir=None, globOpts = '', opts='', 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 passed by a function. These options override the default global options ! * opts are the command specific options passed by a function. These ! options override the default options for the command ! * args are the arguments the user passed to the command. Everything ! left from to first '%' sign is interpreted as global option. A ! options the user specifies overrides all other options """ app = context['APP'] --- 382,393 ---- ! 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'] *************** *** 353,361 **** 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) - userGlobOpts, userOpts = _splitOpts(args) cvsRoot = app.getCvsRoot() --- 398,406 ---- 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() *************** *** 363,376 **** else: cvsRootOpt = '' ! globOpts = "%s %s %s %s" % (defGlobOpts, cvsRootOpt, ! globOpts, userGlobOpts) ! opts = "%s %s %s" % (defOpts, opts, userOpts) ! cmd = 'cvs %s %s %s' % (globOpts, cmd, opts) if getStderr: cmd += ' 2>&1' app.printVMsg(cmd) if not fork: f = os.popen(cmd) ! lines = f.readlines() if f.close() is not None: # cvs command caused an error raise CvsError --- 408,423 ---- 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 *************** *** 405,409 **** if _isDirtyListing(context): app.printMsg("Listing may be out-of-date. " \ ! "Run `update' or `status'.") --- 452,503 ---- 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.splitquotes(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 *************** *** 425,428 **** --- 519,523 ---- context['basic_cmds.CVSROOTS'] = roots + def parseInitCmdsSection(lines, context): app = context['APP'] *************** *** 431,434 **** --- 526,530 ---- app.evalCommand(cmd) + def parseDefaultOptions(lines, context): app = context['APP'] *************** *** 442,453 **** app.printErr("Syntax error in configuration file (line %d)." % n) continue ! globOpt,opt = _splitOpts(l[-1]) for y in l[:-1]: ! if y != 'ALL': ! defOpts[y] = opt ! defGlobOpts[y] = globOpt ! else: ! context['basic_cmds.ALL.defaultOptions'] = opt ! context['basic_cmds.ALL.defaultGlobalOptions'] = globOpt context['basic_cmds.defaultOptions'] = defOpts context['basic_cmds.defaultGlobalOptions'] = defGlobOpts --- 538,560 ---- 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 *************** *** 466,495 **** return oldDir - def _splitOpts(args): - """Splits a cvs option into its global and command specific part. - The parts are divided by a `%'. The tupel (globalOptions, options) - is returned.""" - i = args.find("%") - if i > 0: - return args[:i], args[i+1:] - else: - return '',args - - def _getOptions(context,cmd): - """Returns the options that should be used for cmd. The return value - is the tupel (globalOptions, options)""" - try: - defGlobOpts = context['basic_cmds.ALL.defaultGlobalOptions'] - except KeyError: pass - try: - defOpts = context['basic_cmds.ALL.defaultOptions'] - except KeyError: pass - try: - defGlobOpts += context['basic_cmds.defaultGlobalOptions'][cmd] - except KeyError: pass - try: - defOpts += context['basic_cmds.defaultOptions'][cmd] - except KeyError: pass - return defGlobOpts,defOpts def _toggle(app, oldVal, args): --- 573,576 ---- Index: cvs_shell.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/cvs_shell.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** cvs_shell.py 7 Mar 2002 15:10:51 -0000 1.8 --- cvs_shell.py 8 Mar 2002 11:12:29 -0000 1.9 *************** *** 113,120 **** InteractiveApp.run(self) ! _cvsChangeCmdRE = re.compile(r'\s+(ad(d)?|new|ci|com(mit)?|delete|remove)\s+') 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)) --- 113,123 ---- InteractiveApp.run(self) ! _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)) Index: plugable_app.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/plugable_app.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** plugable_app.py 7 Mar 2002 13:08:49 -0000 1.2 --- plugable_app.py 8 Mar 2002 11:12:29 -0000 1.3 *************** *** 31,35 **** self.cmdToDoc = {} self.cmdToCmds = {} ! def setCommandFile(self,filename): self.commandFile = filename --- 31,36 ---- self.cmdToDoc = {} self.cmdToCmds = {} ! self.cmdToOpts = {} ! def setCommandFile(self,filename): self.commandFile = filename *************** *** 37,41 **** def readCommandFile(self): """Read the file that defines the different commands and parsers.""" ! split_re = re.compile(r'\s*[,=]\s*') f = open(self.commandFile,'r') try: --- 38,42 ---- def readCommandFile(self): """Read the file that defines the different commands and parsers.""" ! splitRE = re.compile(r'\s*[,=]\s*') f = open(self.commandFile,'r') try: *************** *** 43,54 **** except SyntaxError, msg: self.printErr("Syntax error in command file: %s" % msg) ! if sections.has_key('COMMANDS'): ! cmds = sections['COMMANDS'] ! else: ! cmds = [] for x in cmds: n = x[0] line = x[1] ! s = split_re.split(line) if(len(s)) < 2: self.printErr("Syntax error in line %d of command " \ --- 44,53 ---- except SyntaxError, msg: self.printErr("Syntax error in command file: %s" % msg) ! ! cmds = sections.get('COMMANDS', []) for x in cmds: n = x[0] line = x[1] ! s = splitRE.split(line) if(len(s)) < 2: self.printErr("Syntax error in line %d of command " \ *************** *** 56,67 **** else: self.registerCmdFun(s[:-1], s[-1]) ! if sections.has_key('PARSERS'): ! prs = sections['PARSERS'] ! else: ! prs = [] for x in prs: n = x[0] line = x[1] ! s = split_re.split(line) if(len(s)) != 2: self.printErr("Syntax error in line %d of command " \ --- 55,76 ---- else: self.registerCmdFun(s[:-1], s[-1]) ! ! opts = sections.get('COMMAND_OPTIONS', []) ! for x in opts: ! 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]: ! self.cmdToOpts[y] = value ! ! prs = sections.get('PARSERS', []) for x in prs: n = x[0] line = x[1] ! s = splitRE.split(line) if(len(s)) != 2: self.printErr("Syntax error in line %d of command " \ Index: utils.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/utils.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** utils.py 7 Mar 2002 13:08:49 -0000 1.3 --- utils.py 8 Mar 2002 11:12:29 -0000 1.4 *************** *** 136,139 **** --- 136,153 ---- + _splitRE = re.compile(r'("(?:[^"\\]+|\\.)*"|\S+)') + def splitquotes(str): + """Splits str on whitespace except when a quoted string is + encountered. + # Example: splitquotes('foo "foo \"bar\""') => ['foo','"foo \"bar\""'] + """ + res = [] + for x in _splitRE.split(str): + x = x.strip() + if x: res.append(x) # not only whitespace + return res + + + ############################## # Tests |