#!/usr/bin/env python import sys import pysvn import fnmatch import optparse class DelimitedStringList(list): def __init__(self, string="", delimiter="\n"): self.delimiter = delimiter self.changefunc = lambda x: True l = string.split(delimiter) while '' in l: l.remove('') return list.__init__(self, l) def __safe__(self, value): if self.delimiter in value: raise ValueError("Cannot accept value \"%s\"; it contains a delimiter" % value) def __setitem__(self,i,value): self.__safe__(value) r = list.__setitem__(self,i,value) self.changefunc(self) return r def __setslice__(self, i, j, vlist): for v in vlist: self.__safe__(v) r = list.__setslice__(self,i,j,vlist) self.changefunc(self) return r def extend(self, newlist): for v in newlist: self.__safe__(v) r = list.extend(self, newlist) self.changefunc(self) return r def append(self, value): self.__safe__(value) r = list.append(self, value) self.changefunc(self) return r def insert(self, i, value): self.__safe__(value) r = list.insert(self,i,value) self.changefunc(self) return r def as_string(self): return self.delimiter.join(self) class SvnPropList(DelimitedStringList): def __init__(self, client, property, path, write_through=True): self.client = client self.property = property self.path = path self.write_through = write_through strmap = self.client.propget(self.property, self.path) if len(strmap)==0: str = '' else: str=strmap.values()[0] DelimitedStringList.__init__(self, str, '\n') self.changefunc = SvnPropList.__on_change def __on_change(self): str = self.as_string() if self.write_through: self.client.propset(self.property, str, self.path) def ensure(self, value, glob_match=True): """Ensure that 'value' is in the list. If it's not, add it. if glob_match is True, then having a glob in the list that matches, don't add value.""" if value in self: return if glob_match: for pattern in self: if fnmatch.fnmatch(value, pattern): return self.append(value) def main(args): USAGE = "%prog [options] " parser = optparse.OptionParser(usage=USAGE) parser.add_option('-i','--ignore',action='store',dest='ignore_file',metavar='FILE',help='ensure that FILE is ignored') (opts, args) = parser.parse_args(args) if opts.ignore_file is not None: propname = "svn:ignore" filename = os.path.realpath(opts.ignore_file) path = os.path.dirname(filename) value = os.path.basename(filename) else: if len(args) != 4: parser.print_usage(file=sys.stderr) sys.stderr.write("%s\n" % str(args)) return -1 (_, propname, value, path) = args svnC = pysvn.Client() try: x = SvnPropList(svnC, propname, path) x.ensure(value) except pysvn.ClientError, e: sys.stderr.write("SVN error encountered performing request:\n\t%s\n" % e) if __name__ == '__main__': import os sys.exit(main(sys.argv))