cvsshell-devel Mailing List for CvsShell (Page 9)
Status: Beta
Brought to you by:
stefanheimann
You can subscribe to this list here.
2002 |
Jan
|
Feb
|
Mar
(82) |
Apr
|
May
(14) |
Jun
(3) |
Jul
(27) |
Aug
(18) |
Sep
(10) |
Oct
(1) |
Nov
(8) |
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
|
Feb
(1) |
Mar
(1) |
Apr
(63) |
May
(2) |
Jun
(2) |
Jul
(2) |
Aug
|
Sep
(3) |
Oct
(2) |
Nov
|
Dec
|
2004 |
Jan
|
Feb
(5) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Stefan H. <ste...@us...> - 2002-03-14 18:45:50
|
Update of /cvsroot/cvsshell/cvsshell/src In directory usw-pr-cvs1:/tmp/cvs-serv17143/src Modified Files: cvs_cmds.py cvs_shell.py Log Message: * Directories in listing are now marked * listing is made dirty after adding a directory Index: cvs_cmds.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/cvs_cmds.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** cvs_cmds.py 11 Mar 2002 12:02:13 -0000 1.2 --- cvs_cmds.py 14 Mar 2002 18:45:46 -0000 1.3 *************** *** 158,161 **** --- 158,162 ---- for x in l: e,name = x + if os.path.isdir(name): app.setDirtyListing(1) filenames += name + ' ' entries.append(e) Index: cvs_shell.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/cvs_shell.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** cvs_shell.py 11 Mar 2002 12:02:13 -0000 1.14 --- cvs_shell.py 14 Mar 2002 18:45:46 -0000 1.15 *************** *** 364,368 **** l = len(e.status) if l > max: max = l ! formatStr = " %%%dd %%-%ds %%s\n" % (len(`len(self.entries)`), max) oldDir = None id = 0 --- 364,368 ---- l = len(e.status) if l > max: max = l ! formatStr = " %%%dd %%-%ds %%s%%s\n" % (len(`len(self.entries)`), max) oldDir = None id = 0 *************** *** 372,376 **** if oldDir != newDir: lines.append("%s:\n" % newDir) ! lines.append(formatStr % (id, e.status, e.name)) id += 1 oldDir = newDir --- 372,380 ---- if oldDir != newDir: lines.append("%s:\n" % newDir) ! if os.path.isdir(os.path.join(self.rootDir, e.dir, e.name)): ! isDir = "<dir>" ! else: ! isDir = '' ! lines.append(formatStr % (id, e.status, isDir, e.name)) id += 1 oldDir = newDir |
From: Stefan H. <ste...@us...> - 2002-03-14 18:45:50
|
Update of /cvsroot/cvsshell/cvsshell/testing In directory usw-pr-cvs1:/tmp/cvs-serv17143/testing Modified Files: run-test.py Log Message: * Directories in listing are now marked * listing is made dirty after adding a directory Index: run-test.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/testing/run-test.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** run-test.py 11 Mar 2002 12:02:15 -0000 1.2 --- run-test.py 14 Mar 2002 18:45:47 -0000 1.3 *************** *** 32,36 **** testcode = open(thisDir + '/testinput').read() os.system('rm -rf /tmp/testdata /tmp/cvsroot') # little clean-up ! os.unlink(os.path.join(os.environ['HOME'], '.cvsshellrc')) os.chdir('/tmp') stdin, stdout, stderr = os.popen3('python %s/../src/cvs_shell.py -v' % thisDir) --- 32,38 ---- testcode = open(thisDir + '/testinput').read() os.system('rm -rf /tmp/testdata /tmp/cvsroot') # little clean-up ! try: ! os.unlink(os.path.join(os.environ['HOME'], '.cvsshellrc')) ! except: pass os.chdir('/tmp') stdin, stdout, stderr = os.popen3('python %s/../src/cvs_shell.py -v' % thisDir) |
From: Stefan H. <ste...@us...> - 2002-03-11 12:02:18
|
Update of /cvsroot/cvsshell/cvsshell/testing In directory usw-pr-cvs1:/tmp/cvs-serv29583/testing Modified Files: refstdout run-test.py testinput Log Message: * added support for filtering the file-listing * add now ask if the files should be added. Index: refstdout =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/testing/refstdout,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** refstdout 10 Mar 2002 23:13:01 -0000 1.1 --- refstdout 11 Mar 2002 12:02:15 -0000 1.2 *************** *** 2,5 **** --- 2,6 ---- ====== initializing the repository ====== ====== importing the testdata ====== + N testdata/I_AM_HERE.pyc N testdata/test1 N testdata/test2 *************** *** 26,31 **** ====== Testing add ====== === add 1 === - === add 2 === - === add 3 === RCS file: /tmp/cvsroot/testdata/addtest1,v done --- 27,30 ---- *************** *** 53,56 **** --- 52,56 ---- done CVS + I_AM_HERE.pyc addtest1 addtest2 *************** *** 61,64 **** --- 61,65 ---- ====== Testing remove ====== CVS + I_AM_HERE.pyc addtest1 dirX *************** *** 77,81 **** This software is released under the GPL. CvsShell started. ! {a} ~/cvsshell/testing [--] $ cd /tmp {a} /private/tmp [--] --- 78,82 ---- This software is released under the GPL. CvsShell started. ! {a} /private/tmp [--] $ cd /tmp {a} /private/tmp [--] *************** *** 90,93 **** --- 91,96 ---- $ echo "You are file test2" > test2 {a} /private/tmp/testdata [--] + $ echo "You are a file that should by filtered" > I_AM_HERE.pyc + {a} /private/tmp/testdata [--] $ mkdir testdir {a} /private/tmp/testdata [--] *************** *** 184,190 **** {a} /private/tmp/testdata [/tmp/cvsroot] $ cvs -z 3 -d /tmp/cvsroot add addtest1 ! {a} /private/tmp/testdata [/tmp/cvsroot] ! $ echo === add 2 === ! {a} /private/tmp/testdata [/tmp/cvsroot] $ echo "I am addtest2" > addtest2 {a} /private/tmp/testdata [/tmp/cvsroot] --- 187,193 ---- {a} /private/tmp/testdata [/tmp/cvsroot] $ cvs -z 3 -d /tmp/cvsroot add addtest1 ! ! The files have been scheduled for addition. ! Should I run `commit' to add the files to the repository (yes|no)? {a} /private/tmp/testdata [/tmp/cvsroot] $ echo "I am addtest2" > addtest2 {a} /private/tmp/testdata [/tmp/cvsroot] *************** *** 195,202 **** {a} /private/tmp/testdata [/tmp/cvsroot] $ cd /private/tmp/testdata ! cvs -z 3 -d /tmp/cvsroot add -m 'sdfasdf' addtest2 ! {a} /private/tmp/testdata [/tmp/cvsroot] ! $ echo === add 3 === ! {a} /private/tmp/testdata [/tmp/cvsroot] $ mkdir dirX {a} /private/tmp/testdata [/tmp/cvsroot] --- 198,207 ---- {a} /private/tmp/testdata [/tmp/cvsroot] $ cd /private/tmp/testdata ! cvs -z 3 -d /tmp/cvsroot add -m 'sdfasdf' addtest2 ! : ! 0 A addtest2 ! ! The files have been scheduled for addition. ! Should I run `commit' to add the files to the repository (yes|no)? {a} /private/tmp/testdata [/tmp/cvsroot] $ mkdir dirX {a} /private/tmp/testdata [/tmp/cvsroot] *************** *** 206,210 **** {a} /private/tmp/testdata [/tmp/cvsroot] $ cvs -z 3 -d /tmp/cvsroot -Q add -m 'sdfa' dirX ! {a} /private/tmp/testdata [/tmp/cvsroot] $ cvs -z 3 -q -d /tmp/cvsroot update -P : --- 211,217 ---- {a} /private/tmp/testdata [/tmp/cvsroot] $ cvs -z 3 -d /tmp/cvsroot -Q add -m 'sdfa' dirX ! ! The files have been scheduled for addition. ! Should I run `commit' to add the files to the repository (yes|no)? {a} /private/tmp/testdata [/tmp/cvsroot] $ cvs -z 3 -q -d /tmp/cvsroot update -P : *************** *** 216,221 **** {a} /private/tmp/testdata [/tmp/cvsroot] $ cd /private/tmp/testdata ! cvs -z 3 -d /tmp/cvsroot -Q add -m 'sdfas' dirX/addtest3 dirX/addtest4 ! {a} /private/tmp/testdata [/tmp/cvsroot] $ cd /private/tmp/testdata cvs -z 3 -d /tmp/cvsroot -Q commit -m 'dummy' --- 223,233 ---- {a} /private/tmp/testdata [/tmp/cvsroot] $ cd /private/tmp/testdata ! cvs -z 3 -d /tmp/cvsroot -Q add -m 'sdfas' dirX/addtest3 dirX/addtest4 ! dirX: ! 0 A addtest3 ! 1 A addtest4 ! ! The files have been scheduled for addition. ! Should I run `commit' to add the files to the repository (yes|no)? {a} /private/tmp/testdata [/tmp/cvsroot] $ cd /private/tmp/testdata cvs -z 3 -d /tmp/cvsroot -Q commit -m 'dummy' Index: run-test.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/testing/run-test.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** run-test.py 10 Mar 2002 23:13:01 -0000 1.1 --- run-test.py 11 Mar 2002 12:02:15 -0000 1.2 *************** *** 33,36 **** --- 33,37 ---- os.system('rm -rf /tmp/testdata /tmp/cvsroot') # little clean-up os.unlink(os.path.join(os.environ['HOME'], '.cvsshellrc')) + os.chdir('/tmp') stdin, stdout, stderr = os.popen3('python %s/../src/cvs_shell.py -v' % thisDir) stdin.write(testcode) *************** *** 45,62 **** print print '======== diff of stdout ========' ! print '< is the reference, > is the current result:' ! os.system('diff %s %s' % (refstdout, logstdout)) if os.path.exists(refstderr): print print '======== diff of stderr ========' ! print '< is the reference, > is the current result:' ! os.system('diff %s %s' % (refstderr, logstderr)) a = raw_input('Should the result be saved as the new reference (yes|no)? ') if a == 'yes': os.rename(logstdout, refstdout) os.rename(logstderr, refstderr) ! if __name__ == '__main__': ! runTest() --- 46,66 ---- print print '======== diff of stdout ========' ! print 'reference, current result:' ! os.system('diff --context %s %s' % (refstdout, logstdout)) if os.path.exists(refstderr): print print '======== diff of stderr ========' ! print 'reference, result:' ! os.system('diff --context %s %s' % (refstderr, logstderr)) a = raw_input('Should the result be saved as the new reference (yes|no)? ') if a == 'yes': os.rename(logstdout, refstdout) os.rename(logstderr, refstderr) ! os.unlink(os.path.join(os.environ['HOME'], '.cvsshellrc')) if __name__ == '__main__': ! if sys.platform[:3] == 'win': ! print "Tests don't run on windows." ! else: ! runTest() Index: testinput =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/testing/testinput,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** testinput 10 Mar 2002 23:13:01 -0000 1.1 --- testinput 11 Mar 2002 12:02:15 -0000 1.2 *************** *** 5,8 **** --- 5,9 ---- echo "You are file test1" > test1 echo "You are file test2" > test2 + echo "You are a file that should by filtered" > I_AM_HERE.pyc mkdir testdir echo "You are file test3" > testdir/test3 *************** *** 67,72 **** --- 68,75 ---- echo "I am addtest4" > dirX/addtest4 add -m 'sdfa' -Q dirX + y update add -m 'sdfas' -Q 2,3 + n commit -Q -m 'dummy' ls |
From: Stefan H. <ste...@us...> - 2002-03-11 12:02:17
|
Update of /cvsroot/cvsshell/cvsshell/src In directory usw-pr-cvs1:/tmp/cvs-serv29583/src Modified Files: cvs_cmds.py cvs_shell.py utils.py Log Message: * added support for filtering the file-listing * add now ask if the files should be added. Index: cvs_cmds.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/cvs_cmds.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** cvs_cmds.py 11 Mar 2002 09:45:51 -0000 1.1 --- cvs_cmds.py 11 Mar 2002 12:02:13 -0000 1.2 *************** *** 74,78 **** try: (globOpts, opts, ! myOpts, rest) = app.parseArgs(args, app.getCmdToAllowedOpts().get(name, '')) except getopt.GetoptError, msg: app.printErr(msg) --- 74,79 ---- try: (globOpts, opts, ! myOpts, rest) = app.parseArgs(args, ! app.getCmdToAllowedOpts().get(name, '')) except getopt.GetoptError, msg: app.printErr(msg) *************** *** 103,107 **** try: (globOpts, opts, ! myOpts, rest) = app.parseArgs(args, app.getCmdToAllowedOpts().get(name, '')) except getopt.GetoptError, msg: app.printErr(msg) --- 104,109 ---- try: (globOpts, opts, ! myOpts, rest) = app.parseArgs(args, ! app.getCmdToAllowedOpts().get(name, '')) except getopt.GetoptError, msg: app.printErr(msg) *************** *** 137,141 **** try: (globOpts, opts, ! myOpts, rest) = app.parseArgs(args, app.getCmdToAllowedOpts().get(name, '')) except getopt.GetoptError, msg: app.printErr(msg) --- 139,144 ---- try: (globOpts, opts, ! myOpts, rest) = app.parseArgs(args, ! app.getCmdToAllowedOpts().get(name, '')) except getopt.GetoptError, msg: app.printErr(msg) *************** *** 147,167 **** def __doIt(e, filename): e.status = Entry.S_ADDED ! return filename try: ! filenames = app.applyOnEntryList(rest, __doIt) try: if filenames: app.runCvsCmd('add', rootDir=app.getListing().getRootDir(), ! globOpts=globOpts, args=opts+' '+string.join(filenames)) ! except CvsError: pass except utils.ParseError: # args do not spefiy ids in the current listing try: app.runCvsCmd('add', globOpts=globOpts, ! args=opts+' '+rest) app.setDirtyListing(1) ! except CvsError: pass except AppError, msg: app.printErr(msg) ! def addBinary(app, name, args): --- 150,191 ---- def __doIt(e, filename): e.status = Entry.S_ADDED ! return (e, filename) ! filenames = '' ! toAddListing = Listing(app, '') try: ! l = app.applyOnEntryList(rest, __doIt) ! entries = [] ! for x in l: ! e,name = x ! filenames += name + ' ' ! entries.append(e) ! toAddListing.setEntries(entries) ! toAddListing.setRootDir(app.getListing().getRootDir()) try: if filenames: app.runCvsCmd('add', rootDir=app.getListing().getRootDir(), ! globOpts=globOpts, ! args=opts+' '+filenames) ! toAddListing.printEntries() ! except CvsError: return except utils.ParseError: # args do not spefiy ids in the current listing + filenames = rest try: app.runCvsCmd('add', globOpts=globOpts, ! args=opts+' '+filenames) app.setDirtyListing(1) ! except CvsError: return except AppError, msg: app.printErr(msg) ! return ! # ! answ = app.prompt("\nThe files have been scheduled for addition.\n" \ ! "Should I run `commit' to add the files " \ ! "to the repository (yes|no)? ") ! if answ == 'yes': ! for e in toAddListing.entries: ! e.status = Entry.S_OK ! app.runCvsCmd('commit', rootDir=toAddListing.getRootDir(), ! fork=0, args=filenames) def addBinary(app, name, args): *************** *** 173,177 **** try: (globOpts, opts, ! myOpts, rest) = app.parseArgs(args, app.getCmdToAllowedOpts().get(name, '')) except getopt.GetoptError, msg: app.printErr(msg) --- 197,202 ---- try: (globOpts, opts, ! myOpts, rest) = app.parseArgs(args, ! app.getCmdToAllowedOpts().get(name, '')) except getopt.GetoptError, msg: app.printErr(msg) *************** *** 199,203 **** if filenames: app.runCvsCmd('commit', rootDir=app.getListing().getRootDir(), ! globOpts=globOpts, args=opts+' '+string.join(filenames), fork=0) except CvsError: pass except utils.ParseError: # args do not spefiy ids in the current listing --- 224,229 ---- if filenames: app.runCvsCmd('commit', rootDir=app.getListing().getRootDir(), ! globOpts=globOpts, ! args=opts+' '+string.join(filenames), fork=0) except CvsError: pass except utils.ParseError: # args do not spefiy ids in the current listing *************** *** 214,218 **** try: (globOpts, opts, ! myOpts, rest) = app.parseArgs(args, app.getCmdToAllowedOpts().get(name, '')) except getopt.GetoptError, msg: app.printErr(msg) --- 240,245 ---- try: (globOpts, opts, ! myOpts, rest) = app.parseArgs(args, ! app.getCmdToAllowedOpts().get(name, '')) except getopt.GetoptError, msg: app.printErr(msg) Index: cvs_shell.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/cvs_shell.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** cvs_shell.py 11 Mar 2002 10:09:50 -0000 1.13 --- cvs_shell.py 11 Mar 2002 12:02:13 -0000 1.14 *************** *** 20,24 **** ############################################################################### ! import os, sys, re, string, types, getopt, utils from oo_tools import GetSetProvider from app import AppError --- 20,24 ---- ############################################################################### ! import os, sys, re, string, types, getopt, fnmatch, utils from oo_tools import GetSetProvider from app import AppError *************** *** 80,85 **** self.readCommandFile() self.readConfigFile() ! def readCvsRootFromFile(self): s = None --- 80,86 ---- self.readCommandFile() self.readConfigFile() ! self.listingFilter = utils.splitquoted(self.configMap.get('filter','')) + def readCvsRootFromFile(self): s = None *************** *** 176,180 **** except (IOError,OSError), msg: self.printMsg(s, nonl=1) ! self.printErr("Error invoking pager `%s': %s" % (pager,str(msg))) --- 177,182 ---- except (IOError,OSError), msg: self.printMsg(s, nonl=1) ! self.printErr("Error invoking pager `%s': %s" % ! (pager,str(msg))) *************** *** 325,330 **** self.app = app self.rootDir = rootDir - self.entries = entries self.sortOrder = ['dir', 'status', 'name'] def sortEntries(self): --- 327,344 ---- self.app = app self.rootDir = rootDir self.sortOrder = ['dir', 'status', 'name'] + filter = app.getListingFilter() + if not filter: + self.entries = entries + else: + self.entries = [] + for e in entries: + dontInclude = 0 + for f in filter: + if fnmatch.fnmatch(e.getName(), f): + dontInclude = 1 + break + if not dontInclude: + self.entries.append(e) def sortEntries(self): Index: utils.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/utils.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** utils.py 10 Mar 2002 23:13:59 -0000 1.8 --- utils.py 11 Mar 2002 12:02:14 -0000 1.9 *************** *** 65,80 **** ! def splitquoted(str): """Splits str on whitespace except when a quoted string is encountered. # Example: splitquotes('foo "foo \"bar\""') => ['foo','"foo \"bar\""'] """ - doubleQ = r'"(?:[^"\\]+|\\.)*"' - singleQ = r"'(?:[^'\\]+|\\.)*'" - splitRE = re.compile(r'(%s|%s|\S+)' % (doubleQ, singleQ)) res = [] for x in splitRE.split(str): x = x.strip() ! if x: res.append(x) # not only whitespace return res --- 65,85 ---- ! doubleQ = r'"(?:[^"\\]+|\\.)*"' ! singleQ = r"'(?:[^'\\]+|\\.)*'" ! splitRE = re.compile(r'(%s|%s|\S+)' % (doubleQ, singleQ)) ! def splitquoted(str, stripQuotes=0): """Splits str on whitespace except when a quoted string is encountered. # Example: splitquotes('foo "foo \"bar\""') => ['foo','"foo \"bar\""'] + If stripQuotes evaluates to true, the quotation marks are removed. """ res = [] + quotes = ['"', "'"] for x in splitRE.split(str): x = x.strip() ! if x: ! if stripQuotes and x[0] in quotes and x[len(x)-1] in quotes: ! x = x[1:len(x)-1] ! res.append(x) # not only whitespace return res |
From: Stefan H. <ste...@us...> - 2002-03-11 12:02:16
|
Update of /cvsroot/cvsshell/cvsshell In directory usw-pr-cvs1:/tmp/cvs-serv29583 Modified Files: install.py Log Message: * added support for filtering the file-listing * add now ask if the files should be added. Index: install.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/install.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** install.py 11 Mar 2002 10:09:49 -0000 1.2 --- install.py 11 Mar 2002 12:02:13 -0000 1.3 *************** *** 45,50 **** def getPrompt(self): if self.targetDir is None: ! return 'Into which directory should I install the shellscript that starts CvsShell?\n' \ ! 'This directory should be included in your $PATH variable.\n$ ' else: # This will be reached on windows only return 'Where can I find the cvs executable (cvs.exe)?\n$ ' --- 45,50 ---- def getPrompt(self): if self.targetDir is None: ! return 'Into which directory should I install the shellscript that starts ' \ ! 'CvsShell?\nThis directory should be included in your $PATH variable.\n$ ' else: # This will be reached on windows only return 'Where can I find the cvs executable (cvs.exe)?\n$ ' *************** *** 95,99 **** launcher = startup self.printMsg("You can launch it by typing `%s' in a terminal window." % launcher) ! if self.onWindows: self.printMsg('You can also click the icon of this file in the explorer.') --- 95,100 ---- launcher = startup self.printMsg("You can launch it by typing `%s' in a terminal window." % launcher) ! if self.onWindows: ! self.printMsg('You can also click the icon of this file in the explorer.') |
From: Stefan H. <ste...@us...> - 2002-03-11 12:02:16
|
Update of /cvsroot/cvsshell/cvsshell/etc In directory usw-pr-cvs1:/tmp/cvs-serv29583/etc Modified Files: default-cvsshellrc Log Message: * added support for filtering the file-listing * add now ask if the files should be added. Index: default-cvsshellrc =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/etc/default-cvsshellrc,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** default-cvsshellrc 10 Mar 2002 23:13:59 -0000 1.4 --- default-cvsshellrc 11 Mar 2002 12:02:13 -0000 1.5 *************** *** 4,8 **** --- 4,13 ---- # Here you can set configuration variables section CONFIG: + pager = more + + # filenames that matches one of these patterns should be excluded + # from the listing as produced by update, refresh or status + filter = *.pyc *~ end |
From: Stefan H. <ste...@us...> - 2002-03-11 10:09:52
|
Update of /cvsroot/cvsshell/cvsshell/src In directory usw-pr-cvs1:/tmp/cvs-serv2904/src Modified Files: app.py cvs_shell.py interactive_app.py Log Message: installation and cvsshell now works on windows! Index: app.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/app.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** app.py 10 Mar 2002 23:13:59 -0000 1.7 --- app.py 11 Mar 2002 10:09:50 -0000 1.8 *************** *** 1,220 **** ! ############################################################################### ! # This file is part of CvsShell ! # ! # CvsShell 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. ! # ! # CvsShell 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 CvsShell; if not, write to the Free Software ! # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! # ! # Copyright 2002 by Stefan Heimann ! # Website: http://cvsshell.sourceforge.net/ ! ############################################################################### ! ! 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.""" ! print "%s, Version %s" % (self.name, self.version) ! 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=[]): ! """ ! This method should be called once before getarg is called. ! opts is a list of key-value pairs. ! The keys are the name of the options that should be ! supported, without the leading `-'. If an ! option expects an argument, the name of the option should be ! followed by a colon. ! The values are the documentation of the option. ! """ ! str = '' ! self._docs = [] ! for x in opts: ! name = x[0] ! doc = x[1] ! str += name ! 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() ! ! ! ############################## ! # script environment services ! ############################## ! ! 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 ! ! 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 ! ! 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 ! ! 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): ! return self.getopt('-v') or self.getopt('--verbose') ! ! def isHelpRequest(self): ! return self.getopt('-h') or self.getopt('--help') ! ! def printVMsg(self, text='', nonl=0): ! if self.isVerbose(): self.printMsg(text, nonl) ! ! 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): ! if message: ! self.printMsg(message) ! sys.exit(status) ! ! def shell(self, command, fork=0, inp=''): ! if self.isVerbose(): ! self.printMsg(command) # how about ipc? ! if not fork: ! os.system(command) # run a shell cmd ! elif fork == 1: ! return os.popen(command, 'r').read() # get its output ! else: # readlines too? ! pipe = os.popen(command, 'w') ! pipe.write(inp) # send it input ! pipe.close() ! return None ! ! def main(self): ! """to run the app ! main() is the start/run/stop execution protocol""" ! if self.isHelpRequest(): ! self.help() ! return 0 ! res = None ! try: ! self.start() ! self.run() ! res = self.stop() # optional return val ! except SystemExit: # ignore if from exit() ! pass ! except: ! self.printErr('========== Traceback starts here ==========') ! self.printErr('uncaught: ' + `(sys.exc_type,sys.exc_value)`) ! traceback.print_exc() ! self.printErr(""" ! Program Version: %s ! Platform: %s ! Python version: %s""" % (self.version, sys.platform, sys.version)) ! self.printErr("========== Traceback ends here ==========\n" \ ! "You have discovered a bug in %s." % self.name) ! if self.bugAddress.find('@') > 0: ! self.printErr("Please send a bug report to \n %s," ! % self.bugAddress) ! else: ! self.printErr("Please fill out a bug report at \n %s," ! % self.bugAddress) ! self.printErr("including the traceback above.") ! self.closeApp() ! return res ! ! def start(self): ! self.printMsg("%s %s" % (self.name, self.version)) ! self.printMsg(self.copyright) ! self.printVMsg(self.name + ' started.') ! def stop(self): ! self.printVMsg(self.name + ' done.') ! def run(self): ! raise AppError, 'run must be redefined!' ! --- 1,232 ---- ! ############################################################################### ! # This file is part of CvsShell ! # ! # CvsShell 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. ! # ! # CvsShell 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 CvsShell; if not, write to the Free Software ! # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! # ! # Copyright 2002 by Stefan Heimann ! # Website: http://cvsshell.sourceforge.net/ ! ############################################################################### ! ! 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.onWindows = sys.platform[:3] == 'win' ! self.THIS_DIR = _thisdir ! try: ! self.HOME = os.environ['HOME'] ! except KeyError: ! if self.onWindows: ! self.HOME = 'c:\\' ! else: ! self.printErr('$HOME is not set.') ! self.HOME = os.getcwd() ! self.name = self.__class__.__name__ ! self.version = '0.1' ! self.copyright = None ! self.bugAddress = None ! try: ! self.path = os.environ['PATH'].split(os.pathsep) ! except KeyError: ! self.path = [] ! 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.""" ! print "%s, Version %s" % (self.name, self.version) ! 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=[]): ! """ ! This method should be called once before getarg is called. ! opts is a list of key-value pairs. ! The keys are the name of the options that should be ! supported, without the leading `-'. If an ! option expects an argument, the name of the option should be ! followed by a colon. ! The values are the documentation of the option. ! """ ! str = '' ! self._docs = [] ! for x in opts: ! name = x[0] ! doc = x[1] ! str += name ! 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() ! ! ! ############################## ! # script environment services ! ############################## ! ! 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 ! ! 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 ! ! 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 ! ! 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): ! return self.getopt('-v') or self.getopt('--verbose') ! ! def isHelpRequest(self): ! return self.getopt('-h') or self.getopt('--help') ! ! def printVMsg(self, text='', nonl=0): ! if self.isVerbose(): self.printMsg(text, nonl) ! ! 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): ! if message: ! self.printMsg(message) ! sys.exit(status) ! ! def shell(self, command, fork=0, inp=''): ! if self.isVerbose(): ! self.printMsg(command) # how about ipc? ! if not fork: ! os.system(command) # run a shell cmd ! elif fork == 1: ! return os.popen(command, 'r').read() # get its output ! else: # readlines too? ! pipe = os.popen(command, 'w') ! pipe.write(inp) # send it input ! pipe.close() ! return None ! ! def main(self): ! """to run the app ! main() is the start/run/stop execution protocol""" ! if self.isHelpRequest(): ! self.help() ! return 0 ! res = None ! try: ! self.start() ! self.run() ! res = self.stop() # optional return val ! except SystemExit: # ignore if from exit() ! pass ! except: ! self.printErr('========== Traceback starts here ==========') ! self.printErr('uncaught: ' + `(sys.exc_type,sys.exc_value)`) ! traceback.print_exc() ! self.printErr(""" ! Program Version: %s ! Platform: %s ! Python version: %s""" % (self.version, sys.platform, sys.version)) ! self.printErr("========== Traceback ends here ==========\n" \ ! "You have discovered a bug in %s." % self.name) ! if self.bugAddress.find('@') > 0: ! self.printErr("Please send a bug report to \n %s," ! % self.bugAddress) ! else: ! self.printErr("Please fill out a bug report at \n %s," ! % self.bugAddress) ! self.printErr("including the traceback above.") ! self.closeApp() ! return res ! ! def start(self): ! self.printMsg("%s %s" % (self.name, self.version)) ! self.printMsg(self.copyright) ! self.printVMsg(self.name + ' started.') ! def stop(self): ! self.printVMsg(self.name + ' done.') ! def run(self): ! raise AppError, 'run must be redefined!' ! Index: cvs_shell.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/cvs_shell.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** cvs_shell.py 10 Mar 2002 23:13:59 -0000 1.12 --- cvs_shell.py 11 Mar 2002 10:09:50 -0000 1.13 *************** *** 1,392 **** ! ############################################################################### ! # This file is part of CvsShell ! # ! # CvsShell 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. ! # ! # CvsShell 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 CvsShell; if not, write to the Free Software ! # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! # ! # Copyright 2002 by Stefan Heimann ! # Website: http://cvsshell.sourceforge.net/ ! ############################################################################### ! ! 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'), ! os.path.join(etcDir, 'default-cvsshellrc')) ! self.setCommandFile(os.path.join(etcDir, 'cvsshell.ini')) ! self.setHistoryFile(os.path.join(self.HOME,'.cvsshell_history')) ! self.initOptions([('v',"Print some extra information"), ! ('h',"Print this help message")]) ! self.CVS_ROOT_FILE = os.path.join('CVS', 'Root') ! 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 ! ( ! \s+ # delimits name and options ! (?P<opts>.*) # the options of the command ! )? # 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 ! if os.access(self.CVS_ROOT_FILE, os.R_OK): ! s = open(self.CVS_ROOT_FILE, 'r').readline().strip() ! return s ! ! ! def getPrompt(self): ! status = '' ! if self.cvsRootAutoUpdate: status += 'a' ! 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 ! extraChars = 6 ! maxLineWidth = 79 ! minLen = 15 ! ls = len(status) ! ld = len(dir) ! lr = len(root) ! width = ls + extraChars + ld + lr ! if width > maxLineWidth: ! w = max(minLen, (lr - (width - maxLineWidth + 3)) / 2) ! if lr > 2*w: root = root[:w] + '...' + root[-w:] ! lr = len(root) ! width = ls + extraChars + ld + lr ! if width > maxLineWidth: ! w = max(minLen, ld - (width - maxLineWidth + 3)) ! if ld > w: dir = '...' + dir[-w:] ! ld = len(dir) ! return "{%s} %s [%s]\n$ " % (status, ! dir, ! root) ! ! ! def evalCommand(self, cmd): ! result = self.cmdRegex.match(cmd) ! if result is None: ! return None ! cmdName = result.group('name') ! cmdOpts = result.group('opts') ! if cmdOpts == None: ! cmdOpts = '' ! cmdOpts = cmdOpts.strip() ! fun = self.getCmdFun(cmdName, CvsShell.execShellCmd) ! return fun(self, cmdName, cmdOpts) ! ! ! def run(self): # FIXME: why must I redefine run here? ! InteractiveApp.run(self) ! ! ! 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 ! ! ! ! if __name__ == '__main__': ! app = CvsShell() ! res = app.main() ! app.exit(res) ! ! --- 1,394 ---- ! ############################################################################### ! # This file is part of CvsShell ! # ! # CvsShell 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. ! # ! # CvsShell 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 CvsShell; if not, write to the Free Software ! # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! # ! # Copyright 2002 by Stefan Heimann ! # Website: http://cvsshell.sourceforge.net/ ! ############################################################################### ! ! 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'), ! os.path.join(etcDir, 'default-cvsshellrc')) ! self.setCommandFile(os.path.join(etcDir, 'cvsshell.ini')) ! self.setHistoryFile(os.path.join(self.HOME,'.cvsshell_history')) ! self.initOptions([('v',"Print some extra information"), ! ('h',"Print this help message")]) ! self.CVS_ROOT_FILE = os.path.join('CVS', 'Root') ! 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 ! ( ! \s+ # delimits name and options ! (?P<opts>.*) # the options of the command ! )? # 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 ! if os.access(self.CVS_ROOT_FILE, os.R_OK): ! s = open(self.CVS_ROOT_FILE, 'r').readline().strip() ! return s ! ! ! def getPrompt(self): ! status = '' ! if self.cvsRootAutoUpdate: status += 'a' ! 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 ! extraChars = 6 ! maxLineWidth = 79 ! minLen = 15 ! ls = len(status) ! ld = len(dir) ! lr = len(root) ! width = ls + extraChars + ld + lr ! if width > maxLineWidth: ! w = max(minLen, (lr - (width - maxLineWidth + 3)) / 2) ! if lr > 2*w: root = root[:w] + '...' + root[-w:] ! lr = len(root) ! width = ls + extraChars + ld + lr ! if width > maxLineWidth: ! w = max(minLen, ld - (width - maxLineWidth + 3)) ! if ld > w: dir = '...' + dir[-w:] ! ld = len(dir) ! return "{%s} %s [%s]\n$ " % (status, ! dir, ! root) ! ! ! def evalCommand(self, cmd): ! result = self.cmdRegex.match(cmd) ! if result is None: ! return None ! cmdName = result.group('name') ! cmdOpts = result.group('opts') ! if cmdOpts == None: ! cmdOpts = '' ! cmdOpts = cmdOpts.strip() ! fun = self.getCmdFun(cmdName, CvsShell.execShellCmd) ! return fun(self, cmdName, cmdOpts) ! ! ! def run(self): # FIXME: why must I redefine run here? ! InteractiveApp.run(self) ! ! ! 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) ! # on windows, cvs seems to output all information on stdout ! if getStderr and not self.onWindows: cmd += ' 2>&1' ! 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 ! ! ! def main(): ! app = CvsShell() ! res = app.main() ! app.exit(res) ! ! if __name__ == '__main__': ! main() Index: interactive_app.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/interactive_app.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** interactive_app.py 10 Mar 2002 23:13:59 -0000 1.5 --- interactive_app.py 11 Mar 2002 10:09:50 -0000 1.6 *************** *** 1,84 **** ! ############################################################################### ! # This file is part of CvsShell ! # ! # CvsShell 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. ! # ! # CvsShell 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 CvsShell; if not, write to the Free Software ! # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! # ! # Copyright 2002 by Stefan Heimann ! # Website: http://cvsshell.sourceforge.net/ ! ############################################################################### ! ! import os ! from app import App, AppError ! ! class InteractiveApp(App): ! ! def __init__(self): ! App.__init__(self) ! self.BREAK_REPL = 'BREAK_REPL' ! try: ! import readline ! except ImportError: ! self.printErr("Could not import readline. History browsing " \ ! "and tab completion will not be available.") ! return ! else: ! readline.parse_and_bind("tab: complete") ! ! def setHistoryFile(self,filename): ! self.historyFile = filename ! try: ! import readline ! except ImportError: return ! try: ! readline.read_history_file(self.historyFile) ! except IOError: ! pass ! import atexit ! atexit.register(readline.write_history_file, self.historyFile) ! ! def run(self): # define App.run here ! while 1: ! command = self.readCommand() ! if command == None: ! break ! result = self.evalCommand(command) ! if result is self.BREAK_REPL: break ! elif result is None: continue ! else: self.printMsg(result) ! ! def readCommand(self): # subclass hooks + App.start,stop ! return self.prompt(self.getPrompt()) ! ! def getPrompt(self): ! return '? ' ! ! 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() ! ! def evalCommand(self, command): ! """Subclasses should override this method. ! If BREAK_REPL is returned, the repl is terminated, ! otherwise the return-value is printed (if not None).""" ! raise AppError, 'evalCommand must be redefined!' ! --- 1,87 ---- ! ############################################################################### ! # This file is part of CvsShell ! # ! # CvsShell 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. ! # ! # CvsShell 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 CvsShell; if not, write to the Free Software ! # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! # ! # Copyright 2002 by Stefan Heimann ! # Website: http://cvsshell.sourceforge.net/ ! ############################################################################### ! ! import os ! from app import App, AppError ! ! class InteractiveApp(App): ! ! def __init__(self): ! App.__init__(self) ! self.BREAK_REPL = 'BREAK_REPL' ! try: ! import readline ! except ImportError: ! self.printErr("Could not import readline.\nHistory browsing " \ ! "and tab completion will not be available.") ! return ! else: ! readline.parse_and_bind("tab: complete") ! ! def setHistoryFile(self,filename): ! self.historyFile = filename ! try: ! import readline ! except ImportError: return ! try: ! readline.read_history_file(self.historyFile) ! except IOError: ! pass ! import atexit ! atexit.register(readline.write_history_file, self.historyFile) ! ! def run(self): # define App.run here ! while 1: ! command = self.readCommand() ! if command == None: ! break ! result = self.evalCommand(command) ! if result is self.BREAK_REPL: break ! elif result is None: continue ! else: self.printMsg(result) ! ! def readCommand(self): # subclass hooks + App.start,stop ! return self.prompt(self.getPrompt()) ! ! def getPrompt(self): ! return '? ' ! ! 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: ! self.printMsg() ! return None ! except KeyboardInterrupt: ! self.printMsg() ! return None ! a = os.path.expandvars(a) ! a = os.path.expanduser(a) ! return a.strip() ! ! def evalCommand(self, command): ! """Subclasses should override this method. ! If BREAK_REPL is returned, the repl is terminated, ! otherwise the return-value is printed (if not None).""" ! raise AppError, 'evalCommand must be redefined!' ! |
From: Stefan H. <ste...@us...> - 2002-03-11 10:09:52
|
Update of /cvsroot/cvsshell/cvsshell In directory usw-pr-cvs1:/tmp/cvs-serv2904 Modified Files: install.py Log Message: installation and cvsshell now works on windows! Index: install.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/install.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** install.py 10 Mar 2002 23:11:07 -0000 1.1 --- install.py 11 Mar 2002 10:09:49 -0000 1.2 *************** *** 1,103 **** ! #!/usr/bin/env python ! ! ############################################################################### ! # This file is part of CvsShell ! # ! # CvsShell 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. ! # ! # CvsShell 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 CvsShell; if not, write to the Free Software ! # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! # ! # Copyright 2002 by Stefan Heimann ! # Website: http://cvsshell.sourceforge.net/ ! ############################################################################### ! ! import sys, os, time ! ! thisDir = os.path.join(os.getcwd(), sys.path[0]) ! sys.path.insert(1, os.path.join(thisDir, 'src')) ! from interactive_app import InteractiveApp ! from cvs_shell import NAME, VERSION, COPYRIGHT, BUG_ADDRESS ! ! ! unixStartScript = """#!/usr/bin/env sh ! ! # automatically generated on %s ! /usr/bin/env python %s "$@" ! """ % (time.ctime(time.time()), os.path.join(thisDir, 'src', 'cvs_shell.py')) ! ! class Installation(InteractiveApp): ! ! def __init__(self): ! InteractiveApp.__init__(self) ! self.setName(NAME + ' Installation Procedure') ! self.setVersion(VERSION) ! self.setCopyright(COPYRIGHT) ! self.setBugAddress(BUG_ADDRESS) ! self.targetDir = None ! self.initOptions('') ! self.onWindows = sys.platform[:3] == 'win' ! try: ! self.path = os.environ['PATH'].split(os.pathsep) ! except KeyError: ! self.path = [] ! ! ! def getPrompt(self): ! return 'Into which directory should I install the shellscript that starts CvsShell?\n' \ ! 'This directory should be included in your $PATH variable.\n$ ' ! ! ! def evalCommand(self, cmd): ! if os.path.isdir(cmd): ! if not self.inPath(cmd): ! self.printMsg('The directory is not included in your $PATH variable.') ! if raw_input('Are you sure (yes|no)? ') != 'yes': return ! self.targetDir = cmd ! return self.BREAK_REPL ! else: return 'Not a valid directory.' ! ! ! def start(self): ! InteractiveApp.start(self) ! if self.onWindows: ! self.exit("Windows is currently not supported. I am working on it.") ! ! ! def inPath(self, dir): ! return dir in self.path ! ! ! def stop(self): ! failureMsg = 'CvsShell was not successfully installed.' ! global unixStartScript ! if self.targetDir is None: ! self.printMsg(failureMsg) ! return ! startup = os.path.join(self.targetDir, 'cvsshell') ! try: ! open(startup, 'w').write(unixStartScript) ! os.chmod(startup, 0775) ! except (IOError, OSError), msg: ! self.exit(str(msg) + '\n' + failureMsg) ! self.printMsg('CvsShell was successfully installed.') ! if self.inPath(self.targetDir): ! launcher = os.path.basename(startup) ! else: ! launcer = startup ! self.printMsg("You can launch it by typing `%s' in a terminal window" % launcher) ! ! ! ! if __name__ == '__main__': ! i = Installation() ! i.main() --- 1,131 ---- ! #!/usr/bin/env python ! ! ############################################################################### ! # This file is part of CvsShell ! # ! # CvsShell 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. ! # ! # CvsShell 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 CvsShell; if not, write to the Free Software ! # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! # ! # Copyright 2002 by Stefan Heimann ! # Website: http://cvsshell.sourceforge.net/ ! ############################################################################### ! ! import sys, os, time ! ! thisDir = os.path.join(os.getcwd(), sys.path[0]) ! sys.path.insert(1, os.path.join(thisDir, 'src')) ! from interactive_app import InteractiveApp ! from cvs_shell import NAME, VERSION, COPYRIGHT, BUG_ADDRESS ! ! ! class Installation(InteractiveApp): ! ! def __init__(self): ! InteractiveApp.__init__(self) ! self.setName(NAME + ' Installation Procedure') ! self.setVersion(VERSION) ! self.setCopyright(COPYRIGHT) ! self.setBugAddress(BUG_ADDRESS) ! self.targetDir = None ! self.cvsDir = None ! self.initOptions('') ! ! ! def getPrompt(self): ! if self.targetDir is None: ! return 'Into which directory should I install the shellscript that starts CvsShell?\n' \ ! 'This directory should be included in your $PATH variable.\n$ ' ! else: # This will be reached on windows only ! return 'Where can I find the cvs executable (cvs.exe)?\n$ ' ! ! ! def evalCommand(self, cmd): ! if os.path.isdir(cmd): ! if self.targetDir is None: ! if not self.inPath(cmd): ! self.printMsg('The directory is not included in your $PATH variable.') ! if raw_input('Are you sure (yes|no)? ') != 'yes': return ! self.targetDir = cmd ! if not self.onWindows: return self.BREAK_REPL ! else: # only reachable on windows ! if os.path.exists(os.path.join(cmd, 'cvs.exe')): ! self.cvsDir = cmd ! return self.BREAK_REPL ! else: return 'cvs.exe does not exist in this directory.' ! else: return 'Not a valid directory.' ! ! ! def start(self): ! InteractiveApp.start(self) ! if self.onWindows: ! pass #self.exit("Windows is currently not supported. I am working on it.") ! ! ! def inPath(self, dir): ! return dir in self.path ! ! ! def stop(self): ! failureMsg = 'CvsShell was not successfully installed.' ! global unixStartScript ! if self.targetDir is None: ! self.printMsg(failureMsg) ! return ! startup, content = self.createStartScript() ! try: ! open(startup, 'w').write(content) ! os.chmod(startup, 0775) ! except (IOError, OSError), msg: ! self.exit(str(msg) + '\n' + failureMsg) ! self.printMsg('CvsShell was successfully installed.') ! if self.inPath(self.targetDir): ! launcher = os.path.basename(startup) ! else: ! launcher = startup ! self.printMsg("You can launch it by typing `%s' in a terminal window." % launcher) ! if self.onWindows: self.printMsg('You can also click the icon of this file in the explorer.') ! ! ! def createStartScript(self): ! if self.onWindows: return self.createWindowsStartScript() ! else: return self.createUnixStartScript() ! ! ! def createWindowsStartScript(self): ! return (os.path.join(self.targetDir, 'cvsshell.py'), """ ! import os, sys ! ! # Setting up PATH for cvs ! path = os.environ.get('PATH','') ! path = '%s;'+path ! os.environ['PATH'] = path ! ! sys.path.insert(0, '%s') ! import cvs_shell ! cvs_shell.main() ! raw_input() ! """ % (self.cvsDir, os.path.join(self.THIS_DIR, 'src'))) ! ! def createUnixStartScript(self): ! return (os.path.join(self.targetDir, 'cvsshell'), """#!/usr/bin/env sh ! ! # automatically generated on %s ! /usr/bin/env python %s "$@" ! """ % (time.ctime(time.time()), os.path.join(thisDir, 'src', 'cvs_shell.py'))) ! ! ! if __name__ == '__main__': ! i = Installation() ! i.main() ! if i.onWindows: raw_input() |
From: Stefan H. <ste...@us...> - 2002-03-11 09:50:44
|
Update of /cvsroot/cvsshell/cvsshell/src In directory usw-pr-cvs1:/tmp/cvs-serv31258/src Added Files: parsing.py Log Message: initial checkin --- NEW FILE: parsing.py --- ############################################################################### # This file is part of CvsShell # # CvsShell 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. # # CvsShell 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 CvsShell; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Copyright 2002 by Stefan Heimann # Website: http://cvsshell.sourceforge.net/ ############################################################################### import getopt ############################## # Parsing functions ############################## def parseCvsRootSection(lines, app): roots = app.getCvsRootAliases() for x in lines: n = x[0] l = app.keyValSplitRE.split(x[1]) if len(l) != 2: app.printErr("Syntax error in configuration file (line %d)." % n) else: roots[l[0]] = l[1] def parseInitCmdsSection(lines, app): for x in lines: cmd = x[1] app.evalCommand(cmd) def parseDefaultOptions(lines, app): for x in lines: n = x[0] l = app.keysValSplitRE.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) = app.parseArgs(value, app.getCmdToAllowedOpts().get(y,'')) app.cmdToDefOpts[y] = opt app.cmdToDefGlobOpts[y] = globOpt else: (globOpt, opt, du1, du2) = app.parseArgs(value) app.defOpts = opt app.defGlobOpts = 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" \ + `app.cmdToDefGlobOpts` + \ "\nDefault options:\n" \ + `app.cmdToDefOpts` + \ "\nDefault global options for all cmds:\n" \ + `app.defOpts` + \ "\nDefault options for all cmds:\n" \ + `app.defGlobOpts`) def parseConfigSection(lines, app): for x in lines: n = x[0] l = app.keyValSplitRE.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 |
From: Stefan H. <ste...@us...> - 2002-03-11 09:45:54
|
Update of /cvsroot/cvsshell/cvsshell/src In directory usw-pr-cvs1:/tmp/cvs-serv29992/src Added Files: cvs_cmds.py Log Message: initial checkin --- NEW FILE: cvs_cmds.py --- ############################################################################### # This file is part of CvsShell # # CvsShell 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. # # CvsShell 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 CvsShell; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Copyright 2002 by Stefan Heimann # Website: http://cvsshell.sourceforge.net/ ############################################################################### import os, re, string, getopt, utils from cvs_shell import CvsShell, Listing, Entry, CvsError, InternalCvsError from app import AppError ############################## # CVS commands ############################## def status(app, name, args): 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) = app.parseArgs(args, app.getCmdToAllowedOpts().get(name, '')) except getopt.GetoptError, msg: app.printErr(msg) return try: lines = app.runCvsCmd('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(Entry(dir, name, 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(Entry(dir, name, status)) continue dirRes = regexDir.search(line) if dirRes: dir = dirRes.group('dir') if dir == '.': dir = '' app.setListing(Listing(app, os.getcwd(), entries)) app.setDirtyListing(0) app.getListing().sortEntries() app.printListing() def update(app, args, name, simulate=0): try: (globOpts, opts, myOpts, rest) = app.parseArgs(args, app.getCmdToAllowedOpts().get(name, '')) except getopt.GetoptError, msg: app.printErr(msg) return if simulate: globOpts += '-n' try: lines = app.runCvsCmd('update', globOpts=globOpts, args=opts) except CvsError: return entries = [] for line in lines: x = line.split() if len(x) < 2 or x[0] == 'cvs': continue status = x[0] name = os.path.basename(x[1]) dir = os.path.dirname(x[1]) entries.append(Entry(dir, name, status)) app.setListing(Listing(app, os.getcwd(), entries)) app.setDirtyListing(0) app.getListing().sortEntries() app.printListing() def simulateUpdate(app, name, args): update(app, name, args, simulate=1) def checkout(app, name, args): try: (globOpts, opts, myOpts, rest) = app.parseArgs(args, app.getCmdToAllowedOpts().get(name, '')) except getopt.GetoptError, msg: app.printErr(msg) return rest = rest.split() n = len(rest) cvsRoot = app.getCvsRoot() if cvsRoot is None: if n < 1: setCvsRoot(app, '', '') cvsRoot = app.getCvsRoot() else: cvsRoot = app.getCvsRootAliases().get(rest[0], rest[0]) if n < 2: module = app.prompt('enter name of module: ') if module is None: return else: module = rest[1] else: if n < 1: module = app.prompt('enter name of module: ') if module is None: return else: module = rest[0] try: app.runCvsCmd('checkout', cvsRoot=cvsRoot, globOpts=globOpts, args=opts+' '+module) except CvsError: pass app.setDirtyListing(1) def add(app, name, args, isBinary=0): try: (globOpts, opts, myOpts, rest) = app.parseArgs(args, app.getCmdToAllowedOpts().get(name, '')) except getopt.GetoptError, msg: app.printErr(msg) return if isBinary: opts += '-kb' if not rest: rest = app.prompt('enter filenumbers/filenames to add: ') if rest is None: return def __doIt(e, filename): e.status = Entry.S_ADDED return filename try: filenames = app.applyOnEntryList(rest, __doIt) try: if filenames: app.runCvsCmd('add', rootDir=app.getListing().getRootDir(), globOpts=globOpts, args=opts+' '+string.join(filenames)) except CvsError: pass except utils.ParseError: # args do not spefiy ids in the current listing try: app.runCvsCmd('add', globOpts=globOpts, args=opts+' '+rest) app.setDirtyListing(1) except CvsError: pass except AppError, msg: app.printErr(msg) def addBinary(app, name, args): app.printMsg('The file will be added in binary mode.') add(app, name, args, isBinary=1) def commit(app, name, args): try: (globOpts, opts, myOpts, rest) = app.parseArgs(args, app.getCmdToAllowedOpts().get(name, '')) except getopt.GetoptError, msg: app.printErr(msg) return if not rest: # commit without an argument try: if not app.getListing(): rootDir = '' else: rootDir = app.getListing().getRootDir() app.runCvsCmd('commit', rootDir=rootDir, globOpts=globOpts, args=opts, fork=0) app.setDirtyListing(1) except CvsError: pass return def __doIt(e,filename): if e.status == Entry.S_REMOVED: e.status = Entry.S_DELETED else: e.status = Entry.S_OK return filename try: filenames = app.applyOnEntryList(rest, __doIt) try: if filenames: app.runCvsCmd('commit', rootDir=app.getListing().getRootDir(), globOpts=globOpts, args=opts+' '+string.join(filenames), fork=0) except CvsError: pass except utils.ParseError: # args do not spefiy ids in the current listing try: app.runCvsCmd('commit', globOpts=globOpts, args=opts+' '+rest, fork=0) app.setDirtyListing(1) except CvsError: pass except AppError, msg: app.printErr(msg) def remove(app, name, args): try: (globOpts, opts, myOpts, rest) = app.parseArgs(args, app.getCmdToAllowedOpts().get(name, '')) except getopt.GetoptError, msg: app.printErr(msg) return if not rest: rest = app.prompt('enter filenumbers/filenames to remove: ') if rest is None: return def __doIt(e,filename): return e filenames = [] toDeleteListing = Listing(app, '') try: toDeleteListing.setEntries(app.applyOnEntryList(rest, __doIt)) toDeleteListing.setRootDir(app.getListing().getRootDir()) for e in toDeleteListing.entries: name = os.path.join(toDeleteListing.rootDir, e.dir, e.name) print name if os.path.isdir(name): app.printMsg("Refusing the delete a directory: %s" % name) continue 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 = Entry.S_REMOVED except utils.ParseError: # args do not specify ids in the current listing fs = utils.splitquoted(rest) for name in fs: if os.path.isdir(name): app.printMsg("Refusing the delete a directory: %s" % name) continue try: os.unlink(name) except OSError, msg: app.printErr(msg) # Hope that the file already has been removed filenames.append(name) except AppError, msg: app.printErr(msg) return if filenames: args = string.join(filenames) try: app.runCvsCmd('remove', rootDir=toDeleteListing.getRootDir(), globOpts=globOpts, args=opts+' '+args) except CvsError: return toDeleteListing.printEntries(verbose=0) 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 toDeleteListing.entries: e.status = Entry.S_DELETED app.runCvsCmd('commit', rootDir=toDeleteListing.getRootDir(), fork=0, args=args) def printListing(app, name, args): app.printListing() def setCvsRoot(app, name, args): "Sets the cvsroot variable manually." roots = app.getCvsRootAliases() 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 newRoot is None: return if roots.has_key(newRoot): newRoot = roots[newRoot] else: a = app.prompt("You can specify an alias for the cvsroot: ") if a: roots[a] = newRoot app.appendToSection('CVSROOT', ['%s = %s' % (a, newRoot)]) if newRoot is not None: app.setCvsRoot(newRoot) def readCvsRoot(app, name, args): "Reads the cvsroot variable from CVS/Root." newRoot = app.readCvsRootFromFile() if newRoot == None: app.printErr('Could not read CVSROOT from file.') else: app.setCvsRoot(newRoot) def clearCvsRoot(app, name, args): "Unsets the cvsroot variable." app.setCvsRoot(None) def toggleCvsRootAutoUpdate(app, name, args): """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.cvsRootAutoUpdate = app.toggle(app.cvsRootAutoUpdate, args) if app.cvsRootAutoUpdate: newRoot = app.readCvsRootFromFile() if newRoot is not None: app.setCvsRoot(newRoot) def toggleFullPrompt(app, name, args): app.showFullPrompt = app.toggle(app.showFullPrompt, args) |
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] |
From: Stefan H. <ste...@us...> - 2002-03-10 23:14:02
|
Update of /cvsroot/cvsshell/cvsshell/etc In directory usw-pr-cvs1:/tmp/cvs-serv25500/etc Modified Files: cvsshell.ini default-cvsshellrc Log Message: * refactoring * many small improvements Index: cvsshell.ini =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/etc/cvsshell.ini,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** cvsshell.ini 9 Mar 2002 10:56:20 -0000 1.3 --- cvsshell.ini 10 Mar 2002 23:13:59 -0000 1.4 *************** *** 3,18 **** ?, help = basic_cmds.cmdHelp cd = basic_cmds.changeDir ! up, upd, update = basic_cmds.update ! refresh = basic_cmds.simulateUpdate ! sr,set-root = basic_cmds.setCvsRoot ! rr,read-root = basic_cmds.readCvsRoot ! cr,clear-root = basic_cmds.clearCvsRoot ! list = basic_cmds.printListing ! ad, add, new = basic_cmds.add ! ci, com, commit = basic_cmds.commit ! delete, remove = basic_cmds.remove ! co, get, checkout = basic_cmds.checkout ! st, stat, status = basic_cmds.status ! auto = basic_cmds.toggleCvsRootAutoUpdate end --- 3,18 ---- ?, help = basic_cmds.cmdHelp cd = basic_cmds.changeDir ! up, upd, update = cvs_cmds.update ! refresh = cvs_cmds.simulateUpdate ! sr,set-root = cvs_cmds.setCvsRoot ! rr,read-root = cvs_cmds.readCvsRoot ! cr,clear-root = cvs_cmds.clearCvsRoot ! list = cvs_cmds.printListing ! ad, add, new = cvs_cmds.add ! ci, com, commit = cvs_cmds.commit ! delete, remove = cvs_cmds.remove ! co, get, checkout = cvs_cmds.checkout ! st, stat, status = cvs_cmds.status ! auto = cvs_cmds.toggleCvsRootAutoUpdate end *************** *** 27,33 **** section PARSERS: ! INIT_CMDS = basic_cmds.parseInitCmdsSection ! CVSROOT = basic_cmds.parseCvsRootSection ! DEFAULT_CMD_OPTIONS = basic_cmds.parseDefaultOptions ! CONFIG = basic_cmds.parseConfigSection end --- 27,33 ---- section PARSERS: ! INIT_CMDS = parsing.parseInitCmdsSection ! CVSROOT = parsing.parseCvsRootSection ! DEFAULT_CMD_OPTIONS = parsing.parseDefaultOptions ! CONFIG = parsing.parseConfigSection end Index: default-cvsshellrc =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/etc/default-cvsshellrc,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** default-cvsshellrc 9 Mar 2002 10:56:20 -0000 1.3 --- default-cvsshellrc 10 Mar 2002 23:13:59 -0000 1.4 *************** *** 4,8 **** # Here you can set configuration variables section CONFIG: ! pager = less end --- 4,8 ---- # Here you can set configuration variables section CONFIG: ! pager = more end *************** *** 15,23 **** # Format: option1, option2 = options # You can use the keyword `ALL' to apply options to all commands ! # Note: You have to specify the options for every synonym of a command, too. ! section DEFAULT_CMD_OPTIONS: ALL = -z 3 ! up, upd, update = -q -P ! co, get, checkout = -q end --- 15,25 ---- # Format: option1, option2 = options # You can use the keyword `ALL' to apply options to all commands ! # You can specify different options for synonyms of a command. ! # Note: DON'T specify the option `-q' or `-Q' for the commands `st', ! # `stat', `status' or `ALL'. The options suppress information that are ! # needed by these commands. ! section DEFAULT_CMD_OPTIONS: ALL = -z 3 ! up, upd, update = -q -P end |
From: Stefan H. <ste...@us...> - 2002-03-10 23:13:04
|
Update of /cvsroot/cvsshell/cvsshell/testing In directory usw-pr-cvs1:/tmp/cvs-serv25208/testing Added Files: refstderr refstdout run-test.py testinput Log Message: testcases --- NEW FILE: refstderr --- cvs import: Importing /tmp/cvsroot/testdata/testdir cvs checkout: Updating testdata cvs checkout: Updating testdata/testdir cvs checkout: Updating testdata cvs checkout: Updating testdata/testdir cvs checkout: Updating testdata cvs checkout: Updating testdata/testdir cvs checkout: Updating testdata cvs checkout: Updating testdata/testdir cvs add: scheduling file `addtest1' for addition cvs add: use 'cvs commit' to add this file permanently cvs add: scheduling file `addtest2' for addition cvs add: use 'cvs commit' to add this file permanently cvs add: use 'cvs commit' to add these files permanently cvs remove: scheduling `test2' for removal cvs remove: use 'cvs commit' to remove this file permanently cvs remove: scheduling `addtest2' for removal cvs remove: use 'cvs commit' to remove this file permanently --- NEW FILE: refstdout --- ====== Creating testdata ======== ====== initializing the repository ====== ====== importing the testdata ====== N testdata/test1 N testdata/test2 N testdata/testdir/test3 No conflicts created by this import ====== testing checkout, set-root and clear-root ====== === checkout 1 === === checkout 2 === === checkout 3 === === checkout 4 === ====== Testing commit ====== === commit 1 === Checking in test1; /tmp/cvsroot/testdata/test1,v <-- test1 new revision: 1.2; previous revision: 1.1 done === commit 2 === Checking in test1; /tmp/cvsroot/testdata/test1,v <-- test1 new revision: 1.3; previous revision: 1.2 done ====== Testing add ====== === add 1 === === add 2 === === add 3 === RCS file: /tmp/cvsroot/testdata/addtest1,v done Checking in addtest1; /tmp/cvsroot/testdata/addtest1,v <-- addtest1 initial revision: 1.1 done RCS file: /tmp/cvsroot/testdata/addtest2,v done Checking in addtest2; /tmp/cvsroot/testdata/addtest2,v <-- addtest2 initial revision: 1.1 done RCS file: /tmp/cvsroot/testdata/dirX/addtest3,v done Checking in dirX/addtest3; /tmp/cvsroot/testdata/dirX/addtest3,v <-- addtest3 initial revision: 1.1 done RCS file: /tmp/cvsroot/testdata/dirX/addtest4,v done Checking in dirX/addtest4; /tmp/cvsroot/testdata/dirX/addtest4,v <-- addtest4 initial revision: 1.1 done CVS addtest1 addtest2 dirX test1 test2 testdir ====== Testing remove ====== CVS addtest1 dirX test1 testdir Default global options: {'upd': '-q', 'up': '-q', 'update': '-q'} Default options: {'upd': '-P', 'up': '-P', 'update': '-P'} Default global options for all cmds: '' Default options for all cmds: '-z 3' CvsShell 0.1 Copyright 2002 Stefan Heimann (ma...@st...). This software is released under the GPL. CvsShell started. {a} ~/cvsshell/testing [--] $ cd /tmp {a} /private/tmp [--] $ echo ====== Creating testdata ======== {a} /private/tmp [--] $ mkdir testdata {a} /private/tmp [--] $ cd testdata {a} /private/tmp/testdata [--] $ echo "You are file test1" > test1 {a} /private/tmp/testdata [--] $ echo "You are file test2" > test2 {a} /private/tmp/testdata [--] $ mkdir testdir {a} /private/tmp/testdata [--] $ echo "You are file test3" > testdir/test3 {a} /private/tmp/testdata [--] $ cd .. {a} /private/tmp [--] $ {a} /private/tmp [--] $ echo ====== initializing the repository ====== {a} /private/tmp [--] $ cvs -d /tmp/cvsroot init {a} /private/tmp [--] $ {a} /private/tmp [--] $ echo ====== importing the testdata ====== {a} /private/tmp [--] $ cd testdata {a} /private/tmp/testdata [--] $ cvs -d /tmp/cvsroot import -m "testdata" testdata stefan start {a} /private/tmp/testdata [--] $ cd .. {a} /private/tmp [--] $ rm -r testdata {a} /private/tmp [--] $ {a} /private/tmp [--] $ echo ====== testing checkout, set-root and clear-root ====== {a} /private/tmp [--] $ {a} /private/tmp [--] $ echo === checkout 1 === {a} /private/tmp [--] $ {a} /private/tmp [--] $ Aliases: enter new cvsroot: You can specify an alias for the cvsroot: enter name of module: cvs -z 3 -d /tmp/cvsroot checkout testdata {a} /private/tmp [/tmp/cvsroot] $ {a} /private/tmp [/tmp/cvsroot] $ cd testdata {a} /private/tmp/testdata [/tmp/cvsroot] $ cd .. {a} /private/tmp [/tmp/cvsroot] $ rm -r testdata {a} /private/tmp [/tmp/cvsroot] $ {a} /private/tmp [/tmp/cvsroot] $ echo === checkout 2 === {a} /private/tmp [/tmp/cvsroot] $ enter name of module: cvs -z 3 -d /tmp/cvsroot checkout testdata {a} /private/tmp [/tmp/cvsroot] $ cd testdata {a} /private/tmp/testdata [/tmp/cvsroot] $ cd .. {a} /private/tmp [/tmp/cvsroot] $ rm -r testdata {a} /private/tmp [/tmp/cvsroot] $ echo === checkout 3 === {a} /private/tmp [/tmp/cvsroot] $ cvs -z 3 -d /tmp/cvsroot checkout testdata {a} /private/tmp [/tmp/cvsroot] $ cd testdata {a} /private/tmp/testdata [/tmp/cvsroot] $ cd .. {a} /private/tmp [/tmp/cvsroot] $ rm -r testdata {a} /private/tmp [/tmp/cvsroot] $ {a} /private/tmp [--] $ echo === checkout 4 === {a} /private/tmp [--] $ cvs -z 3 -d /tmp/cvsroot checkout testdata {a} /private/tmp [--] $ cd testdata {a} /private/tmp/testdata [/tmp/cvsroot] $ echo ====== Testing commit ====== {a} /private/tmp/testdata [/tmp/cvsroot] $ echo === commit 1 === {a} /private/tmp/testdata [/tmp/cvsroot] $ echo " changed" >> test1 {a} /private/tmp/testdata [/tmp/cvsroot] $ cvs -z 3 -q -d /tmp/cvsroot -n update -P : 0 M test1 {a} /private/tmp/testdata [/tmp/cvsroot] $ cd /private/tmp/testdata cvs -z 3 -d /tmp/cvsroot commit -m 'this file was changed for testing' test1 cd /private/tmp/testdata {a} /private/tmp/testdata [/tmp/cvsroot] $ echo === commit 2 === {a} /private/tmp/testdata [/tmp/cvsroot] $ echo " changed" >> test1 {a} /private/tmp/testdata [/tmp/cvsroot] $ cvs -z 3 -d /tmp/cvsroot commit -m 'this file was changed for testing' test1 {a} /private/tmp/testdata [/tmp/cvsroot] $ echo ====== Testing add ====== {a} /private/tmp/testdata [/tmp/cvsroot] $ echo === add 1 === {a} /private/tmp/testdata [/tmp/cvsroot] $ echo "I am addtest1" > addtest1 {a} /private/tmp/testdata [/tmp/cvsroot] $ cvs -z 3 -d /tmp/cvsroot add addtest1 {a} /private/tmp/testdata [/tmp/cvsroot] $ echo === add 2 === {a} /private/tmp/testdata [/tmp/cvsroot] $ echo "I am addtest2" > addtest2 {a} /private/tmp/testdata [/tmp/cvsroot] $ cvs -z 3 -q -d /tmp/cvsroot -n update -P : 0 A addtest1 1 ? addtest2 {a} /private/tmp/testdata [/tmp/cvsroot] $ cd /private/tmp/testdata cvs -z 3 -d /tmp/cvsroot add -m 'sdfasdf' addtest2 {a} /private/tmp/testdata [/tmp/cvsroot] $ echo === add 3 === {a} /private/tmp/testdata [/tmp/cvsroot] $ mkdir dirX {a} /private/tmp/testdata [/tmp/cvsroot] $ echo "I am addtest3" > dirX/addtest3 {a} /private/tmp/testdata [/tmp/cvsroot] $ echo "I am addtest4" > dirX/addtest4 {a} /private/tmp/testdata [/tmp/cvsroot] $ cvs -z 3 -d /tmp/cvsroot -Q add -m 'sdfa' dirX {a} /private/tmp/testdata [/tmp/cvsroot] $ cvs -z 3 -q -d /tmp/cvsroot update -P : 0 A addtest1 1 A addtest2 dirX: 2 ? addtest3 3 ? addtest4 {a} /private/tmp/testdata [/tmp/cvsroot] $ cd /private/tmp/testdata cvs -z 3 -d /tmp/cvsroot -Q add -m 'sdfas' dirX/addtest3 dirX/addtest4 {a} /private/tmp/testdata [/tmp/cvsroot] $ cd /private/tmp/testdata cvs -z 3 -d /tmp/cvsroot -Q commit -m 'dummy' cd /private/tmp/testdata {a} /private/tmp/testdata [/tmp/cvsroot] $ ls {a} /private/tmp/testdata [/tmp/cvsroot] $ echo ====== Testing remove ====== {a} /private/tmp/testdata [/tmp/cvsroot] $ cvs -z 3 -d /tmp/cvsroot status 2>&1 : 0 Up-to-date addtest1 1 Up-to-date addtest2 2 Up-to-date test1 3 Up-to-date test2 dirX: 4 Up-to-date addtest3 5 Up-to-date addtest4 testdir: 6 Up-to-date test3 {a} /private/tmp/testdata [/tmp/cvsroot] $ /private/tmp/testdata/test2 cd /private/tmp/testdata cvs -z 3 -d /tmp/cvsroot remove test2 : 0 R test2 The files have been scheduled for removal. Should I run `commit' to remove the files permanently (yes|no)? {a} /private/tmp/testdata [/tmp/cvsroot] $ cvs -z 3 -d /tmp/cvsroot remove addtest2 The files have been scheduled for removal. Should I run `commit' to remove the files permanently (yes|no)? {a} /private/tmp/testdata [/tmp/cvsroot] $ {a} /private/tmp/testdata [/tmp/cvsroot] $ Refusing the delete a directory: dirX {a} /private/tmp/testdata [/tmp/cvsroot] $ ls {a} /private/tmp/testdata [/tmp/cvsroot] $ cd /Users/stefan {a} ~ [/tmp/cvsroot] $ rm -rf /tmp/testdata /tmp/cvsroot {a} ~ [/tmp/cvsroot] $ CvsShell done. --- NEW FILE: run-test.py --- #!/usr/bin/env python ############################################################################### # This file is part of CvsShell # # CvsShell 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. # # CvsShell 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 CvsShell; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Copyright 2002 by Stefan Heimann # Website: http://cvsshell.sourceforge.net/ ############################################################################### import sys, os, tempfile thisDir = os.path.join(os.getcwd(), sys.path[0]) def runTest(): global thisDir refstdout = thisDir + '/refstdout' refstderr = thisDir + '/refstderr' testcode = open(thisDir + '/testinput').read() os.system('rm -rf /tmp/testdata /tmp/cvsroot') # little clean-up os.unlink(os.path.join(os.environ['HOME'], '.cvsshellrc')) stdin, stdout, stderr = os.popen3('python %s/../src/cvs_shell.py -v' % thisDir) stdin.write(testcode) stdin.close() logstdout = tempfile.mktemp() logstderr = tempfile.mktemp() open(logstdout,'w').write(stdout.read()) stdout.close() open(logstderr,'w').write(stderr.read()) stderr.close() if os.path.exists(refstdout): print print '======== diff of stdout ========' print '< is the reference, > is the current result:' os.system('diff %s %s' % (refstdout, logstdout)) if os.path.exists(refstderr): print print '======== diff of stderr ========' print '< is the reference, > is the current result:' os.system('diff %s %s' % (refstderr, logstderr)) a = raw_input('Should the result be saved as the new reference (yes|no)? ') if a == 'yes': os.rename(logstdout, refstdout) os.rename(logstderr, refstderr) if __name__ == '__main__': runTest() --- NEW FILE: testinput --- cd /tmp echo ====== Creating testdata ======== mkdir testdata cd testdata echo "You are file test1" > test1 echo "You are file test2" > test2 mkdir testdir echo "You are file test3" > testdir/test3 cd .. echo ====== initializing the repository ====== cvs -d /tmp/cvsroot init echo ====== importing the testdata ====== cd testdata cvs -d /tmp/cvsroot import -m "testdata" testdata stefan start cd .. rm -r testdata echo ====== testing checkout, set-root and clear-root ====== # !! checkout prompts for alias !! echo === checkout 1 === clear-root checkout /tmp/cvsroot testalias testdata cd testdata cd .. rm -r testdata set-root testalias echo === checkout 2 === checkout testdata cd testdata cd .. rm -r testdata echo === checkout 3 === checkout testdata cd testdata cd .. rm -r testdata clear-root echo === checkout 4 === checkout testalias testdata cd testdata echo ====== Testing commit ====== echo === commit 1 === echo " changed" >> test1 refresh commit -m 'this file was changed for testing' 0 echo === commit 2 === echo " changed" >> test1 commit -m 'this file was changed for testing' test1 echo ====== Testing add ====== echo === add 1 === echo "I am addtest1" > addtest1 add addtest1 echo === add 2 === echo "I am addtest2" > addtest2 refresh add -m 'sdfasdf' 1 echo === add 3 === mkdir dirX echo "I am addtest3" > dirX/addtest3 echo "I am addtest4" > dirX/addtest4 add -m 'sdfa' -Q dirX update add -m 'sdfas' -Q 2,3 commit -Q -m 'dummy' ls echo ====== Testing remove ====== status remove 3 y remove addtest2 y # cvsshell refuses to delete dirs! remove dirX ls cd rm -rf /tmp/testdata /tmp/cvsroot exit |
From: Stefan H. <ste...@us...> - 2002-03-10 23:11:27
|
Update of /cvsroot/cvsshell/cvsshell/testing In directory usw-pr-cvs1:/tmp/cvs-serv24978/testing Log Message: Directory /cvsroot/cvsshell/cvsshell/testing added to the repository |
From: Stefan H. <ste...@us...> - 2002-03-10 23:11:10
|
Update of /cvsroot/cvsshell/cvsshell In directory usw-pr-cvs1:/tmp/cvs-serv24870 Added Files: install.py Log Message: initial checkin --- NEW FILE: install.py --- #!/usr/bin/env python ############################################################################### # This file is part of CvsShell # # CvsShell 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. # # CvsShell 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 CvsShell; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Copyright 2002 by Stefan Heimann # Website: http://cvsshell.sourceforge.net/ ############################################################################### import sys, os, time thisDir = os.path.join(os.getcwd(), sys.path[0]) sys.path.insert(1, os.path.join(thisDir, 'src')) from interactive_app import InteractiveApp from cvs_shell import NAME, VERSION, COPYRIGHT, BUG_ADDRESS unixStartScript = """#!/usr/bin/env sh # automatically generated on %s /usr/bin/env python %s "$@" """ % (time.ctime(time.time()), os.path.join(thisDir, 'src', 'cvs_shell.py')) class Installation(InteractiveApp): def __init__(self): InteractiveApp.__init__(self) self.setName(NAME + ' Installation Procedure') self.setVersion(VERSION) self.setCopyright(COPYRIGHT) self.setBugAddress(BUG_ADDRESS) self.targetDir = None self.initOptions('') self.onWindows = sys.platform[:3] == 'win' try: self.path = os.environ['PATH'].split(os.pathsep) except KeyError: self.path = [] def getPrompt(self): return 'Into which directory should I install the shellscript that starts CvsShell?\n' \ 'This directory should be included in your $PATH variable.\n$ ' def evalCommand(self, cmd): if os.path.isdir(cmd): if not self.inPath(cmd): self.printMsg('The directory is not included in your $PATH variable.') if raw_input('Are you sure (yes|no)? ') != 'yes': return self.targetDir = cmd return self.BREAK_REPL else: return 'Not a valid directory.' def start(self): InteractiveApp.start(self) if self.onWindows: self.exit("Windows is currently not supported. I am working on it.") def inPath(self, dir): return dir in self.path def stop(self): failureMsg = 'CvsShell was not successfully installed.' global unixStartScript if self.targetDir is None: self.printMsg(failureMsg) return startup = os.path.join(self.targetDir, 'cvsshell') try: open(startup, 'w').write(unixStartScript) os.chmod(startup, 0775) except (IOError, OSError), msg: self.exit(str(msg) + '\n' + failureMsg) self.printMsg('CvsShell was successfully installed.') if self.inPath(self.targetDir): launcher = os.path.basename(startup) else: launcer = startup self.printMsg("You can launch it by typing `%s' in a terminal window" % launcher) if __name__ == '__main__': i = Installation() i.main() |
From: Stefan H. <ste...@us...> - 2002-03-09 17:24:50
|
Update of /cvsroot/cvsshell/cvsshell/src In directory usw-pr-cvs1:/tmp/cvs-serv32725 Added Files: oo_tools.py Log Message: initial checkin --- NEW FILE: oo_tools.py --- ############################################################################### # This file is part of CvsShell # # CvsShell 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. # # CvsShell 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 CvsShell; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Copyright 2002 by Stefan Heimann # Website: http://cvsshell.sourceforge.net/ ############################################################################### # This class is not thread-safe! Prior to python 2.2 it is not possible # to write something like: # def foo(): # x = 5 # def bar(): # print x # bar() # and so all communication between the inner and the outer function # has to be done with global variables. # # To make it thread-safe, one must lock all access-points of the variable # GetSetProvider.__storage. AccessError = 'AccessError' class GetSetProvider: """Classes which are derived from GetSetProvider have implicit get/set methods for all their variables. """ def __init__(self): self.__readonly = [] self.__private = [] 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: self.__raiseAccessError(attr, 'private') 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) def _GetSetProvider__raiseAccessError(self, attr, access): raise AccessError, \ 'attribute %s in class %s has %s access' % \ (attr, self.__class__.__name__, access) def _setReadonly_(self, name): self.__readonly.append(name) def _setPrivate_(self, name): self.__private.append(name) ############################## # TestCases ############################## if __name__ == '__main__': import unittest class Test(GetSetProvider): def __init__(self, name): GetSetProvider.__init__(self) self.name = name self.private = None self._setPrivate_('private') self.readonly = 'readonly' self._setReadonly_('readonly') class GetSetProviderTestCase(unittest.TestCase): def setUp(self): self.t = Test('Stefan') def tearDown(self): del self.t def testGet(self): self.assertEqual(self.t.getName(), 'Stefan') try: self.t.getAge() self.fail('should raise exception here.') except AttributeError: pass def testSet(self): self.t.setName('Heimann') self.assertEqual(self.t.getName(), 'Heimann') self.t.setAge(23) self.assertEqual(self.t.getAge(), 23) def testAccess(self): self.assertEqual(self.t.getReadonly(), 'readonly') try: self.t.setReadonly(None) fail('should raise exception here.') except AccessError: pass try: self.t.getPrivate() fail('should raise exception here.') except AccessError: pass try: self.t.setPrivate(None) fail('should raise exception here.') except AccessError: pass unittest.main() |
From: Stefan H. <ste...@us...> - 2002-03-09 10:56:24
|
Update of /cvsroot/cvsshell/cvsshell/src In directory usw-pr-cvs1:/tmp/cvs-serv24812/src Modified Files: basic_cmds.py configurable_app.py cvs_shell.py utils.py Log Message: * Added support for pager for long listings Index: basic_cmds.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/basic_cmds.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** basic_cmds.py 8 Mar 2002 22:31:01 -0000 1.12 --- basic_cmds.py 9 Mar 2002 10:56:20 -0000 1.13 *************** *** 137,141 **** dir = dirRes.group('dir') if dir == '.': dir = '' ! l = context['basic_cmds.listing'] = utils.Listing(os.getcwd(), entries) context['basic_cmds.dirty_listing'] = 0 --- 137,141 ---- dir = dirRes.group('dir') if dir == '.': dir = '' ! l = context['basic_cmds.listing'] = utils.Listing(app, os.getcwd(), entries) context['basic_cmds.dirty_listing'] = 0 *************** *** 163,167 **** dir = os.path.dirname(x[1]) entries.append(utils.Entry(dir, name, status)) ! l = context['basic_cmds.listing'] = utils.Listing(os.getcwd(), entries) context['basic_cmds.dirty_listing'] = 0 --- 163,167 ---- 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 *************** *** 286,290 **** return e (rootDir, toDelete) = _applyOnEntryList(rest, context, __doIt) ! toDeleteList = utils.Listing(rootDir, toDelete) filenames = [] if toDelete: --- 286,290 ---- return e (rootDir, toDelete) = _applyOnEntryList(rest, context, __doIt) ! toDeleteList = utils.Listing(app, rootDir, toDelete) filenames = [] if toDelete: *************** *** 477,481 **** app.printErr(noListingErrMsg) else: ! listing.printEntries(app.output) if _isDirtyListing(context): app.printMsg("Listing may be out-of-date. " \ --- 477,481 ---- app.printErr(noListingErrMsg) else: ! listing.printEntries() if _isDirtyListing(context): app.printMsg("Listing may be out-of-date. " \ *************** *** 587,590 **** --- 587,603 ---- 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 Index: configurable_app.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/configurable_app.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** configurable_app.py 8 Mar 2002 22:31:01 -0000 1.4 --- configurable_app.py 9 Mar 2002 10:56:20 -0000 1.5 *************** *** 107,111 **** # helper methods ######################################## ! def _getFun(self, fun): """Returns the function that is given by `fun'. If `fun' is a --- 107,111 ---- # helper methods ######################################## ! def _getFun(self, fun): """Returns the function that is given by `fun'. If `fun' is a Index: cvs_shell.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/cvs_shell.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** cvs_shell.py 8 Mar 2002 22:31:01 -0000 1.10 --- cvs_shell.py 9 Mar 2002 10:56:20 -0000 1.11 *************** *** 20,24 **** ############################################################################### ! import os, sys, re, types from configurable_app import SyntaxError from interactive_app import InteractiveApp --- 20,24 ---- ############################################################################### ! import os, sys, re, string, types from configurable_app import SyntaxError from interactive_app import InteractiveApp *************** *** 45,51 **** ('h',"Print this help message")]) self.CVS_ROOT_FILE = os.path.join('CVS', 'Root') - self.cvsRoot = None - self.cvsRootAutoUpdate = 0 - self.showFullPrompt = 0 self.cmdRegex = re.compile(r""" ^\s* # matches leading whitespace --- 45,48 ---- *************** *** 56,59 **** --- 53,60 ---- )? # options are optional """, re.VERBOSE) + self.cvsRoot = None + self.cvsRootAutoUpdate = 0 + self.showFullPrompt = 0 + self.configMap = {} self.readCommandFile() self.readConfigFile() *************** *** 111,117 **** --- 112,120 ---- return fun(cmdName, cmdOpts, self.CONTEXT) + def run(self): # FIXME: why must I redefine run here? InteractiveApp.run(self) + _cvsChangeCmdRE = re.compile(r"""\s+ (ad(d)?|new|ci|com(mit)?|delete|remove) *************** *** 124,128 **** app.shell('%s %s' % (name, opts)) ! if __name__ == '__main__': app = CvsShell() --- 127,151 ---- 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)) ! ! if __name__ == '__main__': app = CvsShell() Index: utils.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/utils.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** utils.py 8 Mar 2002 22:31:01 -0000 1.6 --- utils.py 9 Mar 2002 10:56:20 -0000 1.7 *************** *** 31,35 **** class Listing: ! def __init__(self, rootDir, entries): self.rootDir = rootDir self.entries = entries --- 31,36 ---- class Listing: ! def __init__(self, app, rootDir, entries): ! self.app = app self.rootDir = rootDir self.entries = entries *************** *** 50,56 **** self.entries.sort(__EntrySorter(self.sortOrder).cmp) ! def printEntries(self, output): if not self.entries: ! output.write('No entries available.\n') return max = 0 --- 51,57 ---- self.entries.sort(__EntrySorter(self.sortOrder).cmp) ! def printEntries(self): if not self.entries: ! self.app.printMsg('No entries available.\n') return max = 0 *************** *** 61,71 **** oldDir = None id = 0 for e in self.entries: newDir = e.dir if oldDir != newDir: ! output.write("%s:\n" % newDir) ! output.write(formatStr % (id, e.status, e.name)) id += 1 oldDir = newDir ############################## --- 62,74 ---- 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) ############################## |
From: Stefan H. <ste...@us...> - 2002-03-09 10:56:24
|
Update of /cvsroot/cvsshell/cvsshell/etc In directory usw-pr-cvs1:/tmp/cvs-serv24812/etc Modified Files: cvsshell.ini default-cvsshellrc Log Message: * Added support for pager for long listings Index: cvsshell.ini =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/etc/cvsshell.ini,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** cvsshell.ini 8 Mar 2002 11:12:29 -0000 1.2 --- cvsshell.ini 9 Mar 2002 10:56:20 -0000 1.3 *************** *** 30,32 **** --- 30,33 ---- CVSROOT = basic_cmds.parseCvsRootSection DEFAULT_CMD_OPTIONS = basic_cmds.parseDefaultOptions + CONFIG = basic_cmds.parseConfigSection end Index: default-cvsshellrc =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/etc/default-cvsshellrc,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** default-cvsshellrc 8 Mar 2002 11:12:29 -0000 1.2 --- default-cvsshellrc 9 Mar 2002 10:56:20 -0000 1.3 *************** *** 2,5 **** --- 2,10 ---- # See http://cvsshell.sourceforge.net for more information + # Here you can set configuration variables + section CONFIG: + pager = less + end + # commands that should be executed at start-up section INIT_CMDS: *************** *** 8,16 **** # options for cvs commands - # # Format: option1, option2 = options - # # You can use the keyword `ALL' to apply options to all commands - # # Note: You have to specify the options for every synonym of a command, too. section DEFAULT_CMD_OPTIONS: --- 13,18 ---- |
From: Stefan H. <ste...@us...> - 2002-03-08 22:44:36
|
Update of /cvsroot/cvsshell/cvsshell/src In directory usw-pr-cvs1:/tmp/cvs-serv23879/src Modified Files: app.py Log Message: Error msg are now printed out with printErr(...) Index: app.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/app.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** app.py 8 Mar 2002 22:31:00 -0000 1.5 --- app.py 8 Mar 2002 22:44:33 -0000 1.6 *************** *** 208,229 **** pass except: ! out = sys.stderr ! out.write('========== Traceback starts here ==========\n') ! out.write('uncaught: ' + `(sys.exc_type,sys.exc_value)` + '\n') traceback.print_exc() ! out.write(""" Program Version: %s Platform: %s ! Python version: %s ! """ % (self.version, sys.platform, sys.version)) ! out.write("========== Traceback ends here ==========\n" \ ! "You have discovered a bug in %s.\n" % self.name) if self.bugAddress.find('@') > 0: ! out.write("Please send a bug report to \n %s," ! % self.bugAddress) else: ! out.write("Please fill out a bug report at \n %s," ! % self.bugAddress) ! self.printMsg("\nincluding the traceback above.\n") self.closeApp() return res --- 208,227 ---- pass except: ! self.printErr('========== Traceback starts here ==========') ! self.printErr('uncaught: ' + `(sys.exc_type,sys.exc_value)`) traceback.print_exc() ! self.printErr(""" Program Version: %s Platform: %s ! Python version: %s""" % (self.version, sys.platform, sys.version)) ! self.printErr("========== Traceback ends here ==========\n" \ ! "You have discovered a bug in %s." % self.name) if self.bugAddress.find('@') > 0: ! self.printErr("Please send a bug report to \n %s," ! % self.bugAddress) else: ! self.printErr("Please fill out a bug report at \n %s," ! % self.bugAddress) ! self.printErr("including the traceback above.") self.closeApp() return res |
From: Stefan H. <ste...@us...> - 2002-03-08 22:31:06
|
Update of /cvsroot/cvsshell/cvsshell/src In directory usw-pr-cvs1:/tmp/cvs-serv20462 Modified Files: app.py basic_cmds.py configurable_app.py cvs_shell.py plugable_app.py utils.py Log Message: * it's now possible to specify filenames for commit, add, remove * auto-aliases for checkout works now Index: app.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/app.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** app.py 7 Mar 2002 13:08:49 -0000 1.4 --- app.py 8 Mar 2002 22:31:00 -0000 1.5 *************** *** 20,233 **** ############################################################################### ! 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.""" ! print "%s, Version %s" % (self.name, self.version) ! 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=[]): ! """ ! This method should be called once before getarg is called. ! opts is a list of key-value pairs. ! The keys are the name of the options that should be ! supported, without the leading `-'. If an ! option expects an argument, the name of the option should be ! followed by a colon. ! The values are the documentation of the option. ! """ ! str = '' ! self.docs = [] ! for x in opts: ! name = x[0] ! doc = x[1] ! str += name ! 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() ! ! ############################## ! # script environment services ! ############################## ! ! 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 ! ! 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 ! ! 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 ! ! def setenv(self, name, value): # convenient method ! """set '$x' environment var""" ! self.env[name] = value ! ! def isVerbose(self): ! return self.getopt('-v') or self.getopt('--verbose') ! ! def isHelpRequest(self): ! return self.getopt('-h') or self.getopt('--help') ! ! def printVMsg(self, text='', nonl=0): ! if self.isVerbose(): self.printMsg(text, nonl) ! ! 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): ! if message: ! self.printMsg(message) ! sys.exit(status) ! ! def shell(self, command, fork=0, inp=''): ! if self.isVerbose(): ! self.printMsg(command) # how about ipc? ! if not fork: ! os.system(command) # run a shell cmd ! elif fork == 1: ! return os.popen(command, 'r').read() # get its output ! else: # readlines too? ! pipe = os.popen(command, 'w') ! 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): ! """to run the app ! main() is the start/run/stop execution protocol""" ! if self.isHelpRequest(): ! self.help() ! return 0 ! res = None ! try: ! self.start() ! self.run() ! res = self.stop() # optional return val ! except SystemExit: # ignore if from exit() ! pass ! except: ! self.printMsg('========== Traceback starts here ==========') ! self.printMsg('uncaught: ' + `(sys.exc_type,sys.exc_value)`) ! traceback.print_exc() ! self.printMsg(""" ! Program Version: %s ! Platform: %s ! Python version: %s""" % (self.version, sys.platform, sys.version)) ! self.printMsg("========== Traceback ends here ==========\n" \ ! "You have discovered a bug in %s." % self.name) ! if self.bugAddress.find('@') > 0: ! self.printMsg("Please send a bug report to \n %s," % self.bugAddress) ! else: ! self.printMsg("Please fill out a bug report at \n %s," % self.bugAddress) ! self.printMsg("including the traceback above.") ! self.closeApp() ! return res ! ! def start(self): ! if self.isVerbose(): self.printMsg(self.name + ' started.') ! def stop(self): ! if self.isVerbose(): self.printMsg(self.name + ' done.') ! def run(self): ! raise AppError, 'run must be redefined!' ! --- 20,239 ---- ############################################################################### ! 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.""" ! print "%s, Version %s" % (self.name, self.version) ! 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=[]): ! """ ! This method should be called once before getarg is called. ! opts is a list of key-value pairs. ! The keys are the name of the options that should be ! supported, without the leading `-'. If an ! option expects an argument, the name of the option should be ! followed by a colon. ! The values are the documentation of the option. ! """ ! str = '' ! self.docs = [] ! for x in opts: ! name = x[0] ! doc = x[1] ! str += name ! 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() ! ! ############################## ! # script environment services ! ############################## ! ! 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 ! ! 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 ! ! 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 ! ! def setenv(self, name, value): # convenient method ! """set '$x' environment var""" ! self.env[name] = value ! ! def isVerbose(self): ! return self.getopt('-v') or self.getopt('--verbose') ! ! def isHelpRequest(self): ! return self.getopt('-h') or self.getopt('--help') ! ! def printVMsg(self, text='', nonl=0): ! if self.isVerbose(): self.printMsg(text, nonl) ! ! 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): ! if message: ! self.printMsg(message) ! sys.exit(status) ! ! def shell(self, command, fork=0, inp=''): ! if self.isVerbose(): ! self.printMsg(command) # how about ipc? ! if not fork: ! os.system(command) # run a shell cmd ! elif fork == 1: ! return os.popen(command, 'r').read() # get its output ! else: # readlines too? ! pipe = os.popen(command, 'w') ! 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): ! """to run the app ! main() is the start/run/stop execution protocol""" ! if self.isHelpRequest(): ! self.help() ! return 0 ! res = None ! try: ! self.start() ! self.run() ! res = self.stop() # optional return val ! except SystemExit: # ignore if from exit() ! pass ! except: ! out = sys.stderr ! out.write('========== Traceback starts here ==========\n') ! out.write('uncaught: ' + `(sys.exc_type,sys.exc_value)` + '\n') ! traceback.print_exc() ! out.write(""" ! Program Version: %s ! Platform: %s ! Python version: %s ! """ % (self.version, sys.platform, sys.version)) ! out.write("========== Traceback ends here ==========\n" \ ! "You have discovered a bug in %s.\n" % self.name) ! if self.bugAddress.find('@') > 0: ! out.write("Please send a bug report to \n %s," ! % self.bugAddress) ! else: ! out.write("Please fill out a bug report at \n %s," ! % self.bugAddress) ! self.printMsg("\nincluding the traceback above.\n") ! self.closeApp() ! return res ! ! def start(self): ! self.printMsg("%s %s" % (self.name, self.version)) ! self.printMsg(self.copyright) ! self.printVMsg(self.name + ' started.') ! def stop(self): ! self.printVMsg(self.name + ' done.') ! def run(self): ! raise AppError, 'run must be redefined!' ! Index: basic_cmds.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/basic_cmds.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** basic_cmds.py 8 Mar 2002 11:32:16 -0000 1.11 --- basic_cmds.py 8 Mar 2002 22:31:01 -0000 1.12 *************** *** 182,185 **** --- 182,187 ---- 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: ') *************** *** 203,218 **** 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 --- 205,226 ---- 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 *************** *** 228,237 **** 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: --- 236,243 ---- 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: *************** *** 257,260 **** --- 263,273 ---- 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): *************** *** 262,287 **** 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 = [] ! 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) ! else: filenames.append(os.path.join(e.dir, e.name)) e.status = utils.Entry.S_REMOVED if filenames: args = utils.list2string(filenames) --- 275,310 ---- 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(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) *************** *** 318,321 **** --- 341,349 ---- 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) *************** *** 358,368 **** """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).""" app = context['APP'] ! defRet = (None, None) try: nums = utils.getNumbers(opts) except utils.ParseError, msg: - app.printErr(msg) return defRet if len(nums) == 0: --- 386,396 ---- """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: Index: configurable_app.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/configurable_app.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** configurable_app.py 7 Mar 2002 13:08:49 -0000 1.3 --- configurable_app.py 8 Mar 2002 22:31:01 -0000 1.4 *************** *** 55,74 **** def readConfigFile(self): - f = open(self.configFile,'r') try: ! sections = self._splitSections(f.readlines()) ! except SyntaxError, msg: ! self.printErr("Syntax error in config file: %s" % msg) ! return ! for x in sections.items(): ! name = x[0] ! content = x[1] ! if self._configsection_to_fun.has_key(name): ! self._configsection_to_fun[name](content, self.CONTEXT) else: ! self.printErr("Unknown section in configuration file: %s" ! % name) ! f.close() ######################################## # helper methods --- 55,107 ---- def readConfigFile(self): try: ! f = open(self.configFile,'r') ! try: ! sections = self._splitSections(f.readlines()) ! except SyntaxError, msg: ! self.printErr("Syntax error in config file: %s" % msg) ! return ! 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: ! self.printErr(msg) ! ! ! def appendToSection(self, section, lines): ! """ Appends lines the the given section (a new section is ! created if not existing). lines is a list of lines without ! trailing \n""" ! try: ! f = open(self.configFile,'r') ! l = f.readlines() ! f.close() ! try: ! sections = self._splitSections(l) ! except SyntaxError, msg: ! self.printErr("Syntax error in config file: %s" % msg) ! return ! if sections.has_key(section): ! n = sections[section].end else: ! n = len(l) ! l.insert(n, '\n') ! n += 1 ! i = 0 ! for x in lines: ! print "inserting %s" % x ! l.insert(n+i-1, x + '\n') ! i += 1 ! f = open(self.configFile,'w') ! f.writelines(l) ! f.close() ! except IOError, msg: ! self.printErr(msg) + ######################################## # helper methods *************** *** 97,106 **** return fun def _splitSections(self,lines): ! """Returns a dictionary which maps every name of a section ! to the lines of the section. the values of the dictionary ! are tuples that consist of the line number and the content of ! the line. Comment lines are already removed. ! Leading and trailing whitespace are also removed. If a syntax exception is encountered, a SyntaxError is raised.""" comment_re= re.compile(r'^(\s*|\s*#.*)$') --- 130,145 ---- return fun + class Section: + def __init__(self, name, start): + self.name = name + self.start = start + self.end = None + self.content = [] + def _splitSections(self,lines): ! """Returns a dict which maps every name of a section to a ! ConfigurableApp.Section instance. ! Comment lines in a section are already removed. ! 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*#.*)$') *************** *** 130,135 **** "section (line %d)." % n section_open = 1 ! section_name = start.group('name') ! section_content = [] continue end = section_end_re.match(l) --- 169,173 ---- "section (line %d)." % n section_open = 1 ! section = ConfigurableApp.Section(start.group('name'), n) continue end = section_end_re.match(l) *************** *** 139,143 **** "(line %d)." % n section_open = 0 ! sections[section_name] = section_content continue # the line must be the content of a section --- 177,182 ---- "(line %d)." % n section_open = 0 ! section.end = n ! sections[section.name] = section continue # the line must be the content of a section *************** *** 146,150 **** "section (line %d)." % n l = l.strip() ! section_content.append((n,l)) return sections --- 185,189 ---- "section (line %d)." % n l = l.strip() ! section.content.append((n,l)) return sections Index: cvs_shell.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/cvs_shell.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** cvs_shell.py 8 Mar 2002 11:12:29 -0000 1.9 --- cvs_shell.py 8 Mar 2002 22:31:01 -0000 1.10 *************** *** 34,38 **** self.setName('CvsShell') self.setVersion(VERSION) ! self.setCopyright('Copyright 2002 by Stefan Heimann. 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') --- 34,39 ---- 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') Index: plugable_app.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/plugable_app.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** plugable_app.py 8 Mar 2002 11:12:29 -0000 1.3 --- plugable_app.py 8 Mar 2002 22:31:01 -0000 1.4 *************** *** 46,49 **** --- 46,50 ---- cmds = sections.get('COMMANDS', []) + if cmds: cmds = cmds.content for x in cmds: n = x[0] *************** *** 57,60 **** --- 58,62 ---- opts = sections.get('COMMAND_OPTIONS', []) + if opts: opts = opts.content for x in opts: n = x[0] *************** *** 69,72 **** --- 71,75 ---- prs = sections.get('PARSERS', []) + if prs: prs = prs.content for x in prs: n = x[0] Index: utils.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/utils.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** utils.py 8 Mar 2002 11:32:16 -0000 1.5 --- utils.py 8 Mar 2002 22:31:01 -0000 1.6 *************** *** 51,54 **** --- 51,57 ---- def printEntries(self, output): + if not self.entries: + output.write('No entries available.\n') + return max = 0 for e in self.entries: *************** *** 57,62 **** formatStr = " %%%dd %%-%ds %%s\n" % (len(`len(self.entries)`), max) oldDir = None - if len(self.entries) == 0: - output.write('No entries available.\n') id = 0 for e in self.entries: --- 60,63 ---- |
From: Stefan H. <ste...@us...> - 2002-03-08 11:32:19
|
Update of /cvsroot/cvsshell/cvsshell/src In directory usw-pr-cvs1:/tmp/cvs-serv27240/src Modified Files: basic_cmds.py utils.py Log Message: splitquotes is now called splitquoted and works also for single quotes Index: basic_cmds.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/basic_cmds.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** basic_cmds.py 8 Mar 2002 11:12:29 -0000 1.10 --- basic_cmds.py 8 Mar 2002 11:32:16 -0000 1.11 *************** *** 468,472 **** cvsGlobOpts = 'HQqrwlntvb:T:e:d:fz:as:' s = cvsGlobOpts+cvsCmdOpts+cmdOpts ! (opts, rest) = getopt.getopt(utils.splitquotes(args), s) cvsGlobOptstr = cvsCmdOptstr = '' cmdOptDict = {} --- 468,472 ---- cvsGlobOpts = 'HQqrwlntvb:T:e:d:fz:as:' s = cvsGlobOpts+cvsCmdOpts+cmdOpts ! (opts, rest) = getopt.getopt(utils.splitquoted(args), s) cvsGlobOptstr = cvsCmdOptstr = '' cmdOptDict = {} Index: utils.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/utils.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** utils.py 8 Mar 2002 11:12:29 -0000 1.4 --- utils.py 8 Mar 2002 11:32:16 -0000 1.5 *************** *** 136,147 **** ! _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 --- 136,149 ---- ! def splitquoted(str): """Splits str on whitespace except when a quoted string is encountered. # Example: splitquotes('foo "foo \"bar\""') => ['foo','"foo \"bar\""'] """ + doubleQ = r'"(?:[^"\\]+|\\.)*"' + singleQ = r"'(?:[^'\\]+|\\.)*'" + splitRE = re.compile(r'(%s|%s|\S+)' % (doubleQ, singleQ)) res = [] ! for x in splitRE.split(str): x = x.strip() if x: res.append(x) # not only whitespace |
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 |
From: Stefan H. <ste...@us...> - 2002-03-08 11:12:32
|
Update of /cvsroot/cvsshell/cvsshell/etc In directory usw-pr-cvs1:/tmp/cvs-serv22728/etc Modified Files: cvsshell.ini default-cvsshellrc Log Message: Added support for better handling of arguments to cvs commands Index: cvsshell.ini =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/etc/cvsshell.ini,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** cvsshell.ini 7 Mar 2002 12:57:17 -0000 1.1 --- cvsshell.ini 8 Mar 2002 11:12:29 -0000 1.2 *************** *** 17,20 **** --- 17,29 ---- end + section COMMAND_OPTIONS: + up, upd, update, refresh = AdD:r:fI:j:k:lRpPW: + ad, add, new = k:m: + ci, com, commit = flRF:m:nr: + delete, remove = flR + co, get, checkout = Acsd:ND:r:fj:k:lRnpP + st, stat, status = lrv + end + section PARSERS: INIT_CMDS = basic_cmds.parseInitCmdsSection Index: default-cvsshellrc =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/etc/default-cvsshellrc,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** default-cvsshellrc 7 Mar 2002 12:57:17 -0000 1.1 --- default-cvsshellrc 8 Mar 2002 11:12:29 -0000 1.2 *************** *** 9,17 **** # options for cvs commands # ! # Format: option1, option2 = global options % options ! # Global options are the options available for all commands, ! # options are the options only available for this specific command. ! # Example: cvs -n update -P ! # Here, `-n' is a global option, while `-P' is just a option # # You can use the keyword `ALL' to apply options to all commands --- 9,13 ---- # options for cvs commands # ! # Format: option1, option2 = options # # You can use the keyword `ALL' to apply options to all commands *************** *** 19,25 **** # Note: You have to specify the options for every synonym of a command, too. section DEFAULT_CMD_OPTIONS: ! ALL = -z 3 % ! up, upd, update = -q % -P -d ! co, get, checkout = -q % end --- 15,21 ---- # Note: You have to specify the options for every synonym of a command, too. section DEFAULT_CMD_OPTIONS: ! ALL = -z 3 ! up, upd, update = -q -P ! co, get, checkout = -q end |
From: Stefan H. <ste...@us...> - 2002-03-07 15:10:56
|
Update of /cvsroot/cvsshell/cvsshell/src In directory usw-pr-cvs1:/tmp/cvs-serv1765 Modified Files: basic_cmds.py cvs_shell.py Log Message: * support for adding binary files * better apearance of prompt Index: basic_cmds.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/basic_cmds.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** basic_cmds.py 7 Mar 2002 13:08:49 -0000 1.8 --- basic_cmds.py 7 Mar 2002 15:10:51 -0000 1.9 *************** *** 52,56 **** except KeyError: app.printErr("Unknown command: %s" % cmd) - first_sentence = re.compile(r'[^\n]*') app.printMsg("The following commands are available:") --- 52,55 ---- *************** *** 62,66 **** items = app.cmdToDoc.items() items.sort(lambda x,y: cmp(x[0], y[0])) - print items for x in items: name = app.cmdToCmds[x[0]] --- 61,64 ---- *************** *** 171,179 **** _runCvsCmd(context, 'checkout', args=module) except CvsError: pass ! ! def add(name, args, context): app = context['APP'] if not args: ! args = app.prompt('enter filenumbers to add: ') if args is None: return def __doIt(e,filename): --- 169,178 ---- _runCvsCmd(context, 'checkout', args=module) except CvsError: pass ! ! ! 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): *************** *** 182,188 **** (rootDir, filenames) = _applyOnEntryList(args, context, __doIt) if filenames: try: ! _runCvsCmd(context, 'add', rootDir=rootDir, args=utils.list2string(filenames)) except CvsError: pass def commit(name, args, context): --- 181,195 ---- (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 + + + 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): *************** *** 214,218 **** app = context['APP'] if args == '': ! args = app.prompt('enter filenumbers to remove: ') if args is None: return def __doIt(e,filename): --- 221,225 ---- app = context['APP'] if args == '': ! args = app.prompt('enter filenumber(s) to remove: ') if args is None: return def __doIt(e,filename): *************** *** 286,302 **** option to a new value with `on' or `off' as argument.""" app = context['APP'] ! if len(args) == 0: ! app.cvsRootAutoUpdate = not app.cvsRootAutoUpdate ! else: ! if args == 'on': app.cvsRootAutoUpdate = 1 ! elif args == 'off': app.cvsRootAutoUpdate = 0 ! else: ! app.printErr("argument must be `on' or `off'") ! return if app.cvsRootAutoUpdate: newRoot = app.readCvsRootFromFile() if newRoot is not None: app.setCvsRoot(newRoot) ################################### # Helper functions for CVS commands --- 293,306 ---- 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 *************** *** 489,492 **** --- 493,505 ---- return defGlobOpts,defOpts + 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 Index: cvs_shell.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/cvs_shell.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** cvs_shell.py 7 Mar 2002 13:08:49 -0000 1.7 --- cvs_shell.py 7 Mar 2002 15:10:51 -0000 1.8 *************** *** 26,30 **** VERSION = '0.1' - _cvsChangeCmdRE = re.compile(r'\s+(ad(d)?|new|ci|com(mit)?|delete|remove)\s+') class CvsShell(PlugableApp, InteractiveApp): --- 26,29 ---- *************** *** 47,50 **** --- 46,50 ---- self.cvsRoot = None self.cvsRootAutoUpdate = 0 + self.showFullPrompt = 0 self.cmdRegex = re.compile(r""" ^\s* # matches leading whitespace *************** *** 75,80 **** else: status += 'A' root = self.getCvsRoot() or '--' ! return "{%s} %s [%s]$ " % (status, ! os.getcwd().replace(self.HOME, '~'), root) --- 75,99 ---- else: status += 'A' root = self.getCvsRoot() or '--' ! dir = os.getcwd().replace(self.HOME, '~') ! if not self.showFullPrompt: ! # make to prompt match on one line ! extraChars = 6 ! maxLineWidth = 79 ! minLen = 15 ! ls = len(status) ! ld = len(dir) ! lr = len(root) ! width = ls + extraChars + ld + lr ! if width > maxLineWidth: ! w = max(minLen, (lr - (width - maxLineWidth + 3)) / 2) ! if lr > 2*w: root = root[:w] + '...' + root[-w:] ! lr = len(root) ! width = ls + extraChars + ld + lr ! if width > maxLineWidth: ! w = max(minLen, ld - (width - maxLineWidth + 3)) ! if ld > w: dir = '...' + dir[-w:] ! ld = len(dir) ! return "{%s} %s [%s]\n$ " % (status, ! dir, root) *************** *** 94,101 **** InteractiveApp.run(self) def execShellCmd(self, name, opts, context): - global _cvsChangeCmdRE app = context['APP'] ! if name == 'cvs' and _cvsChangeCmdRE.search(opts): # command may change the status context['basic_cmds.dirty_listing'] = 1 app.shell('%s %s' % (name, opts)) --- 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)) |
From: Stefan H. <ste...@us...> - 2002-03-07 15:09:32
|
Update of /cvsroot/cvsshell/cvsshell/src In directory usw-pr-cvs1:/tmp/cvs-serv1547 Modified Files: interactive_app.py Log Message: C-c is now also supported to stop the REPL Index: interactive_app.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/interactive_app.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** interactive_app.py 7 Mar 2002 13:08:49 -0000 1.3 --- interactive_app.py 7 Mar 2002 15:09:26 -0000 1.4 *************** *** 20,84 **** ############################################################################### ! import os ! from app import App, AppError ! ! class InteractiveApp(App): ! ! def __init__(self): ! App.__init__(self) ! self.BREAK_REPL = 'BREAK_REPL' ! try: ! import readline ! except ImportError: ! self.printErr("Could not import readline. History browsing " \ ! "and tab completion will not be available.") ! return ! else: ! readline.parse_and_bind("tab: complete") ! ! def setHistoryFile(self,filename): ! self.historyFile = filename ! try: ! import readline ! except ImportError: return ! try: ! readline.read_history_file(self.historyFile) ! except IOError: ! pass ! import atexit ! atexit.register(readline.write_history_file, self.historyFile) ! ! def run(self): # define App.run here ! while 1: ! command = self.readCommand() ! if command == None: ! break ! result = self.evalCommand(command) ! if result is self.BREAK_REPL: break ! elif result is None: continue ! else: self.printMsg(`result`) ! ! def readCommand(self): # subclass hooks + App.start,stop ! return self.prompt(self.getPrompt()) ! ! def getPrompt(self): ! return '? ' ! ! 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: ! self.printMsg() ! return None ! a = os.path.expandvars(a) ! return a.strip() ! ! def evalCommand(self, command): ! """Subclasses should override this method. ! If BREAK_REPL is returned, the repl is terminated, ! otherwise the return-value is printed (if not None).""" ! raise AppError, 'evalCommand must be redefined!' ! --- 20,84 ---- ############################################################################### ! import os ! from app import App, AppError ! ! class InteractiveApp(App): ! ! def __init__(self): ! App.__init__(self) ! self.BREAK_REPL = 'BREAK_REPL' ! try: ! import readline ! except ImportError: ! self.printErr("Could not import readline. History browsing " \ ! "and tab completion will not be available.") ! return ! else: ! readline.parse_and_bind("tab: complete") ! ! def setHistoryFile(self,filename): ! self.historyFile = filename ! try: ! import readline ! except ImportError: return ! try: ! readline.read_history_file(self.historyFile) ! except IOError: ! pass ! import atexit ! atexit.register(readline.write_history_file, self.historyFile) ! ! def run(self): # define App.run here ! while 1: ! command = self.readCommand() ! if command == None: ! break ! result = self.evalCommand(command) ! if result is self.BREAK_REPL: break ! elif result is None: continue ! else: self.printMsg(`result`) ! ! def readCommand(self): # subclass hooks + App.start,stop ! return self.prompt(self.getPrompt()) ! ! def getPrompt(self): ! return '? ' ! ! 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() ! ! def evalCommand(self, command): ! """Subclasses should override this method. ! If BREAK_REPL is returned, the repl is terminated, ! otherwise the return-value is printed (if not None).""" ! raise AppError, 'evalCommand must be redefined!' ! |