aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBogdano Arendartchuk <bogdano@mandriva.org>2006-07-19 18:33:54 +0000
committerBogdano Arendartchuk <bogdano@mandriva.org>2006-07-19 18:33:54 +0000
commit1b73048b2b21d8db4cc37559e06dfbd281f8f7c4 (patch)
tree88d618058e16ea21b01daf776bb1097574a3994b
parent85c8197d97c5d592feb022134fe99d95cbef1386 (diff)
downloadmgarepo-1b73048b2b21d8db4cc37559e06dfbd281f8f7c4.tar
mgarepo-1b73048b2b21d8db4cc37559e06dfbd281f8f7c4.tar.gz
mgarepo-1b73048b2b21d8db4cc37559e06dfbd281f8f7c4.tar.bz2
mgarepo-1b73048b2b21d8db4cc37559e06dfbd281f8f7c4.tar.xz
mgarepo-1b73048b2b21d8db4cc37559e06dfbd281f8f7c4.zip
- reimplmented the SVN class in svn.py to use the module pysvn instead of
pexpect + svn This was an unintented commit trigged by a test, so "releases", "cooker" and "misc" directories should be ignored
-rw-r--r--RepSys/commands/editlog.py2
-rw-r--r--RepSys/log.py22
-rw-r--r--RepSys/rpmutil.py43
-rw-r--r--RepSys/svn.py465
4 files changed, 163 insertions, 369 deletions
diff --git a/RepSys/commands/editlog.py b/RepSys/commands/editlog.py
index 1962ed8..a98b761 100644
--- a/RepSys/commands/editlog.py
+++ b/RepSys/commands/editlog.py
@@ -30,7 +30,7 @@ def parse_options():
def editlog(pkgdirurl, revision):
svn = SVN()
- svn.propedit("svn:log", pkgdirurl, rev=revision)
+ svn.propedit("svn:log", pkgdirurl, revision=revision, revprop=True)
def main():
do_command(parse_options, editlog)
diff --git a/RepSys/log.py b/RepSys/log.py
index 0c49d12..2648b41 100644
--- a/RepSys/log.py
+++ b/RepSys/log.py
@@ -49,14 +49,14 @@ def getrelease(pkgdirurl, rev=None):
Is here where things should be changed if "automatic release increasing"
will be used.
"""
- svn = SVN(baseurl=pkgdirurl)
+ svn = SVN()
tmpdir = tempfile.mktemp()
try:
pkgname = os.path.basename(pkgdirurl)
pkgcurrenturl = os.path.join(pkgdirurl, "current")
specurl = os.path.join(pkgcurrenturl, "SPECS")
- if svn.ls(specurl, noerror=1):
- svn.export(specurl, tmpdir, rev=rev)
+ if svn.exists(specurl):
+ svn.export(specurl, tmpdir, revision=SVN.revision(rev))
found = glob.glob(os.path.join(tmpdir, "*.spec"))
if found:
specpath = found[0]
@@ -250,14 +250,18 @@ def get_revision_offset():
def svn2rpm(pkgdirurl, rev=None, size=None, submit=False, template=None):
+ size = size or 0
concat = config.get("log", "concat", "").split()
revoffset = get_revision_offset()
- svn = SVN(baseurl=pkgdirurl)
+ svn = SVN()
pkgreleasesurl = os.path.join(pkgdirurl, "releases")
pkgcurrenturl = os.path.join(pkgdirurl, "current")
- releaseslog = svn.log(pkgreleasesurl, noerror=1)
- currentlog = svn.log(pkgcurrenturl, limit=size, start=rev,
- end=revoffset)
+ releaseslog = list(svn.log(pkgreleasesurl,
+ strict_node_history=False, noerror=1)) or []
+ currentlog = list(svn.log(pkgcurrenturl,
+ strict_node_history=False,
+ revision_start=SVN.revision(rev),
+ revision_end=SVN.revision(revoffset), limit=size))
lastauthor = None
previous_revision = 0
currelease = None
@@ -350,12 +354,12 @@ def specfile_svn2rpm(pkgdirurl, specfile, rev=None, size=None,
# Merge old changelog, if available
oldurl = config.get("log", "oldurl")
if oldurl:
- svn = SVN(baseurl=pkgdirurl)
+ svn = SVN()
tmpdir = tempfile.mktemp()
try:
pkgname = os.path.basename(pkgdirurl)
pkgoldurl = os.path.join(oldurl, pkgname)
- if svn.ls(pkgoldurl, noerror=1):
+ if svn.exists(pkgoldurl):
svn.export(pkgoldurl, tmpdir, rev=rev)
logfile = os.path.join(tmpdir, "log")
if os.path.isfile(logfile):
diff --git a/RepSys/rpmutil.py b/RepSys/rpmutil.py
index 83d0051..3adbaa3 100644
--- a/RepSys/rpmutil.py
+++ b/RepSys/rpmutil.py
@@ -4,6 +4,7 @@ from RepSys.svn import SVN
from RepSys.rpm import SRPM
from RepSys.log import specfile_svn2rpm
from RepSys.util import execcmd
+import pysvn
import tempfile
import shutil
import glob
@@ -11,11 +12,11 @@ import sys
import os
def get_spec(pkgdirurl, targetdir=".", submit=False):
- svn = SVN(baseurl=pkgdirurl)
+ svn = SVN()
tmpdir = tempfile.mktemp()
try:
geturl = "/".join([pkgdirurl, "current", "SPECS"])
- svn.export("'%s'" % geturl, tmpdir)
+ svn.export("%s" % geturl, tmpdir)
speclist = glob.glob(os.path.join(tmpdir, "*.spec"))
if not speclist:
raise Error, "no spec files found"
@@ -37,7 +38,7 @@ def get_srpm(pkgdirurl,
scripts = [],
submit = False,
template = None):
- svn = SVN(baseurl=pkgdirurl)
+ svn = SVN()
tmpdir = tempfile.mktemp()
topdir = "--define '_topdir %s'" % tmpdir
builddir = "--define '_builddir %s/%s'" % (tmpdir, "BUILD")
@@ -56,7 +57,7 @@ def get_srpm(pkgdirurl,
geturl = os.path.join(pkgdirurl, "current")
else:
raise Error, "unsupported get_srpm mode: %s" % mode
- svn.checkout(geturl, tmpdir, rev=revision)
+ svn.checkout(geturl, tmpdir, revision=SVN.revision(revision))
srpmsdir = os.path.join(tmpdir, "SRPMS")
os.mkdir(srpmsdir)
specsdir = os.path.join(tmpdir, "SPECS")
@@ -68,7 +69,7 @@ def get_srpm(pkgdirurl,
submit = not not revision
specfile_svn2rpm(pkgdirurl, spec, revision, submit=submit,
template=template)
- revisionreal = svn.revision(tmpdir)
+ revisionreal = svn.info(tmpdir).revision.number
for script in scripts:
status, output = execcmd(script, tmpdir, spec, str(revision),
noerror=1)
@@ -98,7 +99,7 @@ def get_srpm(pkgdirurl,
shutil.rmtree(tmpdir)
def patch_spec(pkgdirurl, patchfile, log=""):
- svn = SVN(baseurl=pkgdirurl)
+ svn = SVN()
tmpdir = tempfile.mktemp()
try:
geturl = "/".join([pkgdirurl, "current", "SPECS"])
@@ -111,7 +112,7 @@ def patch_spec(pkgdirurl, patchfile, log=""):
if status != 0:
raise Error, "can't apply patch:\n%s\n" % output
else:
- svn.commit(tmpdir, log="")
+ svn.checkin(tmpdir, log=log)
finally:
if os.path.isdir(tmpdir):
shutil.rmtree(tmpdir)
@@ -120,7 +121,7 @@ def put_srpm(pkgdirurl, srpmfile, appendname=0, log=""):
srpm = SRPM(srpmfile)
if appendname:
pkgdirurl = "/".join([pkgdirurl, srpm.name])
- svn = SVN(baseurl=pkgdirurl)
+ svn = SVN()
tmpdir = tempfile.mktemp()
try:
if srpm.epoch:
@@ -129,7 +130,7 @@ def put_srpm(pkgdirurl, srpmfile, appendname=0, log=""):
version = srpm.version
versionurl = "/".join([pkgdirurl, "releases", version])
releaseurl = "/".join([versionurl, srpm.release])
- ret = svn.mkdir(pkgdirurl, noerror=1, log="Created package directory")
+ ret = svn.mkdir(pkgdirurl, "Created package directory", noerror=1)
if ret:
svn.checkout(pkgdirurl, tmpdir)
svn.mkdir(os.path.join(tmpdir, "releases"))
@@ -141,7 +142,7 @@ def put_srpm(pkgdirurl, srpmfile, appendname=0, log=""):
version_exists = 1
currentdir = os.path.join(tmpdir, "current")
else:
- if svn.ls(releaseurl, noerror=1):
+ if svn.exists(releaseurl, noerror=1):
raise Error, "release already exists"
svn.checkout("/".join([pkgdirurl, "current"]), tmpdir)
svn.mkdir(versionurl, noerror=1,
@@ -197,7 +198,7 @@ def put_srpm(pkgdirurl, srpmfile, appendname=0, log=""):
if os.path.isdir(unpackdir):
shutil.rmtree(unpackdir)
- svn.commit(tmpdir, log=log)
+ svn.checkin(tmpdir, log=log)
finally:
if os.path.isdir(tmpdir):
shutil.rmtree(tmpdir)
@@ -215,7 +216,7 @@ def put_srpm(pkgdirurl, srpmfile, appendname=0, log=""):
(version, srpm.release))
def create_package(pkgdirurl, log="", verbose=0):
- svn = SVN(baseurl=pkgdirurl)
+ svn = SVN()
tmpdir = tempfile.mktemp()
try:
basename = os.path.basename(pkgdirurl)
@@ -237,7 +238,7 @@ def create_package(pkgdirurl, log="", verbose=0):
if verbose:
print "done"
print "Committing...",
- svn.commit(tmpdir,
+ svn.checkin(tmpdir,
log="Created package structure for '%s'." % basename)
print "done"
finally:
@@ -256,11 +257,11 @@ revision: %s
return log
def mark_release(pkgdirurl, version, release, revision):
- svn = SVN(baseurl=pkgdirurl)
+ svn = SVN()
releasesurl = "/".join([pkgdirurl, "releases"])
versionurl = "/".join([releasesurl, version])
releaseurl = "/".join([versionurl, release])
- if svn.ls(releaseurl, noerror=1):
+ if svn.exists(releaseurl, noerror=1):
raise cncrep.Error, "release already exists"
svn.mkdir(releasesurl, noerror=1,
log="Created releases directory.")
@@ -278,14 +279,14 @@ def mark_release(pkgdirurl, version, release, revision):
log=markreleaselog)
def check_changed(url, all=0, show=0, verbose=0):
- svn = SVN(baseurl=pkgdirurl)
+ svn = SVN()
if all:
baseurl = url
packages = []
if verbose:
print "Getting list of packages...",
sys.stdout.flush()
- packages = [x[:-1] for x in svn.ls(baseurl)]
+ packages = [x['name'] for x in svn.ls(baseurl)]
if verbose:
print "done"
if not packages:
@@ -304,11 +305,11 @@ def check_changed(url, all=0, show=0, verbose=0):
if verbose:
print "Checking package %s..." % package,
sys.stdout.flush()
- if not svn.ls(current, noerror=1):
+ if not svn.exists(current):
if verbose:
print "NO CURRENT"
nocurrent.append(package)
- elif not svn.ls(pristine, noerror=1):
+ elif not svn.exists(pristine):
if verbose:
print "NO PRISTINE"
nopristine.append(package)
@@ -338,7 +339,7 @@ def check_changed(url, all=0, show=0, verbose=0):
"nopristine": nopristine}
def checkout(url, path=None, revision=None):
- svn = SVN(baseurl=pkgdirurl)
+ svn = SVN()
current = os.path.join(url, "current")
if path is None:
_, path = os.path.split(url)
@@ -364,7 +365,7 @@ def get_submit_info(path):
if not os.path.isdir(os.path.join(path, ".svn")):
raise Error, "subversion directory not found"
- svn = SVN(baseurl=pkgdirurl)
+ svn = SVN()
# Now, extract the package name.
diff --git a/RepSys/svn.py b/RepSys/svn.py
index e83b072..0d49cf2 100644
--- a/RepSys/svn.py
+++ b/RepSys/svn.py
@@ -1,10 +1,15 @@
from RepSys import Error, config, pexpect
from RepSys.util import execcmd, get_auth
+
import sys
+import os
import re
import time
+import threading
+import tempfile
+import pysvn
-__all__ = ["SVN", "SVNLook", "SVNLogEntry"]
+__all__ = ["SVN", "Revision", "SVNLogEntry"]
class SVNLogEntry:
def __init__(self, revision, author, date):
@@ -17,345 +22,129 @@ class SVNLogEntry:
return cmp(self.date, other.date)
class SVN:
- def __init__(self, username=None, password=None, noauth=0, baseurl=None):
- self.noauth = noauth or (
- baseurl and (
- baseurl.startswith("file:") or
- baseurl.startswith("svn+ssh:")))
- if not self.noauth: # argh
- self.username, self.password = get_auth()
-
-
- def _execsvn(self, *args, **kwargs):
- cmdstr = "svn "+" ".join(args)
- if kwargs.get("local") or kwargs.get("noauth") or self.noauth:
- return execcmd(cmdstr, **kwargs)
- show = kwargs.get("show")
- noerror = kwargs.get("noerror")
- p = pexpect.spawn(cmdstr, timeout=1)
- p.setmaxread(1024)
- p.setecho(False)
- outlist = []
- while True:
- i = p.expect_exact([pexpect.EOF, pexpect.TIMEOUT,
- "username:", "password:",
- "(p)ermanently?",
- "Authorization failed"])
- if i == 0:
- if show and p.before:
- print p.before,
- outlist.append(p.before)
- break
- elif i == 1:
- if show and p.before:
- print p.before,
- outlist.append(p.before)
- elif i == 2:
- p.sendline(self.username)
- outlist = []
- elif i == 3:
- p.sendline(self.password)
- outlist = []
- elif i == 4:
- p.sendline("p")
- outlist = []
- elif i == 5:
- if not noerror:
- raise Error, "authorization failed"
- else:
- break
- while p.isalive():
+ _client = None
+ _client_lock = None
+ _current_message = None
+
+ def __init__(self):
+ self._client = pysvn.Client()
+ self._client_lock = threading.Lock()
+ self._client.callback_get_log_message = self._log_handler
+
+ def _log_handler(self):
+ if self._current_message is None:
+ raise ValueError, "No log message defined"
+ return True, self._current_message
+
+ def _get_log_message(self, received_kwargs):
+ message = received_kwargs.pop("log", None)
+ messagefile = received_kwargs.pop("logfile", None)
+ if messagefile and not message:
+ message = open(messagefile).read()
+ return message
+
+ def _make_wrapper(self, meth):
+ def wrapper(*args, **kwargs):
+ self._client_lock.acquire()
try:
- time.sleep(1)
- except (pexpect.TIMEOUT, pexpect.EOF):
- # Continue until the child dies
- pass
- status, output = p.exitstatus, "".join(outlist).strip()
- if status != 0 and not kwargs.get("noerror"):
- sys.stderr.write(cmdstr)
- sys.stderr.write("\n")
- sys.stderr.write(output)
- sys.stderr.write("\n")
- raise Error, "command failed: "+cmdstr
- return status, output
-
- def _execsvn_success(self, *args, **kwargs):
- status, output = self._execsvn(*args, **kwargs)
- return status == 0
-
- def _add_log(self, cmd_args, received_kwargs, optional=0):
- if (not optional or
- received_kwargs.has_key("log") or
- received_kwargs.has_key("logfile")):
- ret = received_kwargs.get("log")
- if ret is not None:
- cmd_args.append("-m '%s'" % ret)
- ret = received_kwargs.get("logfile")
- if ret is not None:
- cmd_args.append("-F '%s'" % ret)
-
- def _add_revision(self, cmd_args, received_kwargs, optional=0):
- if not optional or received_kwargs.has_key("rev"):
- ret = received_kwargs.get("rev")
- if isinstance(ret, basestring):
+ self._current_message = self._get_log_message(kwargs)
+ ignore_errors = kwargs.pop("noerror", None)
try:
- ret = int(ret)
- except ValueError:
- raise Error, "invalid revision provided"
- if ret:
- cmd_args.append("-r %d" % ret)
-
- def add(self, path, **kwargs):
- cmd = ["add", path]
- return self._execsvn_success(noauth=1, *cmd, **kwargs)
-
- def copy(self, pathfrom, pathto, **kwargs):
- cmd = ["copy", pathfrom, pathto]
- self._add_revision(cmd, kwargs, optional=1)
- self._add_log(cmd, kwargs)
- return self._execsvn_success(*cmd, **kwargs)
-
- def remove(self, path, force=0, **kwargs):
- cmd = ["remove", path]
- self._add_log(cmd, kwargs)
- if force:
- cmd.append("--force")
- return self._execsvn_success(*cmd, **kwargs)
-
- def mkdir(self, path, **kwargs):
- cmd = ["mkdir", path]
- self._add_log(cmd, kwargs)
- return self._execsvn_success(*cmd, **kwargs)
-
- def commit(self, path, **kwargs):
- cmd = ["commit", path]
- self._add_log(cmd, kwargs)
- return self._execsvn_success(*cmd, **kwargs)
-
- def export(self, url, targetpath, **kwargs):
- cmd = ["export", "'%s'" % url, targetpath]
- self._add_revision(cmd, kwargs, optional=1)
- return self._execsvn_success(*cmd, **kwargs)
-
- def checkout(self, url, targetpath, **kwargs):
- cmd = ["checkout", "'%s'" % url, targetpath]
- self._add_revision(cmd, kwargs, optional=1)
- return self._execsvn_success(*cmd, **kwargs)
-
- def propset(self, propname, value, targets, **kwargs):
- cmd = ["propset", propname, "'%s'" % value, targets]
- return self._execsvn_success(*cmd, **kwargs)
-
- def propedit(self, propname, target, **kwargs):
- cmd = ["propedit", propname, target]
- if kwargs.get("rev"):
- cmd.append("--revprop")
- self._add_revision(cmd, kwargs)
- return self._execsvn_success(local=True, show=True, *cmd, **kwargs)
-
- def revision(self, path, **kwargs):
- cmd = ["info", path]
- status, output = self._execsvn(local=True, *cmd, **kwargs)
- if status == 0:
- for line in output.splitlines():
- if line.startswith("Revision: "):
- return int(line.split()[1])
- return None
-
- def info(self, path, **kwargs):
- cmd = ["info", path]
- status, output = self._execsvn(local=True, *cmd, **kwargs)
- if status == 0:
- return output.splitlines()
- return None
-
- def ls(self, path, **kwargs):
- cmd = ["ls", path]
- status, output = self._execsvn(*cmd, **kwargs)
- if status == 0:
- return output.split()
- return None
-
- def status(self, path, **kwargs):
- cmd = ["status", path]
- if kwargs.get("verbose"):
- cmd.append("-v")
- status, output = self._execsvn(*cmd, **kwargs)
- if status == 0:
- return [x.split() for x in output.splitlines()]
- return None
-
- def cleanup(self, path, **kwargs):
- cmd = ["cleanup", path]
- return self._execsvn_success(*cmd, **kwargs)
-
- def revert(self, path, **kwargs):
- cmd = ["revert", path]
- status, output = self._execsvn(*cmd, **kwargs)
- if status == 0:
- return [x.split() for x in output.split()]
- return None
-
- def update(self, path, **kwargs):
- cmd = ["update", path]
- self._add_revision(cmd, kwargs, optional=1)
- status, output = self._execsvn(*cmd, **kwargs)
- if status == 0:
- return [x.split() for x in output.split()]
- return None
-
- def merge(self, url1, url2=None, rev1=None, rev2=None, path=None, **kwargs):
- cmd = ["merge"]
- if rev1 and rev2 and not url2:
- cmd.append("-r")
- cmd.append("%s:%s" % (rev1, rev2))
- cmd.append(url1)
+ return meth(*args, **kwargs)
+ except pysvn.ClientError:
+ if not ignore_errors:
+ raise
+ return False
+ finally:
+ self._current_message = None
+ self._client_lock.release()
+ return wrapper
+
+ def __getattr__(self, attrname):
+ meth = getattr(self._client, attrname)
+ wrapper = self._make_wrapper(meth)
+ return wrapper
+
+ def revision(number=None, head=None):
+ if number is not None:
+ args = (pysvn.opt_revision_kind.number, number)
else:
- if not url2:
- raise ValueError, \
- "url2 needed if two revisions are not provided"
- if rev1:
- cmd.append("%s@%s" % (url1, rev1))
- else:
- cmd.append(url1)
- if rev2:
- cmd.append("%s@%s" % (url2, rev2))
- else:
- cmd.append(url2)
- if path:
- cmd.append(path)
- status, output = self._execsvn(*cmd, **kwargs)
- if status == 0:
- return [x.split() for x in output.split()]
- return None
-
- def diff(self, pathurl1, pathurl2=None, **kwargs):
- cmd = ["diff", pathurl1]
- self._add_revision(cmd, kwargs, optional=1)
- if pathurl2:
- cmd.append(pathurl2)
- status, output = self._execsvn(*cmd, **kwargs)
- if status == 0:
- return output
- return None
-
- def cat(self, url, **kwargs):
- cmd = ["cat", url]
- self._add_revision(cmd, kwargs, optional=1)
- status, output = self._execsvn(*cmd, **kwargs)
- if status == 0:
- return output
- return None
-
- def log(self, url, start=None, end=0, limit=None, **kwargs):
- cmd = ["log", url]
- if start is not None or end != 0:
- if start is not None and type(start) is not type(0):
- try:
- start = int(start)
- except (ValueError, TypeError):
- raise Error, "invalid log start revision provided"
- if type(end) is not type(0):
- try:
- end = int(end)
- except (ValueError, TypeError):
- raise Error, "invalid log end revision provided"
- start = start or "HEAD"
- cmd.append("-r %s:%s" % (start, end))
- if limit is not None:
- try:
- limit = int(limit)
- except (ValueError, TypeError):
- raise Error, "invalid limit number provided"
- cmd.append("--limit %d" % limit)
- status, output = self._execsvn(*cmd, **kwargs)
- if status != 0:
- return None
-
- revheader = re.compile("^r(?P<revision>[0-9]+) \| (?P<author>[^\|]+) \| (?P<date>[^\|]+) \| (?P<lines>[0-9]+) (?:line|lines)$")
- logseparator = "-"*72
- linesleft = 0
- entry = None
- log = []
- emptyline = 0
- for line in output.splitlines():
- if emptyline:
- emptyline = 0
- continue
- line = line.rstrip()
- if linesleft == 0:
- if line != logseparator:
- m = revheader.match(line)
- if m:
- linesleft = int(m.group("lines"))
- timestr = " ".join(m.group("date").split()[:2])
- timetuple = time.strptime(timestr,
- "%Y-%m-%d %H:%M:%S")
- entry = SVNLogEntry(int(m.group("revision")),
- m.group("author"), timetuple)
- log.append(entry)
- emptyline = 1
- else:
- entry.lines.append(line)
- linesleft -= 1
- log.sort()
- log.reverse()
- return log
-
-class SVNLook:
- def __init__(self, repospath, txn=None, rev=None):
- self.repospath = repospath
- self.txn = txn
- self.rev = rev
-
- def _execsvnlook(self, cmd, *args, **kwargs):
- execcmd_args = ["svnlook", cmd, self.repospath]
- self._add_txnrev(execcmd_args, kwargs)
- execcmd_args += args
- execcmd_kwargs = {}
- keywords = ["show", "noerror"]
- for key in keywords:
- if kwargs.has_key(key):
- execcmd_kwargs[key] = kwargs[key]
- return execcmd(*execcmd_args, **execcmd_kwargs)
-
- def _add_txnrev(self, cmd_args, received_kwargs):
- if received_kwargs.has_key("txn"):
- txn = received_kwargs.get("txn")
- if txn is not None:
- cmd_args += ["-t", txn]
- elif self.txn is not None:
- cmd_args += ["-t", self.txn]
- if received_kwargs.has_key("rev"):
- rev = received_kwargs.get("rev")
- if rev is not None:
- cmd_args += ["-r", rev]
- elif self.rev is not None:
- cmd_args += ["-r", self.rev]
-
- def changed(self, **kwargs):
- status, output = self._execsvnlook("changed", **kwargs)
- if status != 0:
- return None
- changes = []
- for line in output.splitlines():
- line = line.rstrip()
- if not line:
- continue
- entry = [None, None, None]
- changedata, changeprop, path = None, None, None
- if line[0] != "_":
- changedata = line[0]
- if line[1] != " ":
- changeprop = line[1]
- path = line[4:]
- changes.append((changedata, changeprop, path))
- return changes
-
- def author(self, **kwargs):
- status, output = self._execsvnlook("author", **kwargs)
- if status != 0:
- return None
- return output.strip()
+ args = (pysvn.opt_revision_kind.head,)
+ return pysvn.Revision(*args)
+ revision = staticmethod(revision)
+
+ # this override method fixed the problem in pysvn's mkdir which
+ # requires a log_message parameter
+ def mkdir(self, path, log=None, **kwargs):
+ meth = self.__getattr__("mkdir")
+ # we can't raise an error because pysvn's mkdir will use
+ # log_message only if path is remote, but it *always* requires this
+ # parameter. Also, 'log' is never used.
+ log = log or "There's a silent bug in your code"
+ return meth(path, log, log=None, **kwargs)
+
+ def checkin(self, path, log, **kwargs):
+ # XXX use EDITOR when log empty
+ meth = self.__getattr__("checkin")
+ return meth(path, log, log=None, **kwargs)
+
+ def log(self, *args, **kwargs):
+ meth = self.__getattr__("log")
+ entries = meth(*args, **kwargs)
+ for entrydic in entries:
+ entry = SVNLogEntry(entrydic["revision"].number,
+ entrydic["author"],
+ time.localtime(entrydic["date"]))
+ entry.lines[:] = entrydic["message"].split("\n")
+ yield entry
+
+ def exists(self, path):
+ return self.ls(path, noerror=1) is not False
+
+ def _edit_message(self, message):
+ # argh!
+ editor = os.getenv("EDITOR", "vim")
+ fd, fpath = tempfile.mkstemp(prefix="repsys")
+ result = (False, None)
+ try:
+ f = os.fdopen(fd, "w")
+ f.write(message)
+ f.close()
+ lastchange = os.stat(fpath).st_mtime
+ while 1:
+ os.system("%s %s" % (editor, fpath))
+ newchange = os.stat(fpath).st_mtime
+ if newchange == lastchange:
+ print "Log message unchanged or not specified"
+ print "(a)bort, (c)ontinue, (e)dit"
+ choice = raw_input()
+ if not choice or choice[0] == 'e':
+ continue
+ elif choice[0] == 'a':
+ break
+ elif choice[0] == 'c':
+ pass # ignore and go ahead
+ newmessage = open(fpath).read()
+ result = (True, newmessage)
+ break
+ finally:
+ os.unlink(fpath)
+ return result
+
+ def propedit(self, propname, pkgdirurl, revision, revprop=False):
+ revision = self.revision(revision)
+ if revprop:
+ propget = self.revpropget
+ propset = self.revpropset
+ else:
+ propget = self.propget
+ propset = self.propset
+ revision, message = propget(propname, pkgdirurl, revision=revision)
+ changed, newmessage = self._edit_message(message)
+ try:
+ if changed:
+ propset(propname, newmessage, pkgdirurl, revision=revision)
+ except pysvn.ClientError, (msg,):
+ raise Error, msg
# vim:et:ts=4:sw=4