Thread: [Cvsshell-devel] CVS: cvsshell/src app.py,1.17,1.18 basic_cmds.py,1.24,1.25 cvs_cmds.py,1.18,1.19 cv
Status: Beta
Brought to you by:
stefanheimann
From: Stefan H. <ste...@us...> - 2003-04-15 13:40:19
|
Update of /cvsroot/cvsshell/cvsshell/src In directory sc8-pr-cvs1:/tmp/cvs-serv12778/src Modified Files: app.py basic_cmds.py cvs_cmds.py cvs_shell.py interactive_app.py parsing.py utils.py Log Message: Index: app.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/app.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** app.py 18 Sep 2002 19:07:56 -0000 1.17 --- app.py 15 Apr 2003 13:40:09 -0000 1.18 *************** *** 26,31 **** _thisdir = os.path.join(os.getcwd(), sys.path[0]) AppError = 'AppError' ! ! class App(GetSetProvider): --- 26,30 ---- _thisdir = os.path.join(os.getcwd(), sys.path[0]) AppError = 'AppError' ! class App(GetSetProvider): *************** *** 57,65 **** 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 --- 56,63 ---- def closeApp(self): ! stdstreams = [sys.__stdin__, sys.__stdout__, sys.__stderr__] ! for x in [sys.stdin, sys.stdout, sys.stderr]: try: ! if x not in stdstreams: x.close() except: pass *************** *** 74,84 **** --- 72,93 ---- print max = 0 + s = self.getExecutableName() + ' ' for x in self._docs: + s += x[0] + ' ' l = len(x[0]) if l > max: max = l + s += self.getRestargSpezification() + print s + print for x in self._docs: spaces = (max - len(x[0])) * ' ' print " %s%s %s" % (x[0],spaces,x[1]) print + s = self.getRestargDocumentation() + if s: + lines = s.split('\n') + for l in lines: + print ' ' + l + print *************** *** 224,228 **** pipe = os.popen(command, 'r') res = pipe.read() ! exitCode = pipe.close() else: exitCode = os.system(command) --- 233,238 ---- pipe = os.popen(command, 'r') res = pipe.read() ! # pipe.close() returns None if command succeeded ! exitCode = pipe.close() or 0 else: exitCode = os.system(command) *************** *** 279,282 **** --- 289,296 ---- def postStart(self): pass def preStop(self): pass + def getRestargSpezification(self): return '' + def getRestargDocumentation(self): return '' + def getExecutableName(self): return sys.argv[0] + class ShellException(GetSetProvider): Index: basic_cmds.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/basic_cmds.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** basic_cmds.py 16 Sep 2002 06:49:32 -0000 1.24 --- basic_cmds.py 15 Apr 2003 13:40:09 -0000 1.25 *************** *** 127,158 **** The abbreviation `rd' means `repository date', `wd' means `working date'.""" from time import strftime, localtime def visit(myEntries, dirname, names): namesToProcess = [x for x in names] ! if dirname.find('CVS') >= 0: return ! if 'CVS' in names: # directory under CVS control ! cvsEntries = utils.parseCvsEntries(dirname) ! for name, (revision, rtstamp) in cvsEntries[0].items(): ! fullname = os.path.join(dirname, name) ! if not os.path.exists(fullname): ! myEntries.append(Entry(dirname, name, 'locally-deleted')) else: namesToProcess.remove(name) ! ltstamp = os.path.getmtime(fullname) ! info = '%s (rd: %s, wd: %s)' % (revision, strftime(app.dateFormat, localtime(rtstamp)), ! strftime(app.dateFormat, localtime(ltstamp))) ! if ltstamp == rtstamp: ! myEntries.append(Entry(dirname, name, Entry.S_OK, info)) ! else: ! myEntries.append(Entry(dirname, name, Entry.S_MODIFIED, info)) ! for name in cvsEntries[1].keys(): namesToProcess.remove(name) ! fullname = os.path.join(dirname, name) ! if not os.path.exists(fullname): ! myEntries.append(Entry(dirname, name, Entry.S_DELETED)) ! else: ! myEntries.append(Entry(dirname, name, Entry.S_OK)) ! # only files not under CVS control are contained in names. for name in namesToProcess: ! if name.find('CVS') < 0: myEntries.append(Entry(dirname, name, Entry.S_UNKNOWN)) # --- 127,208 ---- The abbreviation `rd' means `repository date', `wd' means `working date'.""" from time import strftime, localtime + def isCvsInfoDir(path): + """ + Checks if path denotes the name of a directory where CVS stores the information + about the files under version control. This directory is usually named 'CVS', but + on a case-insensitive filesystem the name could also be cvs, Cvs, ... + """ + prefix, suffix = os.path.split(path) + if len(suffix) != 3: return 0 + elif suffix.upper() == 'CVS': return 1 + else: return 0 def visit(myEntries, dirname, names): namesToProcess = [x for x in names] ! isCvsInfoDir(dirname) ! if isCvsInfoDir(dirname): return ! if not 'CVS' in map(string.upper, names): # directory not under CVS control ! names = [] ! return ! ! cvsEntries = utils.parseCvsEntries(dirname) ! ignoreFilter = app.getCvsIgnoreFilter(dirname) ! ! # process files found in CVS/Entries ! for name, (revision, rtstamp) in cvsEntries[0].items(): ! if ignoreFilter.filter(name): ! try: namesToProcess.remove(name) ! except ValueError: pass ! continue ! fullname = os.path.join(dirname, name) ! if not os.path.exists(fullname): ! # name is not in namesToProcess! ! myEntries.append(Entry(dirname, name, 'locally-deleted')) ! else: ! namesToProcess.remove(name) ! ltstamp = os.path.getmtime(fullname) ! maxRevWidth = 8 ! info = revision ! info += (maxRevWidth -len(revision)) * ' ' ! info += '(rd: %s, wd: %s)' % (strftime(app.dateFormat, localtime(rtstamp)), ! strftime(app.dateFormat, localtime(ltstamp))) ! if ltstamp == rtstamp: ! myEntries.append(Entry(dirname, name, Entry.S_OK, info)) else: + myEntries.append(Entry(dirname, name, Entry.S_MODIFIED, info)) + + # process directories found in CVS/Entries + for name in cvsEntries[1].keys(): + if ignoreFilter.filter(name): + try: + names.remove(name) # do not descend into dir! namesToProcess.remove(name) ! except ValueError: pass ! continue ! fullname = os.path.join(dirname, name) ! if not os.path.exists(fullname): ! myEntries.append(Entry(dirname, name, Entry.S_DELETED)) ! else: namesToProcess.remove(name) ! myEntries.append(Entry(dirname, name, Entry.S_OK)) ! ! # only files not under CVS control are contained in namesToProcess. for name in namesToProcess: ! if ignoreFilter.filter(name): ! try: ! names.remove(name) # do not descend into dir! ! except ValueError: pass ! continue ! if name == 'classes': ! raise 'XXX' ! if isCvsInfoDir(name): ! try: names.remove(name) ! except ValueError: pass ! continue ! path = os.path.join(dirname, name, 'CVS') ! if os.path.isdir(path): ! myEntries.append(Entry(dirname, name, Entry.S_OK)) ! else: ! if os.path.isdir(os.path.join(dirname, name)): ! names.remove(name) myEntries.append(Entry(dirname, name, Entry.S_UNKNOWN)) # Index: cvs_cmds.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/cvs_cmds.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** cvs_cmds.py 29 Nov 2002 18:35:26 -0000 1.18 --- cvs_cmds.py 15 Apr 2003 13:40:10 -0000 1.19 *************** *** 51,57 **** app.printErr(msg) return ! rootDir = utils.getAbsDir(rest) ! if rootDir is None: ! return try: lines = app.runCvsCmd('status', globOpts=globOpts, args=opts+' '+rest, getStderr=1) --- 51,59 ---- app.printErr(msg) return ! try: ! l = app.applyOnEntryList(rest, lambda e, name: (e, name)) ! rest = ' '.join(map(lambda t: t[1], l)) ! # args do not spefiy ids in the current listing ! except utils.ParseError: pass try: lines = app.runCvsCmd('status', globOpts=globOpts, args=opts+' '+rest, getStderr=1) *************** *** 94,97 **** --- 96,100 ---- dir = dirRes.group('dir') if dir == '.': dir = '' + rootDir = utils.getAbsDir(rest) app.setListing(Listing(app, rootDir, entries)) app.setDirtyListing(0) *************** *** 113,119 **** return if simulate: globOpts += '-n' ! rootDir = utils.getAbsDir(rest) ! if rootDir is None: ! return try: lines = app.runCvsCmd('update', globOpts=globOpts, args=opts+' '+rest) --- 116,128 ---- return if simulate: globOpts += '-n' ! rest = rest.strip() ! if rest: ! try: ! l = app.applyOnEntryList(rest, lambda e, name: (e, name)) ! rest = ' '.join(map(lambda t: t[1], l)) ! except utils.ParseError: pass # args do not spefiy ids in the current listing ! except AppError, msg: ! app.printErr(msg) ! return try: lines = app.runCvsCmd('update', globOpts=globOpts, args=opts+' '+rest) *************** *** 127,133 **** dir = os.path.dirname(x[1]) entries.append(Entry(dir, name, status)) ! app.setListing(Listing(app, rootDir, entries)) ! app.setDirtyListing(0) ! app.getListing().sortEntries() app.printListing() --- 136,154 ---- dir = os.path.dirname(x[1]) entries.append(Entry(dir, name, status)) ! if not entries: ! return ! elif rest and app.getListing(): ! # we have updated only some specific files ! listing = app.getListing() ! for filename in utils.splitquoted(rest, stripQuotes=1): ! e = listing.getEntry(filename) ! if e: ! e.status = Entry.S_OK ! else: ! # we have update all files ! rootDir = utils.getAbsDir('.') ! app.setListing(Listing(app, rootDir, entries)) ! app.setDirtyListing(0) ! app.getListing().sortEntries() app.printListing() *************** *** 210,213 **** --- 231,237 ---- try: l = app.applyOnEntryList(rest, __doIt) + if not l: + app.printMsg('No files given.') + return entries = [] for x in l: *************** *** 240,248 **** "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): """Add a new binary file to the repository. --- 264,277 ---- "to the repository (yes|no)? ") if answ == 'yes': ! try: ! args = app.getInitialLogmessageOption() + filenames ! app.runCvsCmd('commit', rootDir=toAddListing.getRootDir(), ! fork=0, args=args) ! for e in toAddListing.entries: ! e.status = Entry.S_OK ! except CvsError: ! pass + def addBinary(app, name, args): """Add a new binary file to the repository. *************** *** 382,385 **** --- 411,415 ---- e.status = Entry.S_DELETED try: + args = app.getDeleteLogmessageOption() + args app.runCvsCmd('commit', rootDir=toDeleteListing.getRootDir(), fork=0, args=args) *************** *** 463,467 **** if answ == 'yes': try: ! args = dst + ' ' + src app.runCvsCmd('commit', rootDir=rootDir, fork=0, args=args) --- 493,497 ---- if answ == 'yes': try: ! args = ' -m "renamed %s => %s" %s %s' % (src, dst, dst, src) app.runCvsCmd('commit', rootDir=rootDir, fork=0, args=args) *************** *** 591,592 **** --- 621,657 ---- app.printErr(msg) + + def login(app, name, args): + """Log in to a remote repository. + Normally, it's not necessary to use this command explicitely because + cvsshell logs in automatically when needed.""" + try: + (globOpts, opts, + myOpts, rest) = app.parseArgs(args, + app.getCmdToAllowedOpts().get(name, '')) + except getopt.GetoptError, msg: + app.printErr(msg) + return + if rest or myOpts: + app.printErr("Illegal arguments.") + return + try: + app.runCvsCmd('login', globOpts=globOpts, args=opts, checkLogin=0) + except CvsError: return + + + def logout(app, name, args): + """Log out of a remote repository.""" + try: + (globOpts, opts, + myOpts, rest) = app.parseArgs(args, + app.getCmdToAllowedOpts().get(name, '')) + except getopt.GetoptError, msg: + app.printErr(msg) + return + if rest or myOpts: + app.printErr("Illegal arguments.") + return + try: + app.runCvsCmd('logout', globOpts=globOpts, args=opts, checkLogin=0) + except CvsError: return Index: cvs_shell.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/cvs_shell.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** cvs_shell.py 29 Nov 2002 18:46:31 -0000 1.37 --- cvs_shell.py 15 Apr 2003 13:40:10 -0000 1.38 *************** *** 1,3 **** ! #!/usr/bin/env python ############################################################################### --- 1,3 ---- ! #!/usr/bin/python ############################################################################### *************** *** 22,26 **** ############################################################################### ! import os, sys, re, string, types, getopt, fnmatch, utils from oo_tools import GetSetProvider from app import AppError, ShellException --- 22,34 ---- ############################################################################### ! import sys ! major = int(sys.version[0]) ! minor = int(sys.version[2]) ! if major < 2 or minor < 1: ! sys.stderr.write('Python 2.1 or higher is required to run this application.\n') ! sys.exit(1) ! ! ! import os, re, string, types, getopt, fnmatch, utils from oo_tools import GetSetProvider from app import AppError, ShellException *************** *** 28,34 **** from plugable_app import PlugableApp ! VERSION = '0.4' 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' --- 36,42 ---- from plugable_app import PlugableApp ! VERSION = '0.5.0rc3' NAME ='CvsShell' ! COPYRIGHT = 'Copyright 2002, 2003 Stefan Heimann (ma...@st...).\n' \ 'This software is released under the GPL.' BUG_ADDRESS = 'http://sourceforge.net/tracker/?group_id=48175&atid=452212' *************** *** 86,95 **** self.readCommandFile() self.readConfigFile() - filter = utils.getCvsIgnoreFilter(self.getenv('HOME')) - filter.addPatterns(utils.splitquoted(self.configMap.get('filter',''))) - cvsignore = self.getenv("CVSIGNORE") - if cvsignore: - filter.addPatterns(utils.splitquoted(cvsignore)) - self.listingFilter = filter self.enableColor = self.configMap.get('colors', 'off') == 'on' and not self.onWindows self.batchMode = 0 --- 94,97 ---- *************** *** 98,104 **** self.showUnmodified = 0 def postStart(self): ! for cmd in self.initCommands: ! self.evalCommand(cmd) def readCvsRootFromFile(self): --- 100,126 ---- self.showUnmodified = 0 + + def getRestargSpezification(self): + return '[command_1 ... command_n]' + + def getRestargDocumentation(self): + return 'command_1 ... command_n are executed at startup (after the initial commands\nfrom the ~/.cvsshellrc file).' + + def getExecutableName(self): + return 'cvsshell' + + def postStart(self): ! if self.initCommands: ! self.printVMsg('executing initial commands:') ! for cmd in self.initCommands: ! self.evalCommand(cmd) ! commandlineCmds = self.restargs() ! if commandlineCmds: ! self.printVMsg('executing commandline commands:') ! for cmd in commandlineCmds: ! self.evalCommand(cmd) ! ! def readCvsRootFromFile(self): *************** *** 180,184 **** cmdOpts = '' cmdOpts = cmdOpts.strip() ! fun = self.getCmdFun(cmdName, CvsShell.execShellCmd) return fun(self, cmdName, cmdOpts) --- 202,210 ---- cmdOpts = '' cmdOpts = cmdOpts.strip() ! fun = self.getCmdFun(cmdName, None) ! if fun is None: ! fun = CvsShell.execShellCmd ! else: ! self.printVMsg(cmdName + ' ' + cmdOpts) return fun(self, cmdName, cmdOpts) *************** *** 259,263 **** def runCvsCmd(self, cmd, rootDir=None, cvsRoot=None, globOpts = '', ! args='', fork=1, getStderr=0): """ * cmd is the command to execute --- 285,289 ---- def runCvsCmd(self, cmd, rootDir=None, cvsRoot=None, globOpts = '', ! args='', fork=1, getStderr=0, checkLogin=1): """ * cmd is the command to execute *************** *** 267,270 **** --- 293,297 ---- * args are the arguments that should be passed to the cvs command """ + oldDir = None if rootDir is not None: *************** *** 280,283 **** --- 307,311 ---- if cvsRoot != None: cvsRootOpt = "-d %s" % cvsRoot else: cvsRootOpt = '' + if checkLogin: self.doLoginCheck(cvsRoot) # globOpts = "%s %s %s" % (defGlobOpts, cvsRootOpt, globOpts) *************** *** 309,312 **** --- 337,368 ---- + # regular expression for matching an cvsroot entry in the .cvspass + # file. The following simplifying assumptions were made: + # (1) username does not contain an '@' + # (2) path does not contain blanks + cvspassRe = re.compile(':pserver:(?P<username>[^@]+)@(?P<hostname>[^:/]+):(?P<port>\d+)?(?P<path>\S*)') + + def doLoginCheck(self, cvsroot): + if not cvsroot: return + m = CvsShell.cvspassRe.match(cvsroot) + if not m: return + username = m.group('username') + hostname = m.group('hostname') + path = m.group('path') + if path and path[-1] == '/': + path = path[:-1] + passfile = os.path.join(self.HOME, '.cvspass') + if os.path.isfile(passfile): + for line in open(passfile).readlines(): + m = CvsShell.cvspassRe.search(line) + if m and m.group('username') == username and \ + m.group('hostname') == hostname and m.group('path') == path: + return + self.printMsg('No matching entry found in %s, login required.' % passfile) + r = os.system('cvs login') + if r != 0: + raise CvsError + + def applyOnEntryList(self, opts, fun): """Applies fun to the entries of the current listing selected by opts. *************** *** 326,330 **** 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) --- 382,387 ---- 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) *************** *** 334,345 **** def printListing(self, footer=None): ! if not self.listing: ! self.printErr(self.noListingErrMsg) ! return ! if self.autoRefresh and self.dirtyListing and self.cvsRoot: ! self.printMsg('getting listing from ' + self.cvsRoot + ! ". To disable this feature execute `auto-root off'.") self.evalCommand('refresh') self.dirtyListing = 0 else: self.listing.printEntries(footer=footer) --- 391,407 ---- def printListing(self, footer=None): ! def refresh(): ! self.printMsg('getting listing from `' + self.cvsRoot + ! "'.\nTo disable this feature execute `auto-root off'.") self.evalCommand('refresh') self.dirtyListing = 0 + if not self.listing: + if self.autoRefresh: + refresh() + else: + self.printErr(self.noListingErrMsg) + return + elif self.autoRefresh and self.dirtyListing and self.cvsRoot: + refresh() else: self.listing.printEntries(footer=footer) *************** *** 350,357 **** 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) --- 412,418 ---- def parseArgs(self, args, cvsCmdOpts='', cmdOpts=''): ! """ ! Parse args and separates it like that: ! * global cvs options (as string) * command specific cvs options (as string) *************** *** 359,386 **** * 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) --- 420,470 ---- * other args (as string) These values are returned as a 4-tupel. ! ! cvsCmdOpts are the options that are allowed for the cvs command ! cmdOpts are additional options (provided by cvsshell) ! global options are handled automatically ! If an option in 'args' is meant to be an global cvs option, it ! must be prefix with a 'g' (do not write '-q' but '-gq' for ! the quiet option. ! ! A GetoptError is raised if there are unknown options. ! """ ! ! globArgs = locArgs = '' ! for arg in utils.splitquoted(args): ! if len(arg) == 3 and arg.startswith('-g'): ! globArgs += '-' + arg[2] + ' ' ! else: ! locArgs += arg + ' ' ! cvsGlobOpts = 'HQqrwlntvb:T:e:d:fz:as:' ! (globOpts, rest) = getopt.getopt(utils.splitquoted(globArgs), cvsGlobOpts) ! if rest: ! raise getopt.GetoptError, 'Unkown global option(s): ' + rest ! cvsGlobOptstr = '' ! for x in globOpts: ! name, value = x ! # getopt prepends '-' to every option ! cvsGlobOptstr += ' ' + name ! if value: cvsGlobOptstr += ' ' + value ! ! s = cvsCmdOpts+cmdOpts ! (opts, rest) = getopt.getopt(utils.splitquoted(locArgs), s) ! cvsCmdOptstr = '' cmdOptDict = {} for x in opts: name, value = x # getopt prepends '-' to every option ! if name[1] in cvsCmdOpts: cvsCmdOptstr += ' ' + name if value: cvsCmdOptstr += ' ' + value else: cmdOptDict[name] = value ! reststr = '' for x in rest: reststr += x + ' ' ! ! return (cvsGlobOptstr.strip(), cvsCmdOptstr.strip(), cmdOptDict, reststr.strip()) *************** *** 394,404 **** return defGlobOpts,defOpts ############################## ! # Listing ############################## class Listing(GetSetProvider): --- 478,564 ---- return defGlobOpts,defOpts + def getInitialLogmessageOption(self): + """ + Returns the cvs option suitable for setting the initial log message. + """ + return self._getMessageOption(self.getConfigMap().get('initial-commit-message', None)) + + def getDeleteLogmessageOption(self): + """ + Returns the cvs option suitable for setting the log message when a file is deleted + """ + return self._getMessageOption(self.getConfigMap().get('delete-message', None)) + + def _getMessageOption(self, msg): + if msg is None: + return '' + else: + msg = '"' + msg.replace('"', '\\"') + '"' + return ' -m ' + msg + ' ' + + def getCvsIgnoreFilter(self, dirname): + """Returns a filter that contains the patterns in the .cvsignore file of + the given directory.""" + def readFromFile(path): + l = [] + if os.path.exists(path): + f = open(path) + for line in f.readlines(): + l += string.split(line) + f.close() + return l + # ~/.cvsignore + filter = Filter(readFromFile(os.path.join(self.HOME, '.cvsignore'))) + # $CVSIGNORE + try: + filter.addPatterns(string.split(self.getenv('CVSIGNORE'))) + except KeyError: pass + # filter in ~/.cvsshellrc + filter.addPatterns(string.split(self.configMap.get('filter',''))) + # ./.cvsignore + filter.addPatterns(readFromFile(os.path.join(dirname, '.cvsignore'))) + # now we have all patterns. The CVS manual says: + # "a single exclamation mark (`!') clears the ignore list" + i = 0 + for p in filter.patterns: + if p == '!': + filter.patterns = filter.patterns[i+1:] + i += 1 + self.printVMsg('filter: ' + `filter.patterns`) + return filter + + + ############################## ! # Filter ############################## + + class Filter: + """This class represents a filter based on filename patterns. + The list with patterns is given in the constructor""" + + def __init__(self, patterns): + self.patterns = patterns + + def filter(self, name): + for p in self.patterns: + if fnmatch.fnmatch(name, p): + return 1 + return 0 + + def addPattern(self, p): + self.patterns.append(p) + + def addPatterns(self, ps): + self.patterns += ps + + ############################## + # Listing + ############################## + class Listing(GetSetProvider): *************** *** 408,432 **** self.rootDir = rootDir self.sortOrder = ['dir', 'status', 'name'] ! # global filter ! filter = app.getListingFilter() ! if not filter: ! tmpEntries = entries ! else: ! tmpEntries = [] ! for e in entries: ! if not filter.filter(e.name): ! tmpEntries.append(e) ! # .cvsignore filter ! filters = {} ! self.entries = [] ! for e in tmpEntries: ! if filters.has_key(e.dir): ! filter = filters[e.dir] ! else: ! filter = utils.getCvsIgnoreFilter(e.dir) ! filters[e.dir] = filter ! if not filter.filter(e.name): ! self.entries.append(e) ! def sortEntries(self): --- 568,572 ---- self.rootDir = rootDir self.sortOrder = ['dir', 'status', 'name'] ! self.entries = entries def sortEntries(self): *************** *** 444,447 **** --- 584,593 ---- self.entries.sort(__EntrySorter(self.sortOrder).cmp) + def getEntry(self, filename): + for e in self.entries: + if os.path.samefile(filename, os.path.join(e.dir, e.name)): + return e + return None + def printEntries(self, verbose=1, footer=None): if not self.entries: Index: interactive_app.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/interactive_app.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** interactive_app.py 16 Sep 2002 06:49:32 -0000 1.14 --- interactive_app.py 15 Apr 2003 13:40:10 -0000 1.15 *************** *** 99,104 **** msg = msg[:i] + '[' + default + ']'+ msg[i+len(self.DEF_PATTERN):] else: ! msg += '[%s] ' % default ! a = raw_input(msg) a = os.path.expandvars(a) a = os.path.expanduser(a) --- 99,111 ---- msg = msg[:i] + '[' + default + ']'+ msg[i+len(self.DEF_PATTERN):] else: ! msg += '[%s] ' % default ! try: ! a = raw_input(msg) ! except EOFError: ! print ! return None ! except KeyboardInterrupt: ! print ! return None a = os.path.expandvars(a) a = os.path.expanduser(a) Index: parsing.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/parsing.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** parsing.py 29 Jul 2002 17:29:10 -0000 1.4 --- parsing.py 15 Apr 2003 13:40:10 -0000 1.5 *************** *** 64,69 **** 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` + \ --- 64,69 ---- app.defGlobOpts = globOpt except getopt.GetoptError, msg: ! app.printErr("Bad format for default option for command "\ ! "`%s': %s: %s" % (y, value, str(msg))) app.printVMsg("Default global options:\n" \ + `app.cmdToDefGlobOpts` + \ Index: utils.py =================================================================== RCS file: /cvsroot/cvsshell/cvsshell/src/utils.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** utils.py 29 Nov 2002 18:35:26 -0000 1.15 --- utils.py 15 Apr 2003 13:40:10 -0000 1.16 *************** *** 25,29 **** def getAbsDir(str): ! """Returns the absolute directory str denotes. If str does not denote a directory, None is returned. """ import os --- 25,32 ---- def getAbsDir(str): ! """ ! Returns the absolute directory the filename 'str' denotes. ! If 'str' does not denote a file, None is returned. ! This function also resolves embedded environment variables. """ import os *************** *** 36,40 **** if not os.path.isabs(str): str = os.path.join(os.getcwd(), str) ! return os.path.dirname(str) except OSError, msg: print msg --- 39,43 ---- if not os.path.isabs(str): str = os.path.join(os.getcwd(), str) ! return os.path.normpath(os.path.dirname(str)) except OSError, msg: print msg *************** *** 107,111 **** else: revision = result.group('revision') ! repTime = timegm(strptime(result.group('mtime'))) files[name] = (revision, repTime) return files, dirs --- 110,117 ---- else: revision = result.group('revision') ! try: ! repTime = timegm(strptime(result.group('mtime'))) ! except ValueError: ! repTime = 0 files[name] = (revision, repTime) return files, dirs *************** *** 179,214 **** return (notEnclosed, enclosed) - - class Filter: - """This class represents a filter based on filename patterns. - The list with patterns is given in the constructor""" - - def __init__(self, patterns): - self.patterns = patterns - - def filter(self, name): - for p in self.patterns: - if fnmatch.fnmatch(name, p): - return 1 - return 0 - - def addPattern(self, p): - self.patterns.append(p) - - def addPatterns(self, ps): - self.patterns += ps - - def getCvsIgnoreFilter(dirname): - """Returns a filter that contains the patterns in the .cvsignore file of - the given directory.""" - cvsignore = os.path.join(dirname, '.cvsignore') - if os.path.exists(cvsignore): - f = open(cvsignore) - filter = Filter(map(string.strip, f.readlines())) - f.close() - else: - filter = Filter([]) - return filter - ############################## --- 185,188 ---- |